Index: lib/Transforms/InstCombine/InstCombineAndOrXor.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ lib/Transforms/InstCombine/InstCombineAndOrXor.cpp @@ -2465,9 +2465,11 @@ // not (cmp A, B) = !cmp A, B CmpInst::Predicate Pred; - if (match(&I, m_Not(m_OneUse(m_Cmp(Pred, m_Value(), m_Value()))))) { - cast(Op0)->setPredicate(CmpInst::getInversePredicate(Pred)); - return replaceInstUsesWith(I, Op0); + Value *CmpL, *CmpR; + if (match(&I, m_Not(m_Cmp(Pred, m_Value(CmpL), m_Value(CmpR))))) { + CmpInst::Predicate InvPred = CmpInst::getInversePredicate(Pred); + return CmpInst::Create(cast(I.getOperand(0))->getOpcode(), InvPred, + CmpL, CmpR); } if (ConstantInt *RHSC = dyn_cast(Op1)) { Index: test/Transforms/InstCombine/logical-select.ll =================================================================== --- test/Transforms/InstCombine/logical-select.ll +++ test/Transforms/InstCombine/logical-select.ll @@ -47,10 +47,15 @@ ret i32 %t3 } +; This is a variation of the next test; see the bug report for more info. + define i32 @poo(i32 %a, i32 %b, i32 %c, i32 %d) { ; CHECK-LABEL: @poo( ; CHECK-NEXT: [[T0:%.*]] = icmp slt i32 %a, %b -; CHECK-NEXT: [[T3:%.*]] = select i1 [[T0]], i32 %c, i32 %d +; CHECK-NEXT: [[T1:%.*]] = select i1 [[T0]], i32 %c, i32 0 +; CHECK-NEXT: [[NOT_T0:%.*]] = icmp slt i32 %a, %b +; CHECK-NEXT: [[T2:%.*]] = select i1 [[NOT_T0]], i32 0, i32 %d +; CHECK-NEXT: [[T3:%.*]] = or i32 [[T1]], [[T2]] ; CHECK-NEXT: ret i32 [[T3]] ; %t0 = icmp slt i32 %a, %b Index: test/Transforms/InstCombine/select-cmp-br.ll =================================================================== --- test/Transforms/InstCombine/select-cmp-br.ll +++ test/Transforms/InstCombine/select-cmp-br.ll @@ -15,8 +15,8 @@ ; CHECK-NEXT: [[M:%.*]] = load i64*, i64** [[TMP]], align 8 ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[C]], %C* [[ARG]], i64 1, i32 0, i32 0 ; CHECK-NEXT: [[N:%.*]] = load i64*, i64** [[TMP1]], align 8 -; CHECK-NEXT: [[NOT_TMP5:%.*]] = icmp ne i64* [[M]], [[N]] ; CHECK-NEXT: [[TMP71:%.*]] = icmp eq %C* [[ARG]], null +; CHECK-NEXT: [[NOT_TMP5:%.*]] = icmp ne i64* [[M]], [[N]] ; CHECK-NEXT: [[TMP7:%.*]] = or i1 [[TMP71]], [[NOT_TMP5]] ; CHECK-NEXT: br i1 [[TMP7]], label [[BB10:%.*]], label [[BB8:%.*]] ; CHECK: bb: @@ -115,8 +115,8 @@ ; CHECK-NEXT: [[M:%.*]] = load i64*, i64** [[TMP]], align 8 ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[C]], %C* [[ARG]], i64 1, i32 0, i32 0 ; CHECK-NEXT: [[N:%.*]] = load i64*, i64** [[TMP1]], align 8 -; CHECK-NEXT: [[NOT_TMP5:%.*]] = icmp ne i64* [[M]], [[N]] ; CHECK-NEXT: [[TMP71:%.*]] = icmp eq %C* [[ARG]], null +; CHECK-NEXT: [[NOT_TMP5:%.*]] = icmp ne i64* [[M]], [[N]] ; CHECK-NEXT: [[TMP7:%.*]] = or i1 [[TMP71]], [[NOT_TMP5]] ; CHECK-NEXT: br i1 [[TMP7]], label [[BB10:%.*]], label [[BB8:%.*]] ; CHECK: bb: Index: test/Transforms/LoopVectorize/if-conversion-nest.ll =================================================================== --- test/Transforms/LoopVectorize/if-conversion-nest.ll +++ test/Transforms/LoopVectorize/if-conversion-nest.ll @@ -46,8 +46,8 @@ ; CHECK-NEXT: [[TMP14:%.*]] = select <4 x i1> [[TMP13]], <4 x i32> , <4 x i32> ; CHECK-NEXT: [[TMP15:%.*]] = and <4 x i1> [[TMP12]], [[TMP11]] ; CHECK-NEXT: [[PREDPHI:%.*]] = select <4 x i1> [[TMP15]], <4 x i32> , <4 x i32> -; CHECK-NEXT: [[TMP16:%.*]] = xor <4 x i1> [[TMP12]], -; CHECK-NEXT: [[TMP17:%.*]] = and <4 x i1> [[TMP11]], [[TMP16]] +; CHECK-NEXT: [[TMP16:%.*]] = icmp slt <4 x i32> [[WIDE_LOAD]], +; CHECK-NEXT: [[TMP17:%.*]] = and <4 x i1> [[TMP16]], [[TMP11]] ; CHECK-NEXT: [[PREDPHI7:%.*]] = select <4 x i1> [[TMP17]], <4 x i32> [[TMP14]], <4 x i32> [[PREDPHI]] ; CHECK-NEXT: [[TMP18:%.*]] = bitcast i32* [[TMP7]] to <4 x i32>* ; CHECK-NEXT: store <4 x i32> [[PREDPHI7]], <4 x i32>* [[TMP18]], align 4, !alias.scope !0, !noalias !3 Index: test/Transforms/LoopVectorize/if-conversion.ll =================================================================== --- test/Transforms/LoopVectorize/if-conversion.ll +++ test/Transforms/LoopVectorize/if-conversion.ll @@ -18,9 +18,9 @@ ;CHECK-LABEL: @function0( ;CHECK: load <4 x i32> -;CHECK: icmp sgt <4 x i32> ;CHECK: mul <4 x i32> ;CHECK: add <4 x i32> +;CHECK: icmp sgt <4 x i32> ;CHECK: select <4 x i1> ;CHECK: ret i32 define i32 @function0(i32* nocapture %a, i32* nocapture %b, i32 %start, i32 %end) nounwind uwtable ssp { @@ -71,8 +71,8 @@ ;CHECK-LABEL: @reduction_func( ;CHECK: load <4 x i32> -;CHECK: icmp slt <4 x i32> ;CHECK: add <4 x i32> +;CHECK: icmp slt <4 x i32> ;CHECK: select <4 x i1> ;CHECK: ret i32 define i32 @reduction_func(i32* nocapture %A, i32 %n) nounwind uwtable readonly ssp { Index: test/Transforms/SimplifyCFG/merge-cond-stores.ll =================================================================== --- test/Transforms/SimplifyCFG/merge-cond-stores.ll +++ test/Transforms/SimplifyCFG/merge-cond-stores.ll @@ -5,15 +5,13 @@ define void @test_simple(i32* %p, i32 %a, i32 %b) { ; CHECK-LABEL: @test_simple( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[TMP0:%.*]] = icmp ne i32 [[A:%.*]], 0 -; CHECK-NEXT: [[X2:%.*]] = icmp eq i32 [[B:%.*]], 0 -; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[X2]], true -; CHECK-NEXT: [[TMP2:%.*]] = or i1 [[TMP0]], [[TMP1]] -; CHECK-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP4:%.*]] -; CHECK: [[NOT_X2:%.*]] = xor i1 [[X2]], true +; CHECK-NEXT: [[TMP0:%.*]] = or i32 [[A:%.*]], [[B:%.*]] +; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 0 +; CHECK-NEXT: br i1 [[TMP1]], label [[TMP3:%.*]], label [[TMP2:%.*]] +; CHECK: [[NOT_X2:%.*]] = icmp ne i32 [[B]], 0 ; CHECK-NEXT: [[DOT:%.*]] = zext i1 [[NOT_X2]] to i32 ; CHECK-NEXT: store i32 [[DOT]], i32* [[P:%.*]], align 4 -; CHECK-NEXT: br label [[TMP4]] +; CHECK-NEXT: br label [[TMP3]] ; CHECK: ret void ; entry: @@ -44,7 +42,8 @@ ; CHECK-NEXT: [[X2:%.*]] = icmp eq i32 [[B:%.*]], 0 ; CHECK-NEXT: [[TMP0:%.*]] = or i1 [[X1]], [[X2]] ; CHECK-NEXT: br i1 [[TMP0]], label [[TMP1:%.*]], label [[TMP2:%.*]] -; CHECK: [[DOT:%.*]] = zext i1 [[X2]] to i32 +; CHECK: [[X3:%.*]] = icmp eq i32 [[B:%.*]], 0 +; CHECK-NEXT: [[DOT:%.*]] = zext i1 [[X3]] to i32 ; CHECK-NEXT: store i32 [[DOT]], i32* [[P:%.*]], align 4 ; CHECK-NEXT: br label [[TMP2]] ; CHECK: ret void @@ -73,20 +72,19 @@ define void @test_recursive(i32* %p, i32 %a, i32 %b, i32 %c, i32 %d) { ; CHECK-LABEL: @test_recursive( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[TMP0:%.*]] = or i32 [[B:%.*]], [[A:%.*]] -; CHECK-NEXT: [[X4:%.*]] = icmp eq i32 [[D:%.*]], 0 +; CHECK-NEXT: [[TMP0:%.*]] = or i32 [[A:%.*]], [[B:%.*]] ; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[TMP0]], [[C:%.*]] -; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP1]], 0 -; CHECK-NEXT: [[TMP2:%.*]] = xor i1 [[X4]], true -; CHECK-NEXT: [[TMP4:%.*]] = or i1 [[TMP3]], [[TMP2]] -; CHECK-NEXT: br i1 [[TMP4]], label [[TMP5:%.*]], label [[TMP6:%.*]] -; CHECK: [[X3:%.*]] = icmp eq i32 [[C]], 0 +; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[D:%.*]] +; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 0 +; CHECK-NEXT: br i1 [[TMP3]], label [[TMP5:%.*]], label [[TMP4:%.*]] +; CHECK: [[X4:%.*]] = icmp eq i32 [[D]], 0 +; CHECK-NEXT: [[X3:%.*]] = icmp eq i32 [[C]], 0 ; CHECK-NEXT: [[NOT_X2:%.*]] = icmp ne i32 [[B]], 0 ; CHECK-NEXT: [[DOT:%.*]] = zext i1 [[NOT_X2]] to i32 ; CHECK-NEXT: [[DOT_:%.*]] = select i1 [[X3]], i32 [[DOT]], i32 2 ; CHECK-NEXT: [[DOT__:%.*]] = select i1 [[X4]], i32 [[DOT_]], i32 3 ; CHECK-NEXT: store i32 [[DOT__]], i32* [[P:%.*]], align 4 -; CHECK-NEXT: br label [[TMP6]] +; CHECK-NEXT: br label [[TMP5]] ; CHECK: ret void ; entry: