Index: llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp =================================================================== --- llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp +++ llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp @@ -291,9 +291,6 @@ /// Keep track of SExt promoted. ValueToSExts ValToSExtendedUses; - /// True if CFG is modified in any way. - bool ModifiedDT; - /// True if optimizing for size. bool OptSize; @@ -354,11 +351,11 @@ bool optimizeExt(Instruction *&I); bool optimizeExtUses(Instruction *I); bool optimizeLoadExt(LoadInst *Load); - bool optimizeSelectInst(SelectInst *SI); + bool optimizeSelectInst(SelectInst *SI, bool &ModifiedDT); bool optimizeShuffleVectorInst(ShuffleVectorInst *SVI); bool optimizeSwitchInst(SwitchInst *SI); bool optimizeExtractElementInst(Instruction *Inst); - bool dupRetToEnableTailCallOpts(BasicBlock *BB); + bool dupRetToEnableTailCallOpts(BasicBlock *BB, bool &ModifiedDT); bool placeDbgValues(Function &F); bool canFormExtLd(const SmallVectorImpl &MovedExts, LoadInst *&LI, Instruction *&Inst, bool HasPromoted); @@ -373,7 +370,7 @@ bool AllowPromotionWithoutCommonHeader, bool HasPromoted, TypePromotionTransaction &TPT, SmallVectorImpl &SpeculativelyMovedExts); - bool splitBranchCondition(Function &F); + bool splitBranchCondition(Function &F, bool &ModifiedDT); bool simplifyOffsetableRelocate(Instruction &I); bool tryToSinkFreeOperands(Instruction *I); @@ -402,7 +399,6 @@ InsertedInsts.clear(); PromotedInsts.clear(); - ModifiedDT = false; if (auto *TPC = getAnalysisIfAvailable()) { TM = &TPC->getTM(); SubtargetInfo = TM->getSubtargetImpl(F); @@ -445,8 +441,9 @@ // unconditional branch. EverMadeChange |= eliminateMostlyEmptyBlocks(F); + bool ModifiedDT = false; if (!DisableBranchOpts) - EverMadeChange |= splitBranchCondition(F); + EverMadeChange |= splitBranchCondition(F, ModifiedDT); // Split some critical edges where one of the sources is an indirect branch, // to help generate sane code for PHIs involving such edges. @@ -1956,7 +1953,7 @@ /// %tmp2 = tail call i32 @f2() /// ret i32 %tmp2 /// @endcode -bool CodeGenPrepare::dupRetToEnableTailCallOpts(BasicBlock *BB) { +bool CodeGenPrepare::dupRetToEnableTailCallOpts(BasicBlock *BB, bool &ModifiedDT) { if (!TLI) return false; @@ -5863,7 +5860,7 @@ /// If we have a SelectInst that will likely profit from branch prediction, /// turn it into a branch. -bool CodeGenPrepare::optimizeSelectInst(SelectInst *SI) { +bool CodeGenPrepare::optimizeSelectInst(SelectInst *SI, bool &ModifiedDT) { // If branch conversion isn't desirable, exit early. if (DisableSelectToBranch || OptSize || !TLI) return false; @@ -6957,7 +6954,7 @@ return optimizeCallInst(CI, ModifiedDT); if (SelectInst *SI = dyn_cast(I)) - return optimizeSelectInst(SI); + return optimizeSelectInst(SI, ModifiedDT); if (ShuffleVectorInst *SVI = dyn_cast(I)) return optimizeShuffleVectorInst(SVI); @@ -7015,7 +7012,7 @@ } } } - MadeChange |= dupRetToEnableTailCallOpts(&BB); + MadeChange |= dupRetToEnableTailCallOpts(&BB, ModifiedDT); return MadeChange; } @@ -7091,7 +7088,7 @@ /// /// FIXME: Remove the (equivalent?) implementation in SelectionDAG. /// -bool CodeGenPrepare::splitBranchCondition(Function &F) { +bool CodeGenPrepare::splitBranchCondition(Function &F, bool &ModifiedDT) { if (!TM || !TM->Options.EnableFastISel || !TLI || TLI->isJumpExpensive()) return false; @@ -7248,10 +7245,7 @@ } } - // Note: No point in getting fancy here, since the DT info is never - // available to CodeGenPrepare. ModifiedDT = true; - MadeChange = true; LLVM_DEBUG(dbgs() << "After branch condition splitting\n"; BB.dump(); Index: llvm/trunk/test/Transforms/CodeGenPrepare/X86/optimizeSelect-DT.ll =================================================================== --- llvm/trunk/test/Transforms/CodeGenPrepare/X86/optimizeSelect-DT.ll +++ llvm/trunk/test/Transforms/CodeGenPrepare/X86/optimizeSelect-DT.ll @@ -0,0 +1,34 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -S -codegenprepare < %s | FileCheck %s + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +define i1 @PR41004(i32 %x, i32 %y, i32 %t1) { +; CHECK-LABEL: @PR41004( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[T0:%.*]] = icmp eq i32 [[Y:%.*]], 1 +; CHECK-NEXT: br i1 [[T0]], label [[SELECT_TRUE_SINK:%.*]], label [[SELECT_END:%.*]] +; CHECK: select.true.sink: +; CHECK-NEXT: [[REM:%.*]] = srem i32 [[X:%.*]], 2 +; CHECK-NEXT: br label [[SELECT_END]] +; CHECK: select.end: +; CHECK-NEXT: [[MUL:%.*]] = phi i32 [ [[REM]], [[SELECT_TRUE_SINK]] ], [ 0, [[ENTRY:%.*]] ] +; CHECK-NEXT: [[TMP0:%.*]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 [[T1:%.*]], i32 1) +; CHECK-NEXT: [[MATH:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0 +; CHECK-NEXT: [[OV:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1 +; CHECK-NEXT: [[ADD:%.*]] = add i32 [[MATH]], [[MUL]] +; CHECK-NEXT: ret i1 [[OV]] +; +entry: + %rem = srem i32 %x, 2 + %t0 = icmp eq i32 %y, 1 + %mul = select i1 %t0, i32 %rem, i32 0 + %neg = add i32 %t1, -1 + %add = add i32 %neg, %mul + br label %if + +if: + %tobool = icmp eq i32 %t1, 0 + ret i1 %tobool +}