[llvm] c1d25df - [ValueTracking] Fix crash in PR175590 (#180355)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Feb 20 00:56:55 PST 2026
Author: Kshitij Paranjape
Date: 2026-02-20T09:56:50+01:00
New Revision: c1d25df74bd9e51ac37a3587382021565897a0bd
URL: https://github.com/llvm/llvm-project/commit/c1d25df74bd9e51ac37a3587382021565897a0bd
DIFF: https://github.com/llvm/llvm-project/commit/c1d25df74bd9e51ac37a3587382021565897a0bd.diff
LOG: [ValueTracking] Fix crash in PR175590 (#180355)
Continuation of PR #175590
Fixes the crash.
Added:
llvm/test/Transforms/AggressiveInstCombine/X86/pr175590.ll
Modified:
llvm/include/llvm/Analysis/ValueTracking.h
llvm/lib/Analysis/ValueTracking.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/Analysis/ValueTracking.h b/llvm/include/llvm/Analysis/ValueTracking.h
index 1cd88fd89aea2..5f1e7773be8d3 100644
--- a/llvm/include/llvm/Analysis/ValueTracking.h
+++ b/llvm/include/llvm/Analysis/ValueTracking.h
@@ -1001,6 +1001,24 @@ LLVM_ABI bool matchSimpleBinaryIntrinsicRecurrence(const IntrinsicInst *I,
PHINode *&P, Value *&Init,
Value *&OtherOp);
+/// Attempt to match a simple value-accumulating recurrence of the form:
+/// %llvm.intrinsic.acc = phi Ty [%Init, %Entry], [%llvm.intrinsic, %backedge]
+/// %llvm.intrinsic = call Ty @llvm.intrinsic(%OtherOp0, %OtherOp1,
+/// %llvm.intrinsic.acc)
+/// OR
+/// %llvm.intrinsic.acc = phi Ty [%Init, %Entry], [%llvm.intrinsic, %backedge]
+/// %llvm.intrinsic = call Ty @llvm.intrinsic(%llvm.intrinsic.acc, %OtherOp0,
+/// %OtherOp1)
+///
+/// The recurrence relation is of kind:
+/// X_0 = %a (initial value),
+/// X_i = call @llvm.ternary.intrinsic(X_i-1, %b, %c)
+/// Where %b, %c are not required to be loop-invariant.
+LLVM_ABI bool matchSimpleTernaryIntrinsicRecurrence(const IntrinsicInst *I,
+ PHINode *&P, Value *&Init,
+ Value *&OtherOp0,
+ Value *&OtherOp1);
+
/// Return true if RHS is known to be implied true by LHS. Return false if
/// RHS is known to be implied false by LHS. Otherwise, return std::nullopt if
/// no implication can be made. A & B must be i1 (boolean) values or a vector of
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 2d78aa4be3455..3f1d7dcbe5ade 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -5924,6 +5924,47 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
}
}
+ // Look for the case of a for loop which has a positive
+ // initial value and is incremented by a squared value.
+ // This will propagate sign information out of such loops.
+ if (P->getNumIncomingValues() != 2)
+ break;
+ else {
+ for (int i = 0; i < 2; i++) {
+ Value *RecurValue = P->getIncomingValue(1 - i);
+ IntrinsicInst *I = dyn_cast<IntrinsicInst>(RecurValue);
+ if (!I)
+ continue;
+ else {
+ Value *R, *L;
+ Value *Init;
+ PHINode *PN;
+ const Function *F = I->getFunction();
+ const fltSemantics &FltSem =
+ I->getType()->getScalarType()->getFltSemantics();
+ DenormalMode Mode =
+ F ? F->getDenormalMode(FltSem) : DenormalMode::getDynamic();
+ if (matchSimpleTernaryIntrinsicRecurrence(I, PN, Init, L, R)) {
+ switch (I->getIntrinsicID()) {
+ case Intrinsic::fma:
+ case Intrinsic::fmuladd: {
+ KnownFPClass KnownStart, KnownL;
+ computeKnownFPClass(Init, DemandedElts, InterestedClasses,
+ KnownStart, Q, Depth + 1);
+ if (KnownStart.isUnknown())
+ break;
+ computeKnownFPClass(L, DemandedElts, InterestedClasses, KnownL, Q,
+ Depth + 1);
+ if (L == R &&
+ isGuaranteedNotToBeUndef(L, Q.AC, Q.CxtI, Q.DT, Depth + 1))
+ Known = KnownFPClass::fma_square(KnownL, KnownStart, Mode);
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
break;
}
case Instruction::BitCast: {
@@ -9248,6 +9289,40 @@ static bool matchTwoInputRecurrence(const PHINode *PN, InstTy *&Inst,
return false;
}
+template <typename InstTy>
+static bool matchThreeInputRecurrence(const PHINode *PN, InstTy *&Inst,
+ Value *&Init, Value *&OtherOp0,
+ Value *&OtherOp1) {
+ if (PN->getNumIncomingValues() != 2)
+ return false;
+
+ for (unsigned I = 0; I != 2; ++I) {
+ if (auto *Operation = dyn_cast<InstTy>(PN->getIncomingValue(I));
+ Operation) {
+ Value *Op0 = Operation->getOperand(0);
+ Value *Op1 = Operation->getOperand(1);
+ Value *Op2 = Operation->getOperand(2);
+
+ if (Op0 != PN && Op1 != PN && Op2 != PN)
+ continue;
+
+ Inst = Operation;
+ Init = PN->getIncomingValue(!I);
+ if (Op0 == PN) {
+ OtherOp0 = Op1;
+ OtherOp1 = Op2;
+ } else if (Op1 == PN) {
+ OtherOp0 = Op0;
+ OtherOp1 = Op2;
+ } else {
+ OtherOp0 = Op0;
+ OtherOp1 = Op1;
+ }
+ return true;
+ }
+ }
+ return false;
+}
bool llvm::matchSimpleRecurrence(const PHINode *P, BinaryOperator *&BO,
Value *&Start, Value *&Step) {
// We try to match a recurrence of the form:
@@ -9284,6 +9359,25 @@ bool llvm::matchSimpleBinaryIntrinsicRecurrence(const IntrinsicInst *I,
return P && matchTwoInputRecurrence(P, II, Init, OtherOp) && II == I;
}
+bool llvm::matchSimpleTernaryIntrinsicRecurrence(const IntrinsicInst *I,
+ PHINode *&P, Value *&Init,
+ Value *&OtherOp0,
+ Value *&OtherOp1) {
+ if (I->arg_size() != 3 || I->getType() != I->getArgOperand(0)->getType() ||
+ I->getType() != I->getArgOperand(1)->getType() ||
+ I->getType() != I->getArgOperand(2)->getType())
+ return false;
+ IntrinsicInst *II = nullptr;
+ P = dyn_cast<PHINode>(I->getArgOperand(0));
+ if (!P) {
+ P = dyn_cast<PHINode>(I->getArgOperand(1));
+ if (!P)
+ P = dyn_cast<PHINode>(I->getArgOperand(2));
+ }
+ return P && matchThreeInputRecurrence(P, II, Init, OtherOp0, OtherOp1) &&
+ II == I;
+}
+
/// Return true if "icmp Pred LHS RHS" is always true.
static bool isTruePredicate(CmpInst::Predicate Pred, const Value *LHS,
const Value *RHS) {
diff --git a/llvm/test/Transforms/AggressiveInstCombine/X86/pr175590.ll b/llvm/test/Transforms/AggressiveInstCombine/X86/pr175590.ll
new file mode 100644
index 0000000000000..71167c2c6aef5
--- /dev/null
+++ b/llvm/test/Transforms/AggressiveInstCombine/X86/pr175590.ll
@@ -0,0 +1,265 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt < %s -passes=aggressive-instcombine -S | FileCheck %s
+target triple = "x86_64-unknown-linux-gnu"
+define double @CompareDistmats(double noundef %distmat1_, double noundef %distmat2_) {
+; CHECK-LABEL: define double @CompareDistmats(
+; CHECK-SAME: double noundef [[DISTMAT1_:%.*]], double noundef [[DISTMAT2_:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: br label %[[FOR_COND:.*]]
+; CHECK: [[FOR_COND]]:
+; CHECK-NEXT: [[RMSD_0:%.*]] = phi double [ 0.000000e+00, %[[ENTRY]] ], [ [[FMACALL:%.*]], %[[FOR_BODY:.*]] ]
+; CHECK-NEXT: [[CMP:%.*]] = phi i1 [ true, %[[ENTRY]] ], [ false, %[[FOR_BODY]] ]
+; CHECK-NEXT: br i1 [[CMP]], label %[[FOR_BODY]], label %[[FOR_COND_CLEANUP:.*]]
+; CHECK: [[FOR_COND_CLEANUP]]:
+; CHECK-NEXT: [[SQRT:%.*]] = call double @llvm.sqrt.f64(double [[RMSD_0]])
+; CHECK-NEXT: ret double [[SQRT]]
+; CHECK: [[FOR_BODY]]:
+; CHECK-NEXT: [[SUB:%.*]] = fsub double [[DISTMAT1_]], [[DISTMAT2_]]
+; CHECK-NEXT: [[FMACALL]] = call double @llvm.fmuladd.f64(double noundef [[SUB]], double noundef [[SUB]], double [[RMSD_0]])
+; CHECK-NEXT: br label %[[FOR_COND]]
+;
+entry:
+ br label %for.cond
+
+for.cond: ; preds = %for.body, %entry
+ %RMSD.0 = phi double [ 0.000000e+00, %entry ], [ %fmacall, %for.body ]
+ %cmp = phi i1 [ true, %entry ], [ false, %for.body ]
+ br i1 %cmp, label %for.body, label %for.cond.cleanup
+
+for.cond.cleanup: ; preds = %for.cond
+ %call = call double @sqrt(double noundef %RMSD.0)
+ ret double %call
+
+for.body: ; preds = %for.cond
+ %sub = fsub double %distmat1_, %distmat2_
+ %fmacall = call double @llvm.fmuladd.f64(double noundef %sub, double noundef %sub, double %RMSD.0)
+ br label %for.cond
+}
+
+define double @shuffledCompareDistmats(double noundef %distmat1_, double noundef %distmat2_) {
+; CHECK-LABEL: define double @shuffledCompareDistmats(
+; CHECK-SAME: double noundef [[DISTMAT1_:%.*]], double noundef [[DISTMAT2_:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: br label %[[FOR_COND:.*]]
+; CHECK: [[FOR_COND]]:
+; CHECK-NEXT: [[RMSD_0:%.*]] = phi double [ [[FMACALL:%.*]], %[[FOR_BODY:.*]] ], [ 0.000000e+00, %[[ENTRY]] ]
+; CHECK-NEXT: [[CMP:%.*]] = phi i1 [ true, %[[ENTRY]] ], [ false, %[[FOR_BODY]] ]
+; CHECK-NEXT: br i1 [[CMP]], label %[[FOR_BODY]], label %[[FOR_COND_CLEANUP:.*]]
+; CHECK: [[FOR_COND_CLEANUP]]:
+; CHECK-NEXT: [[CALL:%.*]] = call double @llvm.sqrt.f64(double [[RMSD_0]])
+; CHECK-NEXT: ret double [[CALL]]
+; CHECK: [[FOR_BODY]]:
+; CHECK-NEXT: [[SUB:%.*]] = fsub double [[DISTMAT1_]], [[DISTMAT2_]]
+; CHECK-NEXT: [[FMACALL]] = call double @llvm.fmuladd.f64(double noundef [[SUB]], double noundef [[SUB]], double [[RMSD_0]])
+; CHECK-NEXT: br label %[[FOR_COND]]
+;
+entry:
+ br label %for.cond
+
+for.cond: ; preds = %for.body, %entry
+ %RMSD.0 = phi double [ %fmacall, %for.body ], [ 0.000000e+00, %entry ]
+ %cmp = phi i1 [ true, %entry ], [ false, %for.body ]
+ br i1 %cmp, label %for.body, label %for.cond.cleanup
+
+for.cond.cleanup: ; preds = %for.cond
+ %call = call double @sqrt(double noundef %RMSD.0)
+ ret double %call
+
+for.body: ; preds = %for.cond
+ %sub = fsub double %distmat1_, %distmat2_
+ %fmacall = call double @llvm.fmuladd.f64(double noundef %sub, double noundef %sub, double %RMSD.0)
+ br label %for.cond
+}
+
+define double @fmaCompareDistmats(double noundef %distmat1_, double noundef %distmat2_) {
+; CHECK-LABEL: define double @fmaCompareDistmats(
+; CHECK-SAME: double noundef [[DISTMAT1_:%.*]], double noundef [[DISTMAT2_:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: br label %[[FOR_COND:.*]]
+; CHECK: [[FOR_COND]]:
+; CHECK-NEXT: [[RMSD_0:%.*]] = phi double [ 0.000000e+00, %[[ENTRY]] ], [ [[FMACALL:%.*]], %[[FOR_BODY:.*]] ]
+; CHECK-NEXT: [[CMP:%.*]] = phi i1 [ true, %[[ENTRY]] ], [ false, %[[FOR_BODY]] ]
+; CHECK-NEXT: br i1 [[CMP]], label %[[FOR_BODY]], label %[[FOR_COND_CLEANUP:.*]]
+; CHECK: [[FOR_COND_CLEANUP]]:
+; CHECK-NEXT: [[SQRT:%.*]] = call double @llvm.sqrt.f64(double [[RMSD_0]])
+; CHECK-NEXT: ret double [[SQRT]]
+; CHECK: [[FOR_BODY]]:
+; CHECK-NEXT: [[SUB:%.*]] = fsub double [[DISTMAT1_]], [[DISTMAT2_]]
+; CHECK-NEXT: [[FMACALL]] = call double @llvm.fma.f64(double [[SUB]], double [[SUB]], double [[RMSD_0]])
+; CHECK-NEXT: br label %[[FOR_COND]]
+;
+entry:
+ br label %for.cond
+
+for.cond: ; preds = %for.body, %entry
+ %RMSD.0 = phi double [ 0.000000e+00, %entry ], [ %fmacall, %for.body ]
+ %cmp = phi i1 [ true, %entry ], [ false, %for.body ]
+ br i1 %cmp, label %for.body, label %for.cond.cleanup
+
+for.cond.cleanup: ; preds = %for.cond
+ %call = call double @sqrt(double noundef %RMSD.0)
+ ret double %call
+
+for.body: ; preds = %for.cond
+ %sub = fsub double %distmat1_, %distmat2_
+ %fmacall = call double @llvm.fma.f64(double %sub, double %sub, double %RMSD.0)
+ br label %for.cond
+}
+
+define double @nonSquareCompareDistmats(double noundef %distmat1_, double noundef %distmat2_) {
+; CHECK-LABEL: define double @nonSquareCompareDistmats(
+; CHECK-SAME: double noundef [[DISTMAT1_:%.*]], double noundef [[DISTMAT2_:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: br label %[[FOR_COND:.*]]
+; CHECK: [[FOR_COND]]:
+; CHECK-NEXT: [[RMSD_0:%.*]] = phi double [ 0.000000e+00, %[[ENTRY]] ], [ [[FMACALL:%.*]], %[[FOR_BODY:.*]] ]
+; CHECK-NEXT: [[CMP:%.*]] = phi i1 [ true, %[[ENTRY]] ], [ false, %[[FOR_BODY]] ]
+; CHECK-NEXT: br i1 [[CMP]], label %[[FOR_BODY]], label %[[FOR_COND_CLEANUP:.*]]
+; CHECK: [[FOR_COND_CLEANUP]]:
+; CHECK-NEXT: [[CALL:%.*]] = call double @sqrt(double noundef [[RMSD_0]])
+; CHECK-NEXT: ret double [[CALL]]
+; CHECK: [[FOR_BODY]]:
+; CHECK-NEXT: [[SUB:%.*]] = fsub double [[DISTMAT1_]], [[DISTMAT2_]]
+; CHECK-NEXT: [[ADD:%.*]] = fadd double [[DISTMAT1_]], [[DISTMAT2_]]
+; CHECK-NEXT: [[FMACALL]] = call double @llvm.fmuladd.f64(double [[SUB]], double [[ADD]], double [[RMSD_0]])
+; CHECK-NEXT: br label %[[FOR_COND]]
+;
+entry:
+ br label %for.cond
+
+for.cond: ; preds = %for.body, %entry
+ %RMSD.0 = phi double [ 0.000000e+00, %entry ], [ %fmacall, %for.body ]
+ %cmp = phi i1 [ true, %entry ], [ false, %for.body ]
+ br i1 %cmp, label %for.body, label %for.cond.cleanup
+
+for.cond.cleanup: ; preds = %for.cond
+ %call = call double @sqrt(double noundef %RMSD.0)
+ ret double %call
+
+for.body: ; preds = %for.cond
+ %sub = fsub double %distmat1_, %distmat2_
+ %add = fadd double %distmat1_, %distmat2_
+ %fmacall = call double @llvm.fmuladd.f64(double %sub, double %add, double %RMSD.0)
+ br label %for.cond
+}
+
+define double @negInitialCompareDistmats(double noundef %distmat1_, double noundef %distmat2_) {
+; CHECK-LABEL: define double @negInitialCompareDistmats(
+; CHECK-SAME: double noundef [[DISTMAT1_:%.*]], double noundef [[DISTMAT2_:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: br label %[[FOR_COND:.*]]
+; CHECK: [[FOR_COND]]:
+; CHECK-NEXT: [[RMSD_0:%.*]] = phi double [ -1.000000e+00, %[[ENTRY]] ], [ [[FMACALL:%.*]], %[[FOR_BODY:.*]] ]
+; CHECK-NEXT: [[CMP:%.*]] = phi i1 [ true, %[[ENTRY]] ], [ false, %[[FOR_BODY]] ]
+; CHECK-NEXT: br i1 [[CMP]], label %[[FOR_BODY]], label %[[FOR_COND_CLEANUP:.*]]
+; CHECK: [[FOR_COND_CLEANUP]]:
+; CHECK-NEXT: [[CALL:%.*]] = call double @sqrt(double noundef [[RMSD_0]])
+; CHECK-NEXT: ret double [[CALL]]
+; CHECK: [[FOR_BODY]]:
+; CHECK-NEXT: [[SUB:%.*]] = fsub double [[DISTMAT1_]], [[DISTMAT2_]]
+; CHECK-NEXT: [[FMACALL]] = call double @llvm.fmuladd.f64(double [[SUB]], double [[SUB]], double [[RMSD_0]])
+; CHECK-NEXT: br label %[[FOR_COND]]
+;
+entry:
+ br label %for.cond
+
+for.cond: ; preds = %for.body, %entry
+ %RMSD.0 = phi double [ -1.000000e+00, %entry ], [ %fmacall, %for.body ]
+ %cmp = phi i1 [ true, %entry ], [ false, %for.body ]
+ br i1 %cmp, label %for.body, label %for.cond.cleanup
+
+for.cond.cleanup: ; preds = %for.cond
+ %call = call double @sqrt(double noundef %RMSD.0)
+ ret double %call
+
+for.body: ; preds = %for.cond
+ %sub = fsub double %distmat1_, %distmat2_
+ %fmacall = call double @llvm.fmuladd.f64(double %sub, double %sub, double %RMSD.0)
+ br label %for.cond
+}
+
+define double @notMatchingRecurrenceCompareDistmats(double noundef %distmat1_, double noundef %distmat2_) {
+; CHECK-LABEL: define double @notMatchingRecurrenceCompareDistmats(
+; CHECK-SAME: double noundef [[DISTMAT1_:%.*]], double noundef [[DISTMAT2_:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: br label %[[FOR_COND:.*]]
+; CHECK: [[FOR_COND]]:
+; CHECK-NEXT: [[RMSD_0:%.*]] = phi double [ -1.000000e+00, %[[ENTRY]] ], [ [[FMACALL:%.*]], %[[FOR_BODY:.*]] ]
+; CHECK-NEXT: [[CMP:%.*]] = phi i1 [ true, %[[ENTRY]] ], [ false, %[[FOR_BODY]] ]
+; CHECK-NEXT: br i1 [[CMP]], label %[[FOR_BODY]], label %[[FOR_COND_CLEANUP:.*]]
+; CHECK: [[FOR_COND_CLEANUP]]:
+; CHECK-NEXT: [[CALL:%.*]] = call double @sqrt(double noundef [[RMSD_0]])
+; CHECK-NEXT: ret double [[CALL]]
+; CHECK: [[FOR_BODY]]:
+; CHECK-NEXT: [[SUB:%.*]] = fsub double [[DISTMAT1_]], [[DISTMAT2_]]
+; CHECK-NEXT: [[FMACALL]] = call double @llvm.fmuladd.f64(double [[SUB]], double [[SUB]], double [[SUB]])
+; CHECK-NEXT: br label %[[FOR_COND]]
+;
+entry:
+ br label %for.cond
+
+for.cond: ; preds = %for.body, %entry
+ %RMSD.0 = phi double [ -1.000000e+00, %entry ], [ %fmacall, %for.body ]
+ %cmp = phi i1 [ true, %entry ], [ false, %for.body ]
+ br i1 %cmp, label %for.body, label %for.cond.cleanup
+
+for.cond.cleanup: ; preds = %for.cond
+ %call = call double @sqrt(double noundef %RMSD.0)
+ ret double %call
+
+for.body: ; preds = %for.cond
+ %sub = fsub double %distmat1_, %distmat2_
+ %fmacall = call double @llvm.fmuladd.f64(double %sub, double %sub, double %sub)
+ br label %for.cond
+}
+
+define i1 @test_phi_operand_crash(ptr %arena, i1 %exitcond) {
+; CHECK-LABEL: define i1 @test_phi_operand_crash(
+; CHECK-SAME: ptr [[ARENA:%.*]], i1 [[EXITCOND:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: br label %[[LOOP:.*]]
+; CHECK: [[LOOP]]:
+; CHECK-NEXT: [[DOT026:%.*]] = phi double [ 0.000000e+00, %[[ENTRY]] ], [ 1.000000e+00, %[[LOOP_BACKEDGE:.*]] ]
+; CHECK-NEXT: br i1 true, label %[[LOAD_BLOCK:.*]], label %[[ZERO_BLOCK:.*]]
+; CHECK: [[ZERO_BLOCK]]:
+; CHECK-NEXT: br label %[[LOOP_BACKEDGE]]
+; CHECK: [[LOAD_BLOCK]]:
+; CHECK-NEXT: [[LOADED_VAL:%.*]] = load double, ptr [[ARENA]], align 8
+; CHECK-NEXT: br label %[[LOOP_BACKEDGE]]
+; CHECK: [[LOOP_BACKEDGE]]:
+; CHECK-NEXT: [[DOT0_I22:%.*]] = phi double [ [[LOADED_VAL]], %[[LOAD_BLOCK]] ], [ 0.000000e+00, %[[ZERO_BLOCK]] ]
+; CHECK-NEXT: br i1 [[EXITCOND]], label %[[LOOP]], label %[[EXIT:.*]]
+; CHECK: [[EXIT]]:
+; CHECK-NEXT: [[FMA_RESULT:%.*]] = tail call double @llvm.fmuladd.f64(double 0.000000e+00, double [[DOT0_I22]], double [[DOT026]])
+; CHECK-NEXT: [[CMP:%.*]] = fcmp oge double [[FMA_RESULT]], 0.000000e+00
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+entry:
+ br label %loop
+
+loop:
+ %.026 = phi double [ 0.000000e+00, %entry ], [ 1.000000e+00, %loop_backedge ]
+ br i1 true, label %load_block, label %zero_block
+
+zero_block:
+ br label %loop_backedge
+
+load_block:
+ %loaded_val = load double, ptr %arena, align 8
+ br label %loop_backedge
+
+loop_backedge:
+ %.0.i22 = phi double [ %loaded_val, %load_block ], [ 0.000000e+00, %zero_block ]
+ br i1 %exitcond, label %loop, label %exit
+
+exit:
+ %fma_result = tail call double @llvm.fmuladd.f64(double 0.000000e+00, double %.0.i22, double %.026)
+ %cmp = fcmp oge double %fma_result, 0.000000e+00
+ ret i1 %cmp
+}
+
+declare double @llvm.fmuladd.f64(double, double, double)
+
+declare double @llvm.fma.f64(double, double, double)
+
+declare double @sqrt(double noundef)
More information about the llvm-commits
mailing list