forked from OSchip/llvm-project
[CodeGenPrepare] Don't create dead instructions in addrmode sinking
When we fail to sink an instruction, we must make sure not to modify the function; otherwise, we end up in an infinite loop because CodeGenPrepare iterates until it doesn't make any changes. Fixes https://bugs.llvm.org/show_bug.cgi?id=33608 . llvm-svn: 307866
This commit is contained in:
parent
c1e903be19
commit
6f7c9ad7d4
|
@ -4393,6 +4393,20 @@ bool CodeGenPrepare::optimizeMemoryInst(Instruction *MemoryInst, Value *Addr,
|
||||||
AddrMode.Scale = 0;
|
AddrMode.Scale = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// It is only safe to sign extend the BaseReg if we know that the math
|
||||||
|
// required to create it did not overflow before we extend it. Since
|
||||||
|
// the original IR value was tossed in favor of a constant back when
|
||||||
|
// the AddrMode was created we need to bail out gracefully if widths
|
||||||
|
// do not match instead of extending it.
|
||||||
|
//
|
||||||
|
// (See below for code to add the scale.)
|
||||||
|
if (AddrMode.Scale) {
|
||||||
|
Type *ScaledRegTy = AddrMode.ScaledReg->getType();
|
||||||
|
if (cast<IntegerType>(IntPtrTy)->getBitWidth() >
|
||||||
|
cast<IntegerType>(ScaledRegTy)->getBitWidth())
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (AddrMode.BaseGV) {
|
if (AddrMode.BaseGV) {
|
||||||
if (ResultPtr)
|
if (ResultPtr)
|
||||||
return false;
|
return false;
|
||||||
|
@ -4443,19 +4457,11 @@ bool CodeGenPrepare::optimizeMemoryInst(Instruction *MemoryInst, Value *Addr,
|
||||||
Value *V = AddrMode.ScaledReg;
|
Value *V = AddrMode.ScaledReg;
|
||||||
if (V->getType() == IntPtrTy) {
|
if (V->getType() == IntPtrTy) {
|
||||||
// done.
|
// done.
|
||||||
} else if (cast<IntegerType>(IntPtrTy)->getBitWidth() <
|
|
||||||
cast<IntegerType>(V->getType())->getBitWidth()) {
|
|
||||||
V = Builder.CreateTrunc(V, IntPtrTy, "sunkaddr");
|
|
||||||
} else {
|
} else {
|
||||||
// It is only safe to sign extend the BaseReg if we know that the math
|
assert(cast<IntegerType>(IntPtrTy)->getBitWidth() <
|
||||||
// required to create it did not overflow before we extend it. Since
|
cast<IntegerType>(V->getType())->getBitWidth() &&
|
||||||
// the original IR value was tossed in favor of a constant back when
|
"We can't transform if ScaledReg is too narrow");
|
||||||
// the AddrMode was created we need to bail out gracefully if widths
|
V = Builder.CreateTrunc(V, IntPtrTy, "sunkaddr");
|
||||||
// do not match instead of extending it.
|
|
||||||
Instruction *I = dyn_cast_or_null<Instruction>(ResultIndex);
|
|
||||||
if (I && (ResultIndex != AddrMode.BaseReg))
|
|
||||||
I->eraseFromParent();
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (AddrMode.Scale != 1)
|
if (AddrMode.Scale != 1)
|
||||||
|
|
|
@ -4,6 +4,8 @@ target datalayout =
|
||||||
"e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
|
"e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
|
||||||
target triple = "x86_64-unknown-linux-gnu"
|
target triple = "x86_64-unknown-linux-gnu"
|
||||||
|
|
||||||
|
@x = external global [1 x [2 x <4 x float>]]
|
||||||
|
|
||||||
; Can we sink single addressing mode computation to use?
|
; Can we sink single addressing mode computation to use?
|
||||||
define void @test1(i1 %cond, i64* %base) {
|
define void @test1(i1 %cond, i64* %base) {
|
||||||
; CHECK-LABEL: @test1
|
; CHECK-LABEL: @test1
|
||||||
|
@ -194,3 +196,25 @@ rare.2:
|
||||||
|
|
||||||
|
|
||||||
declare void @slowpath(i32, i32*)
|
declare void @slowpath(i32, i32*)
|
||||||
|
|
||||||
|
; Make sure we don't end up in an infinite loop after we fail to sink.
|
||||||
|
; CHECK-LABEL: define void @test8
|
||||||
|
; CHECK: %ptr = getelementptr i8, i8* %aFOO_load_ptr2int_2void, i32 undef
|
||||||
|
define void @test8() {
|
||||||
|
allocas:
|
||||||
|
%aFOO_load = load float*, float** undef
|
||||||
|
%aFOO_load_ptr2int = ptrtoint float* %aFOO_load to i64
|
||||||
|
%aFOO_load_ptr2int_broadcast_init = insertelement <4 x i64> undef, i64 %aFOO_load_ptr2int, i32 0
|
||||||
|
%aFOO_load_ptr2int_2void = inttoptr i64 %aFOO_load_ptr2int to i8*
|
||||||
|
%ptr = getelementptr i8, i8* %aFOO_load_ptr2int_2void, i32 undef
|
||||||
|
br label %load.i145
|
||||||
|
|
||||||
|
load.i145:
|
||||||
|
%ptr.i143 = bitcast i8* %ptr to <4 x float>*
|
||||||
|
%valall.i144 = load <4 x float>, <4 x float>* %ptr.i143, align 4
|
||||||
|
%x_offset = getelementptr [1 x [2 x <4 x float>]], [1 x [2 x <4 x float>]]* @x, i32 0, i64 0
|
||||||
|
br label %pl_loop.i.i122
|
||||||
|
|
||||||
|
pl_loop.i.i122:
|
||||||
|
br label %pl_loop.i.i122
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue