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
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 859ad3e..3d9a83d 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/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);
diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp
index 8070e31..814a0b4 100644
--- a/clang/lib/CodeGen/TargetInfo.cpp
+++ b/clang/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 {
diff --git a/clang/lib/CodeGen/TargetInfo.h b/clang/lib/CodeGen/TargetInfo.h
index cc469d6..87f1376 100644
--- a/clang/lib/CodeGen/TargetInfo.h
+++ b/clang/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;
+ }
};
}