Как создать структуру возвращаемые значения в промежуточный код LLVM ИК, совместимых с C?

С моей помощью LLVM-компилятора игрушка, я хочу, чтобы скомпилировать эквивалент этого кода на C:

struct a { long a[4]; };
struct b { long b[2]; };
struct a doStuff(struct b);

struct a myFunction(struct b v) {
  return doStuff(v);
}

В то время как пишется в игрушечный язык программирования, -это функции C и вызывающая функция тоже написана на языке C.

На данный момент, мой компилятор генерирует следующий код:

define { [4 x i64] } @myFunction({ [2 x i64] } %%0) {
entry:
  %%arg = alloca { [2 x i64] }
  store { [2 x i64] } %%0, { [2 x i64] }* %%arg
  %%arg1 = load { [2 x i64] }, { [2 x i64] }* %%arg
  %%call_to_doStuff = call { [2 x i64] } @doStuff({ [2 x i64] } %%arg1)
  ret { [4 x i64] } %%call_to_doStuff
}

Этот код успешно назвав , но потом вылеты, потому что ргумент СС b содержит только мусор.

Когда я использовать Clang, чтобы перевести выше c перевод из , Я вижу, что он использует другой вызов конвенции и :

%%struct.a = type { [4 x i64] }
%%struct.b = type { [2 x i64] }

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @myFunction(%%struct.a* noalias sret %%0, i64 %%1, i64 %%2) #0 {
  %%4 = alloca %%struct.b, align 8
  %%5 = bitcast %%struct.b* %%4 to { i64, i64 }*
  %%6 = getelementptr inbounds { i64, i64 }, { i64, i64 }* %%5, i32 0, i32 0
  store i64 %%1, i64* %%6, align 8
  %%7 = getelementptr inbounds { i64, i64 }, { i64, i64 }* %%5, i32 0, i32 1
  store i64 %%2, i64* %%7, align 8
  %%8 = bitcast %%struct.b* %%4 to { i64, i64 }*
  %%9 = getelementptr inbounds { i64, i64 }, { i64, i64 }* %%8, i32 0, i32 0
  %%10 = load i64, i64* %%9, align 8
  %%11 = getelementptr inbounds { i64, i64 }, { i64, i64 }* %%8, i32 0, i32 1
  %%12 = load i64, i64* %%11, align 8
  call void @doStuff(%%struct.a* sret %%0, i64 %%10, i64 %%12)
  ret void
}

declare dso_local void @doStuff(%%struct.a* sret, i64, i64) #1

Я правильно понимаю, что моя проблема связана с тем, как структуры возвращаются? И как я могу изменить мой генератор ИК излучать надлежащего -код? Есть ли для этого?

(Я ориентируетесь в Linux для x86_64.)

0
2019-09-19 13:46:33
источник
0 ответов

Посмотрите другие вопросы по меткам