Hi grosbach, t.p.northover, hans,
Ruby is currently crashing on ARM because SelectionDAG turns
llvm.eh.sjlj.longjmp and llvm.eh.sjlj.setjmp into nonsense, if the target has
no lowering for them. Handle this properly in the frontend by not using the IR
intrinsics unless the platform is known to have a working implementation. As
documented with the FIXME, the Darwin lowering does not qualify either, it is
written strictly for use by EH.
http://reviews.llvm.org/D7795
Files:
include/clang/Basic/Builtins.def
lib/CodeGen/CGBuiltin.cpp
lib/CodeGen/TargetInfo.cpp
lib/CodeGen/TargetInfo.h
test/CodeGen/2003-08-06-BuiltinSetjmpLongjmp.c
test/CodeGen/builtin-longjmp.c
EMAIL PREFERENCES
http://reviews.llvm.org/settings/panel/emailpreferences/
Index: include/clang/Basic/Builtins.def
===================================================================
--- include/clang/Basic/Builtins.def
+++ include/clang/Basic/Builtins.def
@@ -448,8 +448,8 @@
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:")
Index: lib/CodeGen/CGBuiltin.cpp
===================================================================
--- lib/CodeGen/CGBuiltin.cpp
+++ lib/CodeGen/CGBuiltin.cpp
@@ -859,6 +859,8 @@
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 @@
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);
Index: lib/CodeGen/TargetInfo.cpp
===================================================================
--- lib/CodeGen/TargetInfo.cpp
+++ lib/CodeGen/TargetInfo.cpp
@@ -665,6 +665,9 @@
return llvm::ConstantInt::get(CGM.Int32Ty, Sig);
}
+ bool hasSjLjLowering(CodeGen::CodeGenFunction &CGF) const override {
+ return true;
+ }
};
}
@@ -1599,6 +1602,10 @@
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 @@
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 @@
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 @@
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 @@
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 {
Index: lib/CodeGen/TargetInfo.h
===================================================================
--- lib/CodeGen/TargetInfo.h
+++ lib/CodeGen/TargetInfo.h
@@ -225,6 +225,13 @@
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;
+ }
};
}
Index: test/CodeGen/2003-08-06-BuiltinSetjmpLongjmp.c
===================================================================
--- test/CodeGen/2003-08-06-BuiltinSetjmpLongjmp.c
+++ test/CodeGen/2003-08-06-BuiltinSetjmpLongjmp.c
@@ -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);
-}
Index: test/CodeGen/builtin-longjmp.c
===================================================================
--- test/CodeGen/builtin-longjmp.c
+++ test/CodeGen/builtin-longjmp.c
@@ -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();
+}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits