Index: llvm/trunk/lib/Transforms/Utils/LoopUtils.cpp =================================================================== --- llvm/trunk/lib/Transforms/Utils/LoopUtils.cpp +++ llvm/trunk/lib/Transforms/Utils/LoopUtils.cpp @@ -1530,23 +1530,22 @@ auto *BI = dyn_cast(CondExitBlock->getTerminator()); if (!BI || !BI->isConditional()) return false; - // todo: handle fcmp someday + auto *Cond = dyn_cast(BI->getCondition()); + if (!Cond) + return false; // todo: this would be a lot more powerful if we used scev, but all the // plumbing is currently missing to pass a pointer in from the pass - auto *ICI = dyn_cast(BI->getCondition()); - if (!ICI) - return false; // Check for cmp (phi [x, preheader] ...), y where (pred x, y is known - auto *LHS = dyn_cast(ICI->getOperand(0)); - auto *RHS = ICI->getOperand(1); + auto *LHS = dyn_cast(Cond->getOperand(0)); + auto *RHS = Cond->getOperand(1); if (!LHS || LHS->getParent() != CurLoop->getHeader()) return false; auto DL = ExitBlock->getModule()->getDataLayout(); auto *IVStart = LHS->getIncomingValueForBlock(CurLoop->getLoopPreheader()); - auto *SimpleValOrNull = SimplifyICmpInst(ICI->getPredicate(), - IVStart, RHS, - {DL, /*TLI*/ nullptr, - DT, /*AC*/ nullptr, BI}); + auto *SimpleValOrNull = SimplifyCmpInst(Cond->getPredicate(), + IVStart, RHS, + {DL, /*TLI*/ nullptr, + DT, /*AC*/ nullptr, BI}); auto *SimpleCst = dyn_cast_or_null(SimpleValOrNull); if (!SimpleCst) return false; Index: llvm/trunk/test/Transforms/LICM/hoist-mustexec.ll =================================================================== --- llvm/trunk/test/Transforms/LICM/hoist-mustexec.ll +++ llvm/trunk/test/Transforms/LICM/hoist-mustexec.ll @@ -33,6 +33,34 @@ ret i32 -1 } +; Same as test1, but with a floating point IR and fcmp +define i32 @test_fcmp(i32* noalias nocapture readonly %a) nounwind uwtable { +; CHECK-LABEL: @test_fcmp( +entry: +; CHECK: %i1 = load i32, i32* %a, align 4 +; CHECK-NEXT: br label %for.body + br label %for.body + +for.body: + %iv = phi float [ 0.0, %entry ], [ %inc, %continue ] + %acc = phi i32 [ 0, %entry ], [ %add, %continue ] + %r.chk = fcmp olt float %iv, 2000.0 + br i1 %r.chk, label %continue, label %fail +continue: + %i1 = load i32, i32* %a, align 4 + %add = add nsw i32 %i1, %acc + %inc = fadd float %iv, 1.0 + %exitcond = fcmp ogt float %inc, 1000.0 + br i1 %exitcond, label %for.cond.cleanup, label %for.body + +for.cond.cleanup: + ret i32 %add + +fail: + call void @f() + ret i32 -1 +} + ; Count down from a.length w/entry guard ; TODO: currently unable to prove the following: ; ule i32 (add nsw i32 %len, -1), %len where len is [0, 512]