Index: llvm/trunk/lib/Analysis/InstructionSimplify.cpp =================================================================== --- llvm/trunk/lib/Analysis/InstructionSimplify.cpp +++ llvm/trunk/lib/Analysis/InstructionSimplify.cpp @@ -3045,9 +3045,16 @@ std::swap(LHS, RHS); Pred = CmpInst::getSwappedPredicate(Pred); } + assert(!isa(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(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(RHS)) Index: llvm/trunk/test/Transforms/InstCombine/icmp.ll =================================================================== --- llvm/trunk/test/Transforms/InstCombine/icmp.ll +++ llvm/trunk/test/Transforms/InstCombine/icmp.ll @@ -69,14 +69,14 @@ ; PR4837 define <2 x i1> @test5_eq(<2 x i64> %x) { ; CHECK-LABEL: @test5_eq( -; CHECK-NEXT: ret <2 x i1> +; 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 Index: llvm/trunk/test/Transforms/NewGVN/pr31613.ll =================================================================== --- llvm/trunk/test/Transforms/NewGVN/pr31613.ll +++ llvm/trunk/test/Transforms/NewGVN/pr31613.ll @@ -71,32 +71,35 @@ 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 @@ ] 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 }