summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2013-03-22 00:47:07 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2013-03-22 00:47:07 +0000
commit48366f7af9eedd5bc00f46cd6ad8882d7816b8ed (patch)
treef396905dbdeb3b93bd29bac195ce04fc007193c9
parentb30d11194ca3b430539c01674a35d4fbb8faa70d (diff)
downloadbcm5719-llvm-48366f7af9eedd5bc00f46cd6ad8882d7816b8ed.tar.gz
bcm5719-llvm-48366f7af9eedd5bc00f46cd6ad8882d7816b8ed.zip
ubsan: Pass floating-point arguments to the runtime by value if they fit the
value argument. If not, be sure we don't accidentally use a dynamic alloca. llvm-svn: 177690
-rw-r--r--clang/lib/CodeGen/CGExpr.cpp11
-rw-r--r--clang/test/CodeGen/catch-undef-behavior.c27
2 files changed, 36 insertions, 2 deletions
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index ad69ebe05f7..9bfaacbbd6a 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -2078,6 +2078,15 @@ llvm::Constant *CodeGenFunction::EmitCheckTypeDescriptor(QualType T) {
llvm::Value *CodeGenFunction::EmitCheckValue(llvm::Value *V) {
llvm::Type *TargetTy = IntPtrTy;
+ // Floating-point types which fit into intptr_t are bitcast to integers
+ // and then passed directly (after zero-extension, if necessary).
+ if (V->getType()->isFloatingPointTy()) {
+ unsigned Bits = V->getType()->getPrimitiveSizeInBits();
+ if (Bits <= TargetTy->getIntegerBitWidth())
+ V = Builder.CreateBitCast(V, llvm::Type::getIntNTy(getLLVMContext(),
+ Bits));
+ }
+
// Integers which fit in intptr_t are zero-extended and passed directly.
if (V->getType()->isIntegerTy() &&
V->getType()->getIntegerBitWidth() <= TargetTy->getIntegerBitWidth())
@@ -2085,7 +2094,7 @@ llvm::Value *CodeGenFunction::EmitCheckValue(llvm::Value *V) {
// Pointers are passed directly, everything else is passed by address.
if (!V->getType()->isPointerTy()) {
- llvm::Value *Ptr = Builder.CreateAlloca(V->getType());
+ llvm::Value *Ptr = CreateTempAlloca(V->getType());
Builder.CreateStore(V, Ptr);
V = Ptr;
}
diff --git a/clang/test/CodeGen/catch-undef-behavior.c b/clang/test/CodeGen/catch-undef-behavior.c
index bd4973c069c..8e3388ea63e 100644
--- a/clang/test/CodeGen/catch-undef-behavior.c
+++ b/clang/test/CodeGen/catch-undef-behavior.c
@@ -288,7 +288,10 @@ int float_int_overflow(float f) {
// CHECK: %[[GE:.*]] = fcmp ogt float %[[F:.*]], 0xC1E0000020000000
// CHECK: %[[LE:.*]] = fcmp olt float %[[F]], 0x41E0000000000000
// CHECK: and i1 %[[GE]], %[[LE]]
- // CHECK: call void @__ubsan_handle_float_cast_overflow(
+
+ // CHECK: %[[CAST:.*]] = bitcast float %[[F]] to i32
+ // CHECK: %[[ARG:.*]] = zext i32 %[[CAST]] to i64
+ // CHECK: call void @__ubsan_handle_float_cast_overflow({{.*}}, i64 %[[ARG]]
// CHECK-TRAP: %[[GE:.*]] = fcmp ogt float %[[F:.*]], 0xC1E0000020000000
// CHECK-TRAP: %[[LE:.*]] = fcmp olt float %[[F]], 0x41E0000000000000
@@ -300,6 +303,28 @@ int float_int_overflow(float f) {
return f;
}
+// CHECK: @long_double_int_overflow
+// CHECK-TRAP: @long_double_int_overflow
+int long_double_int_overflow(long double ld) {
+ // CHECK: alloca x86_fp80
+ // CHECK: %[[GE:.*]] = fcmp ogt x86_fp80 %[[F:.*]], 0xKC01E8000000100000000
+ // CHECK: %[[LE:.*]] = fcmp olt x86_fp80 %[[F]], 0xK401E8000000000000000
+ // CHECK: and i1 %[[GE]], %[[LE]]
+
+ // CHECK: store x86_fp80 %[[F]], x86_fp80* %[[ALLOCA:.*]]
+ // CHECK: %[[ARG:.*]] = ptrtoint x86_fp80* %[[ALLOCA]] to i64
+ // CHECK: call void @__ubsan_handle_float_cast_overflow({{.*}}, i64 %[[ARG]]
+
+ // CHECK-TRAP: %[[GE:.*]] = fcmp ogt x86_fp80 %[[F:.*]], 0xKC01E800000010000000
+ // CHECK-TRAP: %[[LE:.*]] = fcmp olt x86_fp80 %[[F]], 0xK401E800000000000000
+ // CHECK-TRAP: %[[INBOUNDS:.*]] = and i1 %[[GE]], %[[LE]]
+ // CHECK-TRAP-NEXT: br i1 %[[INBOUNDS]]
+
+ // CHECK-TRAP: call void @llvm.trap() [[NR_NUW]]
+ // CHECK-TRAP-NEXT: unreachable
+ return ld;
+}
+
// CHECK: @float_uint_overflow
// CHECK-TRAP: @float_uint_overflow
unsigned float_uint_overflow(float f) {
OpenPOWER on IntegriCloud