forked from OSchip/llvm-project
[CodeGenPrepare] Avoid out-of-bounds shift
AddressingModeMatcher::matchOperationAddr may attempt to shift a variable by the same amount of steps as found in the IR in a SHL instruction. This was done without considering that there could be undefined behavior in the IR, so the shift performed when compiling could end up having undefined behavior as well. This patch avoid UB in the codegenprepare by making sure that we limit the shift amount used, in a similar way as already being done in CodeGenPrepare::optimizeLoadExt. Differential Revision: https://reviews.llvm.org/D118602
This commit is contained in:
parent
1d111090ad
commit
0352ee1a22
|
@ -4550,9 +4550,9 @@ bool AddressingModeMatcher::matchOperationAddr(User *AddrInst, unsigned Opcode,
|
|||
ConstantInt *RHS = dyn_cast<ConstantInt>(AddrInst->getOperand(1));
|
||||
if (!RHS || RHS->getBitWidth() > 64)
|
||||
return false;
|
||||
int64_t Scale = RHS->getSExtValue();
|
||||
if (Opcode == Instruction::Shl)
|
||||
Scale = 1LL << Scale;
|
||||
int64_t Scale = Opcode == Instruction::Shl
|
||||
? 1LL << RHS->getLimitedValue(RHS->getBitWidth() - 1)
|
||||
: RHS->getSExtValue();
|
||||
|
||||
return matchScaledValue(AddrInst->getOperand(0), Scale, Depth);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
||||
; RUN: opt < %s -mtriple i686-unknown-unknown -codegenprepare -S | FileCheck %s
|
||||
|
||||
target datalayout = "e-p:8:8"
|
||||
|
||||
; The shl has UB (shift count oob). This used to result in undefined behavior
|
||||
; in codegenprepare when AddressingModeMatcher::matchOperationAddr tried to
|
||||
; shift a variable by that amount during compilation. Intent with the test
|
||||
; case is to verify that this compiles without complaints even if opt is built
|
||||
; with ubsan enabled.
|
||||
define dso_local void @main(i32 %a, [3 x { i8, i8 }*]* %p) {
|
||||
; CHECK-LABEL: @main(
|
||||
; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[A:%.*]], -1229216766
|
||||
; CHECK-NEXT: [[ARRAYIDX926:%.*]] = getelementptr inbounds [3 x { i8, i8 }*], [3 x { i8, i8 }*]* [[P:%.*]], i32 0, i32 [[SHL]]
|
||||
; CHECK-NEXT: [[L0:%.*]] = load { i8, i8 }*, { i8, i8 }** [[ARRAYIDX926]], align 1
|
||||
; CHECK-NEXT: ret void
|
||||
;
|
||||
%shl = shl i32 %a, -1229216766
|
||||
%arrayidx926 = getelementptr inbounds [3 x { i8, i8 }*], [3 x { i8, i8 }*]* %p, i32 0, i32 %shl
|
||||
%l0 = load { i8, i8 }*, { i8, i8 }** %arrayidx926, align 1
|
||||
ret void
|
||||
}
|
Loading…
Reference in New Issue