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
23 lines
1.1 KiB
LLVM
23 lines
1.1 KiB
LLVM
; 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
|
|
}
|