bridge: preserve pointerness in C-ABI oracle
To support stack maps it is necessary to preserve pointerness.
Make sure we don't lose pointerness in the C-ABI oracle.
Change-Id: I6a73f3350c1e280aef7921097bc8938538ac3456
Reviewed-on: https://go-review.googlesource.com/137757
Reviewed-by: Than McIntosh <thanm@google.com>
diff --git a/bridge/go-llvm-cabi-oracle.cpp b/bridge/go-llvm-cabi-oracle.cpp
index 023c664..abe87db 100644
--- a/bridge/go-llvm-cabi-oracle.cpp
+++ b/bridge/go-llvm-cabi-oracle.cpp
@@ -372,13 +372,20 @@
unsigned bytes = ebr.offsets[nel-1] - ebr.offsets[0] +
tm()->llvmTypeSize(ebr.types[nel-1]);
assert(bytes && bytes <= 8);
- ebr.abiDirectType = tm()->llvmArbitraryIntegerType(bytes);
+ // Preserve pointerness for the use of GC.
+ // TODO: this assumes pointer is 8 byte, so we never pack pointer
+ // and other stuff together.
+ if (ebr.types[0]->isPointerTy())
+ ebr.abiDirectType = tm()->llvmPtrType();
+ else
+ ebr.abiDirectType = tm()->llvmArbitraryIntegerType(bytes);
intRegions += 1;
}
}
// See the example above for more on why this is needed.
- if (intRegions == 2)
+ if (intRegions == 2 &&
+ ebrs_[0].abiDirectType->isIntegerTy())
ebrs_[0].abiDirectType = tm()->llvmArbitraryIntegerType(8);
else if (floatRegions == 2 &&
ebrs_[0].abiDirectType == tm()->llvmFloatType())
diff --git a/unittests/BackendCore/BackendCABIOracleTests.cpp b/unittests/BackendCore/BackendCABIOracleTests.cpp
index 0c431b6..29ff26b 100644
--- a/unittests/BackendCore/BackendCABIOracleTests.cpp
+++ b/unittests/BackendCore/BackendCABIOracleTests.cpp
@@ -68,6 +68,7 @@
Btype *bi16t = be->integer_type(false, 16);
Btype *bf32t = be->float_type(32);
Btype *bf64t = be->float_type(64);
+ Btype *bpu64t = be->pointer_type(bu64t);
Btype *bpf64t = be->pointer_type(bf64t);
Btype *st0 = mkBackendStruct(be, nullptr);
Btype *st1 = mkBackendStruct(be, bi8t, "a", bu8t, "b", bf32t, "c", nullptr);
@@ -79,6 +80,10 @@
bu64t, "c", nullptr);
Btype *st7 = mkBackendStruct(be, bf32t, "f1", bu32t, "f2", nullptr);
Btype *st8 = mkBackendStruct(be, bi8t, "f1", bi16t, "f2", st7, "f3", nullptr);
+ Btype *stii = mkBackendStruct(be, bu64t, "a", bu64t, "b", nullptr);
+ Btype *stip = mkBackendStruct(be, bu64t, "a", bpu64t, "b", nullptr);
+ Btype *stpi = mkBackendStruct(be, bpu64t, "a", bu64t, "b", nullptr);
+ Btype *stpp = mkBackendStruct(be, bpu64t, "a", bpu64t, "b", nullptr);
Btype *at0 = be->array_type(bu32t, mkInt64Const(be, int64_t(0)));
Btype *at1 = be->array_type(bu32t, mkInt64Const(be, int64_t(1)));
Btype *at2 = be->array_type(bu32t, mkInt64Const(be, int64_t(3)));
@@ -182,6 +187,16 @@
"Param 1: Direct AttrNest { i8* } sigOffset: 0 "
"Param 2: Direct { i64, i64 } sigOffset: 1",
"{ i64, i32 } (i8*, i64, i64)"),
+
+ // 12
+ // Make sure pointerness is preserved.
+ FcnItem( { stip }, { stii, stpp, stpi },
+ "Return: Direct { { i64, i8* } } sigOffset: -1 "
+ "Param 1: Direct AttrNest { i8* } sigOffset: 0 "
+ "Param 2: Direct { i64, i64 } sigOffset: 1 "
+ "Param 3: Direct { i8*, i8* } sigOffset: 3 "
+ "Param 4: Direct { i8*, i64 } sigOffset: 5",
+ "{ i64, i8* } (i8*, i64, i64, i8*, i8*, i8*, i64)"),
};
unsigned count = 1;