Skip to content

Commit be308cf

Browse files
rorthtstellar
authored andcommitted
[clang][Sparc] Fix __builtin_extract_return_addr etc.
While investigating the failures of `symbolize_pc.cpp` and `symbolize_pc_inline.cpp` on SPARC (both Solaris and Linux), I noticed that `__builtin_extract_return_addr` is a no-op in `clang` on all targets, while `gcc` has non-default implementations for arm, mips, s390, and sparc. This patch provides the SPARC implementation. For background see `SparcISelLowering.cpp` (`SparcTargetLowering::LowerReturn_32`), the SPARC psABI p.3-12, `%i7` and p.3-16/17, and SCD 2.4.1, p.3P-10, `%i7` and p.3P-15. Tested (after enabling the `sanitizer_common` tests on SPARC) on `sparcv9-sun-solaris2.11`. Differential Revision: https://reviews.llvm.org/D91607 (cherry picked from commit efdd0a2)
1 parent 7607a39 commit be308cf

File tree

2 files changed

+56
-3
lines changed

2 files changed

+56
-3
lines changed

clang/lib/CodeGen/TargetInfo.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9474,6 +9474,28 @@ class SparcV8TargetCodeGenInfo : public TargetCodeGenInfo {
94749474
public:
94759475
SparcV8TargetCodeGenInfo(CodeGenTypes &CGT)
94769476
: TargetCodeGenInfo(std::make_unique<SparcV8ABIInfo>(CGT)) {}
9477+
9478+
llvm::Value *decodeReturnAddress(CodeGen::CodeGenFunction &CGF,
9479+
llvm::Value *Address) const override {
9480+
int Offset;
9481+
if (isAggregateTypeForABI(CGF.CurFnInfo->getReturnType()))
9482+
Offset = 12;
9483+
else
9484+
Offset = 8;
9485+
return CGF.Builder.CreateGEP(CGF.Int8Ty, Address,
9486+
llvm::ConstantInt::get(CGF.Int32Ty, Offset));
9487+
}
9488+
9489+
llvm::Value *encodeReturnAddress(CodeGen::CodeGenFunction &CGF,
9490+
llvm::Value *Address) const override {
9491+
int Offset;
9492+
if (isAggregateTypeForABI(CGF.CurFnInfo->getReturnType()))
9493+
Offset = -12;
9494+
else
9495+
Offset = -8;
9496+
return CGF.Builder.CreateGEP(CGF.Int8Ty, Address,
9497+
llvm::ConstantInt::get(CGF.Int32Ty, Offset));
9498+
}
94779499
};
94789500
} // end anonymous namespace
94799501

@@ -9748,6 +9770,18 @@ class SparcV9TargetCodeGenInfo : public TargetCodeGenInfo {
97489770

97499771
bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
97509772
llvm::Value *Address) const override;
9773+
9774+
llvm::Value *decodeReturnAddress(CodeGen::CodeGenFunction &CGF,
9775+
llvm::Value *Address) const override {
9776+
return CGF.Builder.CreateGEP(CGF.Int8Ty, Address,
9777+
llvm::ConstantInt::get(CGF.Int32Ty, 8));
9778+
}
9779+
9780+
llvm::Value *encodeReturnAddress(CodeGen::CodeGenFunction &CGF,
9781+
llvm::Value *Address) const override {
9782+
return CGF.Builder.CreateGEP(CGF.Int8Ty, Address,
9783+
llvm::ConstantInt::get(CGF.Int32Ty, -8));
9784+
}
97519785
};
97529786
} // end anonymous namespace
97539787

clang/test/CodeGen/builtins-sparc.c

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,29 @@
11
// REQUIRES: sparc-registered-target
22
// RUN: %clang_cc1 -triple sparc-unknown-unknown -emit-llvm %s -o - | FileCheck %s
3-
// RUN: %clang_cc1 -triple sparc64-unknown-unknown -emit-llvm %s -o - | FileCheck %s
3+
// RUN: %clang_cc1 -triple sparc64-unknown-unknown -emit-llvm %s -o - | FileCheck -check-prefix CHECK-V9 %s
44

55
void test_eh_return_data_regno(void)
66
{
77
volatile int res;
8-
res = __builtin_eh_return_data_regno(0); // CHECK: store volatile i32 24
9-
res = __builtin_eh_return_data_regno(1); // CHECK: store volatile i32 25
8+
res = __builtin_eh_return_data_regno(0); // CHECK,CHECKV9: store volatile i32 24
9+
res = __builtin_eh_return_data_regno(1); // CHECK,CHECKV9: store volatile i32 25
10+
}
11+
12+
void *test_extract_return_address(void)
13+
{
14+
// CHECK,CHECKV9: getelementptr i8, i8* %0, i32 8
15+
return __builtin_extract_return_addr(__builtin_return_address(0));
16+
}
17+
18+
struct s {
19+
void *p;
20+
};
21+
22+
struct s test_extract_struct_return_address(void)
23+
{
24+
struct s s;
25+
// CHECK: getelementptr i8, i8* %0, i32 12
26+
// CHECK-V9: getelementptr i8, i8* %0, i32 8
27+
s.p = __builtin_extract_return_addr(__builtin_return_address(0));
28+
return s;
1029
}

0 commit comments

Comments
 (0)