Index: lib/Analysis/ValueTracking.cpp =================================================================== --- lib/Analysis/ValueTracking.cpp +++ lib/Analysis/ValueTracking.cpp @@ -3966,7 +3966,10 @@ unsigned Depth, AssumptionCache *AC, const Instruction *CxtI, const DominatorTree *DT) { - assert(LHS->getType() == RHS->getType() && "mismatched type"); + // Types must match. + if (LHS->getType() != RHS->getType()) + return None; + Type *OpTy = LHS->getType(); assert(OpTy->getScalarType()->isIntegerTy(1)); Index: lib/Transforms/InstCombine/InstCombineSelect.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineSelect.cpp +++ lib/Transforms/InstCombine/InstCombineSelect.cpp @@ -1213,5 +1213,23 @@ } } + // See if we can determine the result of this select based on a dominating + // condition. + BasicBlock *Parent = SI.getParent(); + BasicBlock *Dom = Parent->getSinglePredecessor(); + auto *PBI = + Dom ? dyn_cast_or_null(Dom->getTerminator()) : nullptr; + if (PBI && PBI->isConditional() && + PBI->getSuccessor(0) != PBI->getSuccessor(1) && + (PBI->getSuccessor(0) == Parent || PBI->getSuccessor(1) == Parent)) { + bool CondIsFalse = PBI->getSuccessor(1) == Parent; + Optional Implication = isImpliedCondition( + PBI->getCondition(), SI.getCondition(), DL, CondIsFalse); + if (Implication) { + Value *V = *Implication ? TrueVal : FalseVal; + return replaceInstUsesWith(SI, V); + } + } + return nullptr; } Index: test/Transforms/InstCombine/pr21210.ll =================================================================== --- test/Transforms/InstCombine/pr21210.ll +++ test/Transforms/InstCombine/pr21210.ll @@ -40,7 +40,8 @@ br label %b1 b1: -; CHECK: phi i32 [ %cond, %bb ], [ undef, %b0 ], [ %0, %entry ] +; This seems perfectly fine to me? +; CHECK: phi i32 [ %len, %bb ], [ undef, %b0 ], [ %0, %entry ] %1 = phi i32 [ %cond, %bb ], [ undef, %b0 ], [ %0, %entry ] br label %ret Index: test/Transforms/InstCombine/select-implied.ll =================================================================== --- /dev/null +++ test/Transforms/InstCombine/select-implied.ll @@ -0,0 +1,54 @@ +; RUN: opt < %s -instcombine -S | FileCheck %s + +; A == B implies A >u B is false. +; CHECK-LABEL: @test1 +; CHECK: call void @foo(i32 10) +define void @test1(i32 %a, i32 %b) { + %cmp1 = icmp eq i32 %a, %b + br i1 %cmp1, label %taken, label %end + +taken: + %cmp2 = icmp ugt i32 %a, %b + %c = select i1 %cmp2, i32 0, i32 10 + call void @foo(i32 %c) + br label %end + +end: + ret void +} + +; If A == B is false then A != B is true. +; CHECK-LABEL: @test2 +; CHECK: call void @foo(i32 20) +define void @test2(i32 %a, i32 %b) { + %cmp1 = icmp eq i32 %a, %b + br i1 %cmp1, label %end, label %taken + +taken: + %cmp2 = icmp ne i32 %a, %b + %c = select i1 %cmp2, i32 20, i32 0 + call void @foo(i32 %c) + br label %end + +end: + ret void +} + +; A >u 10 implies A >u 10 is true. +; CHECK-LABEL: @test3 +; CHECK: call void @foo(i32 30) +define void @test3(i32 %a, i32 %b) { + %cmp1 = icmp ugt i32 %a, 10 + br i1 %cmp1, label %taken, label %end + +taken: + %cmp2 = icmp ugt i32 %a, 10 + %c = select i1 %cmp2, i32 30, i32 0 + call void @foo(i32 %c) + br label %end + +end: + ret void +} + +declare void @foo(i32)