aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGExprScalar.cpp
diff options
context:
space:
mode:
authorWill Dietz <wdietz2@illinois.edu>2013-02-25 22:37:49 +0000
committerWill Dietz <wdietz2@illinois.edu>2013-02-25 22:37:49 +0000
commitbb60fc6a71f280f8e19e7f1a784ef05c40f5aa39 (patch)
tree303f3bb6c0463f51b2afe244d409574094b4496f /lib/CodeGen/CGExprScalar.cpp
parentdb061e40d639da0d938f915f0eef9e9772019c22 (diff)
[ubsan] Emit single check for left shift.
Avoids warning twice on same shift. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@176056 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGExprScalar.cpp')
-rw-r--r--lib/CodeGen/CGExprScalar.cpp19
1 files changed, 15 insertions, 4 deletions
diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp
index d76cad2c56..3ec4040a64 100644
--- a/lib/CodeGen/CGExprScalar.cpp
+++ b/lib/CodeGen/CGExprScalar.cpp
@@ -2407,13 +2407,17 @@ Value *ScalarExprEmitter::EmitShl(const BinOpInfo &Ops) {
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 BinOpInfo &Ops) {
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)