diff --git a/src/tcompiler.cpp b/src/tcompiler.cpp index 2a8a25ef..8039a46e 100644 --- a/src/tcompiler.cpp +++ b/src/tcompiler.cpp @@ -1036,7 +1036,8 @@ struct CCallingConv { if (all_float && n_elts <= 8) { *usedint += n_elts; if (n_elts == 1) { - return Argument(C_AGGREGATE_REG, t, t->type); + return Argument(C_AGGREGATE_REG, t, + StructType::get(Type::getFloatTy(*CU->TT->ctx))); } else { auto at = ArrayType::get(Type::getFloatTy(*CU->TT->ctx), n_elts); return Argument(C_ARRAY_REG, t, at); @@ -1045,7 +1046,8 @@ struct CCallingConv { if (all_double && n_elts <= 8) { *usedint += n_elts; if (n_elts == 1) { - return Argument(C_AGGREGATE_REG, t, t->type); + return Argument(C_AGGREGATE_REG, t, + StructType::get(Type::getDoubleTy(*CU->TT->ctx))); } else { auto at = ArrayType::get(Type::getDoubleTy(*CU->TT->ctx), n_elts); return Argument(C_ARRAY_REG, t, at); diff --git a/tests/cconv_array.t b/tests/cconv_array.t new file mode 100644 index 00000000..26949e71 --- /dev/null +++ b/tests/cconv_array.t @@ -0,0 +1,69 @@ +-- Test arrays passed (returned) by value: these are not supported by +-- C, but Terra supports them and so has to implement them at least in +-- a self-consistent way. + +local test = require("test") + +local function run_test_case(typ, N) + print("running test for " .. tostring(typ[N])) + local terra callee(x : typ[N]) + escape + for i = 1, N do + emit quote + x[i-1] = x[i-1] + i + end + end + end + return x + end + + local args = terralib.newlist() + for i = 1, N do + args:insert(terralib.newsymbol(typ)) + end + local terra caller([args]) + var y : typ[N] + escape + for i = 1, N do + emit quote + y[i-1] = [args[i]] + end + end + end + var z = callee(y) + return [( + function() + local result = terralib.newlist() + for i = 1, N do + result:insert(`y[i-1]) + end + for i = 1, N do + result:insert(`z[i-1]) + end + return result + end)()] + end + + local values = terralib.newlist() + for i = 1, N do + values:insert(i * 10) + end + + local values = terralib.newlist({unpacktuple(caller(unpack(values)))}) + + for i = 1, N do + test.eq(values[i], i*10) + end + for i = N+1, 2*N do + test.eq(values[i], (i-N)*11) + end +end + +for N = 0, 11 do + run_test_case(int8, N) +end +for _, typ in ipairs({int16, int32, int64, float, double}) do + for N = 0, 32 do + run_test_case(typ, N) + end +end