Author: wdietz2 Date: Mon Feb 25 16:37:49 2013 New Revision: 176056 URL: http://llvm.org/viewvc/llvm-project?rev=176056&view=rev Log: [ubsan] Emit single check for left shift.
Avoids warning twice on same shift. Modified: cfe/trunk/lib/CodeGen/CGExprScalar.cpp cfe/trunk/test/CodeGen/catch-undef-behavior.c cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp Modified: cfe/trunk/lib/CodeGen/CGExprScalar.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprScalar.cpp?rev=176056&r1=176055&r2=176056&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGExprScalar.cpp (original) +++ cfe/trunk/lib/CodeGen/CGExprScalar.cpp Mon Feb 25 16:37:49 2013 @@ -2407,13 +2407,17 @@ Value *ScalarExprEmitter::EmitShl(const if (CGF.SanOpts->Shift && !CGF.getLangOpts().OpenCL && isa<llvm::IntegerType>(Ops.LHS->getType())) { llvm::Value *WidthMinusOne = GetWidthMinusOneValue(Ops.LHS, RHS); - // FIXME: Emit the branching explicitly rather than emitting the check - // twice. - EmitBinOpCheck(Builder.CreateICmpULE(RHS, WidthMinusOne), Ops); + llvm::Value *Valid = Builder.CreateICmpULE(RHS, WidthMinusOne); if (Ops.Ty->hasSignedIntegerRepresentation()) { + llvm::BasicBlock *Orig = Builder.GetInsertBlock(); + llvm::BasicBlock *Cont = CGF.createBasicBlock("cont"); + llvm::BasicBlock *CheckBitsShifted = CGF.createBasicBlock("check"); + Builder.CreateCondBr(Valid, CheckBitsShifted, Cont); + // Check whether we are shifting any non-zero bits off the top of the // integer. + CGF.EmitBlock(CheckBitsShifted); llvm::Value *BitsShiftedOff = Builder.CreateLShr(Ops.LHS, Builder.CreateSub(WidthMinusOne, RHS, "shl.zeros", @@ -2428,8 +2432,15 @@ Value *ScalarExprEmitter::EmitShl(const BitsShiftedOff = Builder.CreateLShr(BitsShiftedOff, One); } llvm::Value *Zero = llvm::ConstantInt::get(BitsShiftedOff->getType(), 0); - EmitBinOpCheck(Builder.CreateICmpEQ(BitsShiftedOff, Zero), Ops); + llvm::Value *SecondCheck = Builder.CreateICmpEQ(BitsShiftedOff, Zero); + CGF.EmitBlock(Cont); + llvm::PHINode *P = Builder.CreatePHI(Valid->getType(), 2); + P->addIncoming(Valid, Orig); + P->addIncoming(SecondCheck, CheckBitsShifted); + Valid = P; } + + EmitBinOpCheck(Valid, Ops); } // OpenCL 6.3j: shift values are effectively % word size of LHS. if (CGF.getLangOpts().OpenCL) Modified: cfe/trunk/test/CodeGen/catch-undef-behavior.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/catch-undef-behavior.c?rev=176056&r1=176055&r2=176056&view=diff ============================================================================== --- cfe/trunk/test/CodeGen/catch-undef-behavior.c (original) +++ cfe/trunk/test/CodeGen/catch-undef-behavior.c Mon Feb 25 16:37:49 2013 @@ -8,8 +8,7 @@ // FIXME: When we only emit each type once, use [[INT]] more below. // CHECK: @[[LINE_100:.*]] = private unnamed_addr global {{.*}}, i32 100, i32 5 {{.*}} @[[INT]], i64 4, i8 1 // CHECK: @[[LINE_200:.*]] = {{.*}}, i32 200, i32 10 {{.*}}, i64 4, i8 0 -// CHECK: @[[LINE_300_A:.*]] = {{.*}}, i32 300, i32 12 {{.*}} @{{.*}}, {{.*}} @{{.*}} -// CHECK: @[[LINE_300_B:.*]] = {{.*}}, i32 300, i32 12 {{.*}} @{{.*}}, {{.*}} @{{.*}} +// CHECK: @[[LINE_300:.*]] = {{.*}}, i32 300, i32 12 {{.*}} @{{.*}}, {{.*}} @{{.*}} // CHECK: @[[LINE_400:.*]] = {{.*}}, i32 400, i32 12 {{.*}} @{{.*}}, {{.*}} @{{.*}} // CHECK: @[[LINE_500:.*]] = {{.*}}, i32 500, i32 10 {{.*}} @{{.*}}, i64 4, i8 0 } // CHECK: @[[LINE_600:.*]] = {{.*}}, i32 600, i32 3 {{.*}} @{{.*}}, i64 4, i8 1 } @@ -106,35 +105,36 @@ int addr_space(int __attribute__((addres // CHECK-TRAP: @lsh_overflow int lsh_overflow(int a, int b) { // CHECK: %[[INBOUNDS:.*]] = icmp ule i32 %[[RHS:.*]], 31 - // CHECK-NEXT: br i1 %[[INBOUNDS]] + // CHECK-NEXT: br i1 %[[INBOUNDS]], label %[[CHECKBB:.*]], label %[[CONTBB:.*]] // CHECK-TRAP: %[[INBOUNDS:.*]] = icmp ule i32 %[[RHS:.*]], 31 - // CHECK-TRAP-NEXT: br i1 %[[INBOUNDS]] - - // FIXME: Only emit one trap block here. - // CHECK: %[[ARG1:.*]] = zext - // CHECK-NEXT: %[[ARG2:.*]] = zext - // CHECK-NEXT: call void @__ubsan_handle_shift_out_of_bounds(i8* bitcast ({{.*}} @[[LINE_300_A]] to i8*), i64 %[[ARG1]], i64 %[[ARG2]]) - - // CHECK-TRAP: call void @llvm.trap() [[NR_NUW]] - // CHECK-TRAP-NEXT: unreachable + // CHECK-TRAP-NEXT: br i1 %[[INBOUNDS]], label %[[CHECKBB:.*]], label %[[CONTBB:.*]] // CHECK: %[[SHIFTED_OUT_WIDTH:.*]] = sub nuw nsw i32 31, %[[RHS]] // CHECK-NEXT: %[[SHIFTED_OUT:.*]] = lshr i32 %[[LHS:.*]], %[[SHIFTED_OUT_WIDTH]] // CHECK-NEXT: %[[NO_OVERFLOW:.*]] = icmp eq i32 %[[SHIFTED_OUT]], 0 - // CHECK-NEXT: br i1 %[[NO_OVERFLOW]], {{.*}} !prof ![[WEIGHT_MD]] + // CHECK-NEXT: br label %[[CONTBB]] // CHECK-TRAP: %[[SHIFTED_OUT_WIDTH:.*]] = sub nuw nsw i32 31, %[[RHS]] // CHECK-TRAP-NEXT: %[[SHIFTED_OUT:.*]] = lshr i32 %[[LHS:.*]], %[[SHIFTED_OUT_WIDTH]] // CHECK-TRAP-NEXT: %[[NO_OVERFLOW:.*]] = icmp eq i32 %[[SHIFTED_OUT]], 0 - // CHECK-TRAP-NEXT: br i1 %[[NO_OVERFLOW]] + // CHECK-TRAP-NEXT: br label %[[CONTBB]] + + // CHECK: %[[VALID:.*]] = phi i1 [ %[[INBOUNDS]], {{.*}} ], [ %[[NO_OVERFLOW]], %[[CHECKBB]] ] + // CHECK-NEXT: br i1 %[[VALID]], {{.*}} !prof ![[WEIGHT_MD]] + + // CHECK-TRAP: %[[VALID:.*]] = phi i1 [ %[[INBOUNDS]], {{.*}} ], [ %[[NO_OVERFLOW]], %[[CHECKBB]] ] + // CHECK-TRAP-NEXT: br i1 %[[VALID]] + // CHECK: %[[ARG1:.*]] = zext // CHECK-NEXT: %[[ARG2:.*]] = zext - // CHECK-NEXT: call void @__ubsan_handle_shift_out_of_bounds(i8* bitcast ({{.*}} @[[LINE_300_B]] to i8*), i64 %[[ARG1]], i64 %[[ARG2]]) + // CHECK-NEXT: call void @__ubsan_handle_shift_out_of_bounds(i8* bitcast ({{.*}} @[[LINE_300]] to i8*), i64 %[[ARG1]], i64 %[[ARG2]]) + // CHECK-NOT: call void @__ubsan_handle_shift_out_of_bounds // CHECK-TRAP: call void @llvm.trap() [[NR_NUW]] - // CHECK-TRAP-NEXT: unreachable + // CHECK-TRAP: unreachable + // CHECK-TRAP-NOT: call void @llvm.trap() // CHECK: %[[RET:.*]] = shl i32 %[[LHS]], %[[RHS]] // CHECK-NEXT: ret i32 %[[RET]] Modified: cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp?rev=176056&r1=176055&r2=176056&view=diff ============================================================================== --- cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp (original) +++ cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp Mon Feb 25 16:37:49 2013 @@ -130,7 +130,12 @@ int lsh_overflow(int a, int b) { // CHECK-NEXT: %[[SHIFTED_OUT_NOT_SIGN:.*]] = lshr i32 %[[SHIFTED_OUT]], 1 // CHECK-NEXT: %[[NO_OVERFLOW:.*]] = icmp eq i32 %[[SHIFTED_OUT_NOT_SIGN]], 0 - // CHECK-NEXT: br i1 %[[NO_OVERFLOW]] + + // CHECK: %[[VALID:.*]] = phi i1 [ %[[INBOUNDS]], {{.*}} ], [ %[[NO_OVERFLOW]], {{.*}} ] + // CHECK-NEXT: br i1 %[[VALID]] + + // CHECK: call void @__ubsan_handle_shift_out_of_bounds + // CHECK-NOT: call void @__ubsan_handle_shift_out_of_bounds // CHECK: %[[RET:.*]] = shl i32 %[[LHS]], %[[RHS]] // CHECK-NEXT: ret i32 %[[RET]] _______________________________________________ cfe-commits mailing list cfe-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits