summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Analysis/InstructionSimplify.cpp7
-rw-r--r--llvm/test/Transforms/InstCombine/icmp.ll4
-rw-r--r--llvm/test/Transforms/NewGVN/pr31613.ll19
3 files changed, 20 insertions, 10 deletions
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 1c839fed171..851306bfe20 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -3045,9 +3045,16 @@ static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
std::swap(LHS, RHS);
Pred = CmpInst::getSwappedPredicate(Pred);
}
+ assert(!isa<UndefValue>(LHS) && "Unexpected icmp undef,%X");
Type *ITy = GetCompareTy(LHS); // The return type.
+ // For EQ and NE, we can always pick a value for the undef to make the
+ // predicate pass or fail, so we can return undef.
+ // Matches behavior in llvm::ConstantFoldCompareInstruction.
+ if (isa<UndefValue>(RHS) && ICmpInst::isEquality(Pred))
+ return UndefValue::get(ITy);
+
// icmp X, X -> true/false
// icmp X, undef -> true/false because undef could be X.
if (LHS == RHS || isa<UndefValue>(RHS))
diff --git a/llvm/test/Transforms/InstCombine/icmp.ll b/llvm/test/Transforms/InstCombine/icmp.ll
index b2244c5de2b..3fecf97e89d 100644
--- a/llvm/test/Transforms/InstCombine/icmp.ll
+++ b/llvm/test/Transforms/InstCombine/icmp.ll
@@ -69,14 +69,14 @@ define i32 @test4(i32 %X) {
; PR4837
define <2 x i1> @test5_eq(<2 x i64> %x) {
; CHECK-LABEL: @test5_eq(
-; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true>
+; CHECK-NEXT: ret <2 x i1> undef
;
%V = icmp eq <2 x i64> %x, undef
ret <2 x i1> %V
}
define <2 x i1> @test5_ne(<2 x i64> %x) {
; CHECK-LABEL: @test5_ne(
-; CHECK-NEXT: ret <2 x i1> zeroinitializer
+; CHECK-NEXT: ret <2 x i1> undef
;
%V = icmp ne <2 x i64> %x, undef
ret <2 x i1> %V
diff --git a/llvm/test/Transforms/NewGVN/pr31613.ll b/llvm/test/Transforms/NewGVN/pr31613.ll
index d96ea18466a..789541f74bd 100644
--- a/llvm/test/Transforms/NewGVN/pr31613.ll
+++ b/llvm/test/Transforms/NewGVN/pr31613.ll
@@ -71,32 +71,35 @@ bb18: ; preds = %bb4
declare void @c.d.p(i64, i8*)
-define void @e() {
+define void @e(i32 %a0, i32 %a1, %struct.a** %p2) {
; CHECK-LABEL: @e(
; CHECK-NEXT: [[F:%.*]] = alloca i32
-; CHECK-NEXT: store i32 undef, i32* [[F]], !g !0
+; CHECK-NEXT: store i32 [[A0:%.*]], i32* [[F]], !g !0
; CHECK-NEXT: br label [[H:%.*]]
; CHECK: h:
; CHECK-NEXT: call void @c.d.p(i64 8, i8* undef)
+; CHECK-NEXT: [[I:%.*]] = load i32, i32* [[F]]
; CHECK-NEXT: [[J:%.*]] = load i32, i32* null
-; CHECK-NEXT: br i1 true, label [[L:%.*]], label [[Q:%.*]]
+; CHECK-NEXT: [[K:%.*]] = icmp eq i32 [[I]], [[J]]
+; CHECK-NEXT: br i1 [[K]], label [[L:%.*]], label [[Q:%.*]]
; CHECK: l:
; CHECK-NEXT: br label [[R:%.*]]
; CHECK: q:
-; CHECK-NEXT: store i8 undef, i8* null
+; CHECK-NEXT: [[M:%.*]] = load %struct.a*, %struct.a** null
; CHECK-NEXT: br label [[R]]
; CHECK: r:
; CHECK-NEXT: switch i32 undef, label [[N:%.*]] [
; CHECK-NEXT: i32 0, label [[S:%.*]]
; CHECK-NEXT: ]
; CHECK: s:
+; CHECK-NEXT: store i32 [[A1:%.*]], i32* [[F]], !g !0
; CHECK-NEXT: br label [[H]]
; CHECK: n:
-; CHECK-NEXT: [[O:%.*]] = load %struct.a*, %struct.a** null
+; CHECK-NEXT: [[O:%.*]] = load %struct.a*, %struct.a** [[P2:%.*]]
; CHECK-NEXT: ret void
;
%f = alloca i32
- store i32 undef, i32* %f, !g !0
+ store i32 %a0, i32* %f, !g !0
br label %h
h: ; preds = %s, %0
@@ -120,11 +123,11 @@ r: ; preds = %q, %l
]
s: ; preds = %r
- store i32 undef, i32* %f, !g !0
+ store i32 %a1, i32* %f, !g !0
br label %h
n: ; preds = %r
- %o = load %struct.a*, %struct.a** null
+ %o = load %struct.a*, %struct.a** %p2
%2 = bitcast %struct.a* %o to %struct.b*
ret void
}
OpenPOWER on IntegriCloud