; 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 } define i1 @test_ternary_recurrence_crash(double noundef %distmat1_, double noundef %distmat2_, double %x) { ; CHECK-LABEL: define i1 @test_ternary_recurrence_crash( ; CHECK-SAME: double noundef [[DISTMAT1_:%.*]], double noundef [[DISTMAT2_:%.*]], double [[X:%.*]]) { ; CHECK-NEXT: [[ENTRY:.*]]: ; CHECK-NEXT: [[INIT_VAL:%.*]] = call double @llvm.sqrt.f64(double [[X]]) ; CHECK-NEXT: br label %[[FOR_COND:.*]] ; CHECK: [[FOR_COND]]: ; CHECK-NEXT: [[RMSD_0:%.*]] = phi double [ [[INIT_VAL]], %[[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: [[RES:%.*]] = fcmp oge double [[RMSD_0]], 0.000000e+00 ; CHECK-NEXT: ret i1 [[RES]] ; 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: %init_val = call double @llvm.sqrt.f64(double %x) br label %for.cond for.cond: ; preds = %for.body, %entry %RMSD.0 = phi double [ %init_val, %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 %res = fcmp oge double %RMSD.0, 0.000000e+00 ret i1 %res 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 } declare double @llvm.fmuladd.f64(double, double, double) declare double @llvm.fma.f64(double, double, double) declare double @sqrt(double noundef)