From: Richard Sandiford Date: Wed, 4 Dec 2013 09:59:57 +0000 (+0000) Subject: [SystemZ] Fix handling of pass-by-pointer arguments X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=76aef2149440afb75620bd4a3ca824ef0b968305;p=clang [SystemZ] Fix handling of pass-by-pointer arguments I'd misunderstood getIndirect() to mean that the argument should be passed as a pointer at the ABI level, with the ByVal argument choosing caller-copy semantics over no-caller-copy (callee-copy-on-write) semantics. But getIndirect(x) actually means that x is passed by pointer at the IR level but (at least on all other targets I looked at) directly at the ABI level. getIndirect(x, false) selects a pointer to a caller-made copy, which is what SystemZ was aiming for. This fixes a miscompilation of c-index-test. Structure arguments were being passed by pointer, but no copy was being made, so a write in the callee stomped over a caller's local variable. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@196370 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp index 3d0c9f1601..76acf871da 100644 --- a/lib/CodeGen/TargetInfo.cpp +++ b/lib/CodeGen/TargetInfo.cpp @@ -4573,7 +4573,7 @@ ABIArgInfo SystemZABIInfo::classifyArgumentType(QualType Ty) const { // Values that are not 1, 2, 4 or 8 bytes in size are passed indirectly. uint64_t Size = getContext().getTypeSize(Ty); if (Size != 8 && Size != 16 && Size != 32 && Size != 64) - return ABIArgInfo::getIndirect(0); + return ABIArgInfo::getIndirect(0, /*ByVal=*/false); // Handle small structures. if (const RecordType *RT = Ty->getAs()) { @@ -4581,7 +4581,7 @@ ABIArgInfo SystemZABIInfo::classifyArgumentType(QualType Ty) const { // fail the size test above. const RecordDecl *RD = RT->getDecl(); if (RD->hasFlexibleArrayMember()) - return ABIArgInfo::getIndirect(0); + return ABIArgInfo::getIndirect(0, /*ByVal=*/false); // The structure is passed as an unextended integer, a float, or a double. llvm::Type *PassTy; @@ -4598,7 +4598,7 @@ ABIArgInfo SystemZABIInfo::classifyArgumentType(QualType Ty) const { // Non-structure compounds are passed indirectly. if (isCompoundType(Ty)) - return ABIArgInfo::getIndirect(0); + return ABIArgInfo::getIndirect(0, /*ByVal=*/false); return ABIArgInfo::getDirect(0); } diff --git a/test/CodeGen/systemz-inline-asm.c b/test/CodeGen/systemz-inline-asm.c index eb0f9128fc..c9372333b1 100644 --- a/test/CodeGen/systemz-inline-asm.c +++ b/test/CodeGen/systemz-inline-asm.c @@ -123,7 +123,7 @@ double test_f64(double f, double g) { long double test_f128(long double f, long double g) { asm("axbr %0, %2" : "=f" (f) : "0" (f), "f" (g)); return f; -// CHECK: define void @test_f128(fp128* noalias nocapture sret [[DEST:%.*]], fp128* byval nocapture readonly, fp128* byval nocapture readonly) +// CHECK: define void @test_f128(fp128* noalias nocapture sret [[DEST:%.*]], fp128* nocapture readonly, fp128* nocapture readonly) // CHECK: %f = load fp128* %0 // CHECK: %g = load fp128* %1 // CHECK: [[RESULT:%.*]] = tail call fp128 asm "axbr $0, $2", "=f,0,f"(fp128 %f, fp128 %g)