summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2012-09-21 23:36:40 +0000
committerChandler Carruth <chandlerc@gmail.com>2012-09-21 23:36:40 +0000
commitd54a6b56a91c72cc33ce3dafcf1653123e6fdd87 (patch)
tree4ff7c38ddea533a2c4ed7c3cbf8fe89fb1982145
parentc69bdadac9431efc0cfa6832a321e0f51ab4e6cd (diff)
downloadllvm-d54a6b56a91c72cc33ce3dafcf1653123e6fdd87.tar.gz
llvm-d54a6b56a91c72cc33ce3dafcf1653123e6fdd87.tar.bz2
llvm-d54a6b56a91c72cc33ce3dafcf1653123e6fdd87.tar.xz
Fix a case where the new SROA pass failed to zap dead operands to
selects with a constant condition. This resulted in the operands remaining live through the SROA rewriter. Most of the time, this just caused some dead allocas to persist and get zapped by later passes, but in one case found by Joerg, it caused a crash when we tried to *promote* the alloca despite it having this dead use. We already have the mechanisms in place to handle this, just wire select up to them. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@164427 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Transforms/Scalar/SROA.cpp4
-rw-r--r--test/Transforms/SROA/phi-and-select.ll18
2 files changed, 15 insertions, 7 deletions
diff --git a/lib/Transforms/Scalar/SROA.cpp b/lib/Transforms/Scalar/SROA.cpp
index 3b0cb38338..e1f0286856 100644
--- a/lib/Transforms/Scalar/SROA.cpp
+++ b/lib/Transforms/Scalar/SROA.cpp
@@ -901,6 +901,10 @@ private:
// If the result of the constant fold will be the pointer, recurse
// through the select as if we had RAUW'ed it.
enqueueUsers(SI, Offset);
+ else
+ // Otherwise the operand to the select is dead, and we can replace it
+ // with undef.
+ P.DeadOperands.push_back(U);
return;
}
diff --git a/test/Transforms/SROA/phi-and-select.ll b/test/Transforms/SROA/phi-and-select.ll
index f7c479f856..ad0c55748d 100644
--- a/test/Transforms/SROA/phi-and-select.ll
+++ b/test/Transforms/SROA/phi-and-select.ll
@@ -130,31 +130,35 @@ entry:
; CHECK: ret i32 1
}
-declare void @f(i32*)
+declare void @f(i32*, i32*)
define i32 @test6(i32* %b) {
; CHECK: @test6
entry:
%a = alloca [2 x i32]
-; The alloca remains because it is used in a dead select.
-; CHECK: alloca
+ %c = alloca i32
+; CHECK-NOT: alloca
%a1 = getelementptr [2 x i32]* %a, i64 0, i32 1
store i32 1, i32* %a1
%select = select i1 true, i32* %a1, i32* %b
%select2 = select i1 false, i32* %a1, i32* %b
-; CHECK-NOT: select i1 true
-; We don't aggressively DCE this select.
-; CHECK: select i1 false
+ %select3 = select i1 false, i32* %c, i32* %b
+; CHECK: %[[select2:.*]] = select i1 false, i32* undef, i32* %b
+; CHECK: %[[select3:.*]] = select i1 false, i32* undef, i32* %b
; Note, this would potentially escape the alloca pointer except for the
; constant folding of the select.
- call void @f(i32* %select2)
+ call void @f(i32* %select2, i32* %select3)
+; CHECK: call void @f(i32* %[[select2]], i32* %[[select3]])
+
%result = load i32* %select
; CHECK-NOT: load
+ %dead = load i32* %c
+
ret i32 %result
; CHECK: ret i32 1
}