Skip to content

Commit

Permalink
Fix for passing arrays by value in PPC64le (#577)
Browse files Browse the repository at this point in the history
  • Loading branch information
elliottslaughter authored Jun 30, 2022
1 parent 2122f1f commit 7c7d653
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 2 deletions.
6 changes: 4 additions & 2 deletions src/tcompiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
Expand Down
69 changes: 69 additions & 0 deletions tests/cconv_array.t
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 7c7d653

Please sign in to comment.