forked from OSchip/llvm-project
Only lower __builtin_setjmp / __builtin_longjmp to
llvm.eh.sjlj.setjmp / llvm.eh.sjlj.longjmp, if the backend is known to support them outside the Exception Handling context. The default handling in LLVM codegen doesn't work and will create incorrect code. The ARM backend on the other hand will assert if the intrinsics are used. llvm-svn: 230255
This commit is contained in:
parent
0100e6c08c
commit
096feeb741
|
@ -448,8 +448,8 @@ BUILTIN(__builtin_extract_return_addr, "v*v*", "n")
|
|||
BUILTIN(__builtin_frame_address, "v*IUi", "n")
|
||||
BUILTIN(__builtin___clear_cache, "vc*c*", "n")
|
||||
BUILTIN(__builtin_flt_rounds, "i", "nc")
|
||||
BUILTIN(__builtin_setjmp, "iv**", "j")
|
||||
BUILTIN(__builtin_longjmp, "vv**i", "r")
|
||||
BUILTIN(__builtin_setjmp, "iv**", "Fj")
|
||||
BUILTIN(__builtin_longjmp, "vv**i", "Fr")
|
||||
BUILTIN(__builtin_unwind_init, "v", "")
|
||||
BUILTIN(__builtin_eh_return_data_regno, "iIi", "nc")
|
||||
BUILTIN(__builtin_snprintf, "ic*zcC*.", "nFp:2:")
|
||||
|
|
|
@ -859,6 +859,8 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
|
|||
return RValue::get(Builder.CreateZExt(Result, Int64Ty, "extend.zext"));
|
||||
}
|
||||
case Builtin::BI__builtin_setjmp: {
|
||||
if (!getTargetHooks().hasSjLjLowering(*this))
|
||||
break;
|
||||
// Buffer is a void**.
|
||||
Value *Buf = EmitScalarExpr(E->getArg(0));
|
||||
|
||||
|
@ -881,6 +883,8 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
|
|||
return RValue::get(Builder.CreateCall(F, Buf));
|
||||
}
|
||||
case Builtin::BI__builtin_longjmp: {
|
||||
if (!getTargetHooks().hasSjLjLowering(*this))
|
||||
break;
|
||||
Value *Buf = EmitScalarExpr(E->getArg(0));
|
||||
Buf = Builder.CreateBitCast(Buf, Int8PtrTy);
|
||||
|
||||
|
|
|
@ -665,6 +665,9 @@ public:
|
|||
return llvm::ConstantInt::get(CGM.Int32Ty, Sig);
|
||||
}
|
||||
|
||||
bool hasSjLjLowering(CodeGen::CodeGenFunction &CGF) const override {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -1599,6 +1602,10 @@ public:
|
|||
unsigned getOpenMPSimdDefaultAlignment(QualType) const override {
|
||||
return HasAVX ? 32 : 16;
|
||||
}
|
||||
|
||||
bool hasSjLjLowering(CodeGen::CodeGenFunction &CGF) const override {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class PS4TargetCodeGenInfo : public X86_64TargetCodeGenInfo {
|
||||
|
@ -3116,6 +3123,10 @@ public:
|
|||
unsigned getOpenMPSimdDefaultAlignment(QualType) const override {
|
||||
return 16; // Natural alignment for Altivec vectors.
|
||||
}
|
||||
|
||||
bool hasSjLjLowering(CodeGen::CodeGenFunction &CGF) const override {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -3328,6 +3339,10 @@ public:
|
|||
unsigned getOpenMPSimdDefaultAlignment(QualType) const override {
|
||||
return 16; // Natural alignment for Altivec and VSX vectors.
|
||||
}
|
||||
|
||||
bool hasSjLjLowering(CodeGen::CodeGenFunction &CGF) const override {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class PPC64TargetCodeGenInfo : public DefaultTargetCodeGenInfo {
|
||||
|
@ -3345,6 +3360,10 @@ public:
|
|||
unsigned getOpenMPSimdDefaultAlignment(QualType) const override {
|
||||
return 16; // Natural alignment for Altivec vectors.
|
||||
}
|
||||
|
||||
bool hasSjLjLowering(CodeGen::CodeGenFunction &CGF) const override {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -4462,6 +4481,12 @@ public:
|
|||
llvm::AttributeSet::FunctionIndex,
|
||||
B));
|
||||
}
|
||||
|
||||
bool hasSjLjLowering(CodeGen::CodeGenFunction &CGF) const override {
|
||||
return false;
|
||||
// FIXME: backend implementation too restricted, even on Darwin.
|
||||
// return CGF.getTarget().getTriple().isOSDarwin();
|
||||
}
|
||||
};
|
||||
|
||||
class WindowsARMTargetCodeGenInfo : public ARMTargetCodeGenInfo {
|
||||
|
|
|
@ -225,6 +225,13 @@ public:
|
|||
virtual unsigned getOpenMPSimdDefaultAlignment(QualType Type) const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// Control whether __builtin_longjmp / __builtin_setjmp are lowered to
|
||||
/// llvm.eh.sjlj.longjmp / llvm.eh.sjlj.setjmp or the normal library
|
||||
/// function.
|
||||
virtual bool hasSjLjLowering(CodeGen::CodeGenFunction &CGF) const {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
/* RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
|
||||
*
|
||||
* __builtin_longjmp/setjmp should get transformed into intrinsics.
|
||||
*/
|
||||
|
||||
// CHECK-NOT: builtin_longjmp
|
||||
|
||||
void jumpaway(int *ptr) {
|
||||
__builtin_longjmp(ptr,1);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
__builtin_setjmp(0);
|
||||
jumpaway(0);
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm < %s| FileCheck %s -check-prefix=SUPPORTED
|
||||
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm < %s| FileCheck %s -check-prefix=SUPPORTED
|
||||
// RUN: %clang_cc1 -triple powerpc-unknown-unknown -emit-llvm < %s| FileCheck %s -check-prefix=SUPPORTED
|
||||
// RUN: %clang_cc1 -triple powerpc64-unknown-unknown -emit-llvm < %s| FileCheck %s -check-prefix=SUPPORTED
|
||||
// RUN: %clang_cc1 -triple arm-unknown-unknown -emit-llvm < %s| FileCheck %s -check-prefix=UNSUPPORTED
|
||||
// RUN: %clang_cc1 -triple aarch64-unknown-unknown -emit-llvm < %s| FileCheck %s -check-prefix=UNSUPPORTED
|
||||
// RUN: %clang_cc1 -triple mips-unknown-unknown -emit-llvm < %s| FileCheck %s -check-prefix=UNSUPPORTED
|
||||
// RUN: %clang_cc1 -triple mips64-unknown-unknown -emit-llvm < %s| FileCheck %s -check-prefix=UNSUPPORTED
|
||||
|
||||
// Check that __builtin_longjmp and __builtin_setjmp are lowerd into
|
||||
// IR intrinsics on those architectures that can handle them.
|
||||
// Check that they are lowered to the libcalls on other architectures.
|
||||
|
||||
typedef void *jmp_buf;
|
||||
jmp_buf buf;
|
||||
|
||||
// SUPPORTED: define{{.*}} void @do_jump()
|
||||
// SUPPORTED: call{{.*}} void @llvm.eh.sjlj.longjmp
|
||||
// UNSUPPORTED: define{{.*}} void @do_jump()
|
||||
// UNSUPPORTED: call{{.*}} void @longjmp
|
||||
|
||||
// SUPPORTED: define{{.*}} void @do_setjmp()
|
||||
// SUPPORTED: call{{.*}} i32 @llvm.eh.sjlj.setjmp
|
||||
// UNSUPPORTED: define{{.*}} void @do_setjmp()
|
||||
// UNSUPPORTED: call{{.*}} i32 @setjmp
|
||||
|
||||
void do_jump(void) {
|
||||
__builtin_longjmp(buf, 1);
|
||||
}
|
||||
|
||||
void f(void);
|
||||
|
||||
void do_setjmp(void) {
|
||||
if (!__builtin_setjmp(buf))
|
||||
f();
|
||||
}
|
Loading…
Reference in New Issue