Index: lib/Transforms/Scalar/JumpThreading.cpp =================================================================== --- lib/Transforms/Scalar/JumpThreading.cpp +++ lib/Transforms/Scalar/JumpThreading.cpp @@ -1230,6 +1230,8 @@ BasicBlock *OnlyDest = nullptr; BasicBlock *MultipleDestSentinel = (BasicBlock*)(intptr_t)~0ULL; + Constant *OnlyVal = nullptr; + Constant *MultipleDestVal = (Constant *)(intptr_t)~0ULL; unsigned PredWithKnownSuccessor = 0; for (const auto &PredValue : PredValues) { @@ -1253,10 +1255,17 @@ } // If we have exactly one destination, remember it for efficiency below. - if (PredToDestList.empty()) + if (PredToDestList.empty()) { OnlyDest = DestBB; - else if (OnlyDest != DestBB) - OnlyDest = MultipleDestSentinel; + OnlyVal = Val; + } else { + if (OnlyDest != DestBB) + OnlyDest = MultipleDestSentinel; + // It possible we have same destination, but different value, e.g. default + // case in switchinst. + if (Val != OnlyVal) + OnlyVal = MultipleDestVal; + } // We know where this predecessor will go. PredWithKnownSuccessor++; @@ -1297,8 +1306,13 @@ auto *CondInst = dyn_cast(Cond); if (CondInst && CondInst->use_empty()) CondInst->eraseFromParent(); - // FIXME: in case this instruction is defined in the current BB and it - // resolves to a single value from all predecessors, we can do RAUW. + else if (CondInst && OnlyVal && OnlyVal != MultipleDestVal && + CondInst->getParent() == BB) { + // If the fact we just learned is the same value for all uses of the + // condition, replace it with a constant value + CondInst->replaceAllUsesWith(OnlyVal); + CondInst->eraseFromParent(); + } return true; } } Index: test/Transforms/JumpThreading/basic.ll =================================================================== --- test/Transforms/JumpThreading/basic.ll +++ test/Transforms/JumpThreading/basic.ll @@ -3,6 +3,35 @@ declare i32 @f1() declare i32 @f2() declare void @f3() +declare void @f4(i32) + +; Make sure we can do the RAUW for %add... +; +; CHECK-LABEL: @rauw_if_possible( +; CHECK: call void @f4(i32 96) +define void @rauw_if_possible(i32 %value) nounwind { +entry: + %cmp = icmp eq i32 %value, 32 + br i1 %cmp, label %L0, label %L3 +L0: + call i32 @f2() + call i32 @f2() + %add = add i32 %value, 64 + switch i32 %add, label %L3 [ + i32 32, label %L1 + i32 96, label %L2 + ] + +L1: + call void @f3() + ret void +L2: + call void @f4(i32 %add) + ret void +L3: + call void @f3() + ret void +} ; Make sure we can fold this branch ... We will not be able to thread it as ; L0 is too big to duplicate. @@ -43,7 +72,6 @@ call void @f3() ret void } - define i32 @test1(i1 %cond) { ; CHECK-LABEL: @test1(