| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6 |
| ; RUN: opt -passes=slp-vectorizer -mtriple=aarch64-none-linux-gnu -mcpu=neoverse-n1 -S %s | FileCheck %s |
| ; |
| declare void @sink_use(i32, i32, i32) |
| |
| ; "bad" ordering: outer.latch after inner.body => LCSSA-phi users first. |
| define double @test(ptr %obj, ptr %arr, i32 %n) { |
| ; CHECK-LABEL: define double @test( |
| ; CHECK-SAME: ptr [[OBJ:%.*]], ptr [[ARR:%.*]], i32 [[N:%.*]]) #[[ATTR0:[0-9]+]] { |
| ; CHECK-NEXT: [[ENTRY:.*]]: |
| ; CHECK-NEXT: [[POS1:%.*]] = getelementptr inbounds i8, ptr [[OBJ]], i64 44 |
| ; CHECK-NEXT: [[POS2:%.*]] = getelementptr inbounds i8, ptr [[OBJ]], i64 48 |
| ; CHECK-NEXT: [[COND_ENTER:%.*]] = icmp sgt i32 [[N]], 0 |
| ; CHECK-NEXT: br i1 [[COND_ENTER]], label %[[OUTER_PREHEADER:.*]], label %[[EXIT:.*]] |
| ; CHECK: [[OUTER_PREHEADER]]: |
| ; CHECK-NEXT: br label %[[OUTER_HEADER:.*]] |
| ; CHECK: [[OUTER_HEADER]]: |
| ; CHECK-NEXT: %"$vphi.1" = phi i32 [ 16, %[[OUTER_PREHEADER]] ], [ [[DOTSINK6_I_LCSSA:%.*]], %[[OUTER_LATCH:.*]] ] |
| ; CHECK-NEXT: %"$vphi.0" = phi i32 [ 4, %[[OUTER_PREHEADER]] ], [ [[DOTSINK_I_LCSSA:%.*]], %[[OUTER_LATCH]] ] |
| ; CHECK-NEXT: [[LOCAL_4_128:%.*]] = phi i32 [ 0, %[[OUTER_PREHEADER]] ], [ [[LCSSA_IV:%.*]], %[[OUTER_LATCH]] ] |
| ; CHECK-NEXT: [[LOCAL_3_127:%.*]] = phi i32 [ 0, %[[OUTER_PREHEADER]] ], [ [[LOCAL_3_16_LCSSA:%.*]], %[[OUTER_LATCH]] ] |
| ; CHECK-NEXT: br label %[[INNER_HEADER:.*]] |
| ; CHECK: [[INNER_HEADER]]: |
| ; CHECK-NEXT: %"$vphi.1418" = phi i32 [ %"$vphi.1", %[[OUTER_HEADER]] ], [ [[DOTSINK6_I:%.*]], %[[INNER_BODY:.*]] ] |
| ; CHECK-NEXT: %"$vphi.0419" = phi i32 [ %"$vphi.0", %[[OUTER_HEADER]] ], [ [[DOTSINK_I:%.*]], %[[INNER_BODY]] ] |
| ; CHECK-NEXT: [[LOCAL_4_128420:%.*]] = phi i32 [ [[LOCAL_4_128]], %[[OUTER_HEADER]] ], [ [[INC:%.*]], %[[INNER_BODY]] ] |
| ; CHECK-NEXT: [[LOCAL_3_127421:%.*]] = phi i32 [ [[LOCAL_3_127]], %[[OUTER_HEADER]] ], [ [[LOCAL_3_16:%.*]], %[[INNER_BODY]] ] |
| ; CHECK-NEXT: [[CHUNK_IV:%.*]] = phi i64 [ 0, %[[OUTER_HEADER]] ], [ [[CHUNK_IV_NEXT:%.*]], %[[INNER_BODY]] ] |
| ; CHECK-NEXT: [[C27:%.*]] = icmp ult i32 %"$vphi.0419", 17 |
| ; CHECK-NEXT: [[C28:%.*]] = icmp ult i32 %"$vphi.1418", 17 |
| ; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[C28]], [[C27]] |
| ; CHECK-NEXT: [[DOTNOT3_I17:%.*]] = icmp eq i32 %"$vphi.0419", 0 |
| ; CHECK-NEXT: [[V29:%.*]] = add i32 %"$vphi.0419", -1 |
| ; CHECK-NEXT: [[TMP10:%.*]] = select i1 [[DOTNOT3_I17]], i32 16, i32 [[V29]] |
| ; CHECK-NEXT: [[C30:%.*]] = icmp ult i32 [[TMP10]], 17 |
| ; CHECK-NEXT: [[WIDE_CHK354:%.*]] = and i1 [[WIDE_CHK]], [[C30]] |
| ; CHECK-NEXT: [[DOTNOT4_I19:%.*]] = icmp eq i32 %"$vphi.1418", 0 |
| ; CHECK-NEXT: [[V31:%.*]] = add i32 %"$vphi.1418", -1 |
| ; CHECK-NEXT: [[TMP11:%.*]] = select i1 [[DOTNOT4_I19]], i32 16, i32 [[V31]] |
| ; CHECK-NEXT: [[C32:%.*]] = icmp ult i32 [[TMP11]], 17 |
| ; CHECK-NEXT: [[TMP8:%.*]] = and i1 [[C32]], [[WIDE_CHK354]] |
| ; CHECK-NEXT: br i1 [[TMP8]], label %[[INNER_BODY]], label %[[DEOPT:.*]] |
| ; CHECK: [[INNER_BODY]]: |
| ; CHECK-NEXT: [[CHUNK_IV_NEXT]] = add nuw nsw i64 [[CHUNK_IV]], 1 |
| ; CHECK-NEXT: [[V34:%.*]] = zext nneg i32 %"$vphi.0419" to i64 |
| ; CHECK-NEXT: [[V35:%.*]] = getelementptr inbounds nuw [4 x i8], ptr [[ARR]], i64 [[V34]] |
| ; CHECK-NEXT: [[V36:%.*]] = load i32, ptr [[V35]], align 4 |
| ; CHECK-NEXT: [[V37:%.*]] = zext nneg i32 %"$vphi.1418" to i64 |
| ; CHECK-NEXT: [[V38:%.*]] = getelementptr inbounds nuw [4 x i8], ptr [[ARR]], i64 [[V37]] |
| ; CHECK-NEXT: [[V39:%.*]] = load i32, ptr [[V38]], align 4 |
| ; CHECK-NEXT: [[V40:%.*]] = sub i32 [[V36]], [[V39]] |
| ; CHECK-NEXT: [[V41:%.*]] = add nsw i32 [[V40]], 2147483647 |
| ; CHECK-NEXT: [[V42:%.*]] = icmp slt i32 [[V40]], 0 |
| ; CHECK-NEXT: [[SPEC_SELECT_I13:%.*]] = select i1 [[V42]], i32 [[V41]], i32 [[V40]] |
| ; CHECK-NEXT: store i32 [[SPEC_SELECT_I13]], ptr [[V38]], align 4 |
| ; CHECK-NEXT: [[V43:%.*]] = sitofp i32 [[SPEC_SELECT_I13]] to double |
| ; CHECK-NEXT: [[V44:%.*]] = fmul nnan double [[V43]], f0x3E00000000200000 |
| ; CHECK-NEXT: [[V45:%.*]] = zext nneg i32 [[TMP10]] to i64 |
| ; CHECK-NEXT: [[V46:%.*]] = getelementptr inbounds nuw [4 x i8], ptr [[ARR]], i64 [[V45]] |
| ; CHECK-NEXT: [[V47:%.*]] = load i32, ptr [[V46]], align 4 |
| ; CHECK-NEXT: [[V48:%.*]] = zext nneg i32 [[TMP11]] to i64 |
| ; CHECK-NEXT: [[V49:%.*]] = getelementptr inbounds nuw [4 x i8], ptr [[ARR]], i64 [[V48]] |
| ; CHECK-NEXT: [[V50:%.*]] = load i32, ptr [[V49]], align 4 |
| ; CHECK-NEXT: [[V51:%.*]] = sub i32 [[V47]], [[V50]] |
| ; CHECK-NEXT: [[V52:%.*]] = add nsw i32 [[V51]], 2147483647 |
| ; CHECK-NEXT: [[V53:%.*]] = icmp slt i32 [[V51]], 0 |
| ; CHECK-NEXT: [[SPEC_SELECT_I:%.*]] = select i1 [[V53]], i32 [[V52]], i32 [[V51]] |
| ; CHECK-NEXT: store i32 [[SPEC_SELECT_I]], ptr [[V49]], align 4 |
| ; CHECK-NEXT: [[DOTNOT3_I:%.*]] = icmp eq i32 [[TMP10]], 0 |
| ; CHECK-NEXT: [[V54:%.*]] = add nsw i32 [[TMP10]], -1 |
| ; CHECK-NEXT: [[DOTSINK_I]] = select i1 [[DOTNOT3_I]], i32 16, i32 [[V54]] |
| ; CHECK-NEXT: store i32 [[DOTSINK_I]], ptr [[POS1]], align 4 |
| ; CHECK-NEXT: [[DOTNOT4_I:%.*]] = icmp eq i32 [[TMP11]], 0 |
| ; CHECK-NEXT: [[V55:%.*]] = add nsw i32 [[TMP11]], -1 |
| ; CHECK-NEXT: [[DOTSINK6_I]] = select i1 [[DOTNOT4_I]], i32 16, i32 [[V55]] |
| ; CHECK-NEXT: store i32 [[DOTSINK6_I]], ptr [[POS2]], align 8 |
| ; CHECK-NEXT: [[V56:%.*]] = sitofp i32 [[SPEC_SELECT_I]] to double |
| ; CHECK-NEXT: [[V57:%.*]] = fmul nnan double [[V56]], f0x3E00000000200000 |
| ; CHECK-NEXT: [[V58:%.*]] = fmul nnan double [[V44]], [[V44]] |
| ; CHECK-NEXT: [[V59:%.*]] = fmul nnan double [[V57]], [[V57]] |
| ; CHECK-NEXT: [[V60:%.*]] = fadd double [[V58]], [[V59]] |
| ; CHECK-NEXT: [[V61:%.*]] = fcmp ole double [[V60]], 1.000000e+00 |
| ; CHECK-NEXT: [[V62:%.*]] = zext i1 [[V61]] to i32 |
| ; CHECK-NEXT: [[LOCAL_3_16]] = add i32 [[V62]], [[LOCAL_3_127421]] |
| ; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[LOCAL_4_128420]], 1 |
| ; CHECK-NEXT: [[DOTNOT:%.*]] = icmp slt i32 [[INC]], [[N]] |
| ; CHECK-NEXT: [[CHUNK_COND:%.*]] = icmp samesign ult i64 [[CHUNK_IV]], 32 |
| ; CHECK-NEXT: [[V64:%.*]] = and i1 [[DOTNOT]], [[CHUNK_COND]] |
| ; CHECK-NEXT: br i1 [[V64]], label %[[INNER_HEADER]], label %[[OUTER_LATCH]] |
| ; CHECK: [[DEOPT]]: |
| ; CHECK-NEXT: %"$vphi.0419.lcssa" = phi i32 [ %"$vphi.0419", %[[INNER_HEADER]] ] |
| ; CHECK-NEXT: [[LOCAL_4_128420_LCSSA:%.*]] = phi i32 [ [[LOCAL_4_128420]], %[[INNER_HEADER]] ] |
| ; CHECK-NEXT: [[LOCAL_3_127421_LCSSA:%.*]] = phi i32 [ [[LOCAL_3_127421]], %[[INNER_HEADER]] ] |
| ; CHECK-NEXT: call void @sink_use(i32 %"$vphi.0419.lcssa", i32 [[LOCAL_4_128420_LCSSA]], i32 [[LOCAL_3_127421_LCSSA]]) |
| ; CHECK-NEXT: ret double 0.000000e+00 |
| ; CHECK: [[OUTER_LATCH]]: |
| ; CHECK-NEXT: [[DOTSINK_I_LCSSA]] = phi i32 [ [[DOTSINK_I]], %[[INNER_BODY]] ] |
| ; CHECK-NEXT: [[DOTSINK6_I_LCSSA]] = phi i32 [ [[DOTSINK6_I]], %[[INNER_BODY]] ] |
| ; CHECK-NEXT: [[LOCAL_3_16_LCSSA]] = phi i32 [ [[LOCAL_3_16]], %[[INNER_BODY]] ] |
| ; CHECK-NEXT: [[LCSSA_IV]] = phi i32 [ [[INC]], %[[INNER_BODY]] ] |
| ; CHECK-NEXT: [[DOTNOT_LCSSA:%.*]] = phi i1 [ [[DOTNOT]], %[[INNER_BODY]] ] |
| ; CHECK-NEXT: br i1 [[DOTNOT_LCSSA]], label %[[OUTER_HEADER]], label %[[EXIT_LOOP:.*]] |
| ; CHECK: [[EXIT_LOOP]]: |
| ; CHECK-NEXT: [[FINAL:%.*]] = phi i32 [ [[LOCAL_3_16_LCSSA]], %[[OUTER_LATCH]] ] |
| ; CHECK-NEXT: [[RESULT:%.*]] = sitofp i32 [[FINAL]] to double |
| ; CHECK-NEXT: br label %[[EXIT]] |
| ; CHECK: [[EXIT]]: |
| ; CHECK-NEXT: [[RET_VAL:%.*]] = phi double [ 0.000000e+00, %[[ENTRY]] ], [ [[RESULT]], %[[EXIT_LOOP]] ] |
| ; CHECK-NEXT: [[NFP:%.*]] = sitofp i32 [[N]] to double |
| ; CHECK-NEXT: [[DIV:%.*]] = fdiv double [[RET_VAL]], [[NFP]] |
| ; CHECK-NEXT: [[MUL:%.*]] = fmul double [[DIV]], 4.000000e+00 |
| ; CHECK-NEXT: ret double [[MUL]] |
| ; |
| entry: |
| %pos1 = getelementptr inbounds i8, ptr %obj, i64 44 |
| %pos2 = getelementptr inbounds i8, ptr %obj, i64 48 |
| %cond.enter = icmp sgt i32 %n, 0 |
| br i1 %cond.enter, label %outer.preheader, label %exit |
| |
| outer.preheader: |
| br label %outer.header |
| |
| outer.header: |
| %"$vphi.1" = phi i32 [ 16, %outer.preheader ], [ %.sink6.i.lcssa, %outer.latch ] |
| %"$vphi.0" = phi i32 [ 4, %outer.preheader ], [ %.sink.i.lcssa, %outer.latch ] |
| %local_4_128 = phi i32 [ 0, %outer.preheader ], [ %lcssa.iv, %outer.latch ] |
| %local_3_127 = phi i32 [ 0, %outer.preheader ], [ %local_3_16.lcssa, %outer.latch ] |
| br label %inner.header |
| |
| inner.header: |
| %"$vphi.1418" = phi i32 [ %"$vphi.1", %outer.header ], [ %.sink6.i, %inner.body ] |
| %"$vphi.0419" = phi i32 [ %"$vphi.0", %outer.header ], [ %.sink.i, %inner.body ] |
| %local_4_128420 = phi i32 [ %local_4_128, %outer.header ], [ %inc, %inner.body ] |
| %local_3_127421 = phi i32 [ %local_3_127, %outer.header ], [ %local_3_16, %inner.body ] |
| %chunk.iv = phi i64 [ 0, %outer.header ], [ %chunk.iv.next, %inner.body ] |
| %c27 = icmp ult i32 %"$vphi.0419", 17 |
| %c28 = icmp ult i32 %"$vphi.1418", 17 |
| %wide.chk = and i1 %c28, %c27 |
| %.not3.i17 = icmp eq i32 %"$vphi.0419", 0 |
| %v29 = add i32 %"$vphi.0419", -1 |
| %.sink.i18 = select i1 %.not3.i17, i32 16, i32 %v29 |
| %c30 = icmp ult i32 %.sink.i18, 17 |
| %wide.chk354 = and i1 %wide.chk, %c30 |
| %.not4.i19 = icmp eq i32 %"$vphi.1418", 0 |
| %v31 = add i32 %"$vphi.1418", -1 |
| %.sink6.i20 = select i1 %.not4.i19, i32 16, i32 %v31 |
| %c32 = icmp ult i32 %.sink6.i20, 17 |
| %wide.chk355 = and i1 %c32, %wide.chk354 |
| br i1 %wide.chk355, label %inner.body, label %deopt |
| |
| inner.body: |
| %chunk.iv.next = add nuw nsw i64 %chunk.iv, 1 |
| %v34 = zext nneg i32 %"$vphi.0419" to i64 |
| %v35 = getelementptr inbounds nuw [4 x i8], ptr %arr, i64 %v34 |
| %v36 = load i32, ptr %v35, align 4 |
| %v37 = zext nneg i32 %"$vphi.1418" to i64 |
| %v38 = getelementptr inbounds nuw [4 x i8], ptr %arr, i64 %v37 |
| %v39 = load i32, ptr %v38, align 4 |
| %v40 = sub i32 %v36, %v39 |
| %v41 = add nsw i32 %v40, 2147483647 |
| %v42 = icmp slt i32 %v40, 0 |
| %spec.select.i13 = select i1 %v42, i32 %v41, i32 %v40 |
| store i32 %spec.select.i13, ptr %v38, align 4 |
| %v43 = sitofp i32 %spec.select.i13 to double |
| %v44 = fmul nnan double %v43, 0x3E00000000200000 |
| %v45 = zext nneg i32 %.sink.i18 to i64 |
| %v46 = getelementptr inbounds nuw [4 x i8], ptr %arr, i64 %v45 |
| %v47 = load i32, ptr %v46, align 4 |
| %v48 = zext nneg i32 %.sink6.i20 to i64 |
| %v49 = getelementptr inbounds nuw [4 x i8], ptr %arr, i64 %v48 |
| %v50 = load i32, ptr %v49, align 4 |
| %v51 = sub i32 %v47, %v50 |
| %v52 = add nsw i32 %v51, 2147483647 |
| %v53 = icmp slt i32 %v51, 0 |
| %spec.select.i = select i1 %v53, i32 %v52, i32 %v51 |
| store i32 %spec.select.i, ptr %v49, align 4 |
| %.not3.i = icmp eq i32 %.sink.i18, 0 |
| %v54 = add nsw i32 %.sink.i18, -1 |
| %.sink.i = select i1 %.not3.i, i32 16, i32 %v54 |
| store i32 %.sink.i, ptr %pos1, align 4 |
| %.not4.i = icmp eq i32 %.sink6.i20, 0 |
| %v55 = add nsw i32 %.sink6.i20, -1 |
| %.sink6.i = select i1 %.not4.i, i32 16, i32 %v55 |
| store i32 %.sink6.i, ptr %pos2, align 8 |
| %v56 = sitofp i32 %spec.select.i to double |
| %v57 = fmul nnan double %v56, 0x3E00000000200000 |
| %v58 = fmul nnan double %v44, %v44 |
| %v59 = fmul nnan double %v57, %v57 |
| %v60 = fadd double %v58, %v59 |
| %v61 = fcmp ole double %v60, 1.000000e+00 |
| %v62 = zext i1 %v61 to i32 |
| %local_3_16 = add i32 %v62, %local_3_127421 |
| %inc = add nuw nsw i32 %local_4_128420, 1 |
| %.not = icmp slt i32 %inc, %n |
| %chunk.cond = icmp samesign ult i64 %chunk.iv, 32 |
| %v64 = and i1 %.not, %chunk.cond |
| br i1 %v64, label %inner.header, label %outer.latch |
| |
| deopt: |
| %"$vphi.0419.lcssa" = phi i32 [ %"$vphi.0419", %inner.header ] |
| %local_4_128420.lcssa = phi i32 [ %local_4_128420, %inner.header ] |
| %local_3_127421.lcssa = phi i32 [ %local_3_127421, %inner.header ] |
| call void @sink_use(i32 %"$vphi.0419.lcssa", i32 %local_4_128420.lcssa, i32 %local_3_127421.lcssa) |
| ret double 0.000000e+00 |
| |
| outer.latch: |
| %.sink.i.lcssa = phi i32 [ %.sink.i, %inner.body ] |
| %.sink6.i.lcssa = phi i32 [ %.sink6.i, %inner.body ] |
| %local_3_16.lcssa = phi i32 [ %local_3_16, %inner.body ] |
| %lcssa.iv = phi i32 [ %inc, %inner.body ] |
| %.not.lcssa = phi i1 [ %.not, %inner.body ] |
| br i1 %.not.lcssa, label %outer.header, label %exit.loop |
| |
| exit.loop: |
| %final = phi i32 [ %local_3_16.lcssa, %outer.latch ] |
| %result = sitofp i32 %final to double |
| br label %exit |
| |
| exit: |
| %ret.val = phi double [ 0.000000e+00, %entry ], [ %result, %exit.loop ] |
| %nfp = sitofp i32 %n to double |
| %div = fdiv double %ret.val, %nfp |
| %mul = fmul double %div, 4.000000e+00 |
| ret double %mul |
| } |
| |
| define double @test_inloop_first(ptr %obj, ptr %arr, i32 %n) { |
| ; CHECK-LABEL: define double @test_inloop_first( |
| ; CHECK-SAME: ptr [[OBJ:%.*]], ptr [[ARR:%.*]], i32 [[N:%.*]]) #[[ATTR0]] { |
| ; CHECK-NEXT: [[ENTRY:.*]]: |
| ; CHECK-NEXT: [[POS1:%.*]] = getelementptr inbounds i8, ptr [[OBJ]], i64 44 |
| ; CHECK-NEXT: [[POS2:%.*]] = getelementptr inbounds i8, ptr [[OBJ]], i64 48 |
| ; CHECK-NEXT: [[COND_ENTER:%.*]] = icmp sgt i32 [[N]], 0 |
| ; CHECK-NEXT: br i1 [[COND_ENTER]], label %[[OUTER_PREHEADER:.*]], label %[[EXIT:.*]] |
| ; CHECK: [[OUTER_PREHEADER]]: |
| ; CHECK-NEXT: br label %[[OUTER_HEADER:.*]] |
| ; CHECK: [[OUTER_HEADER]]: |
| ; CHECK-NEXT: %"$vphi.1" = phi i32 [ 16, %[[OUTER_PREHEADER]] ], [ [[DOTSINK6_I_LCSSA:%.*]], %[[OUTER_LATCH:.*]] ] |
| ; CHECK-NEXT: %"$vphi.0" = phi i32 [ 4, %[[OUTER_PREHEADER]] ], [ [[DOTSINK_I_LCSSA:%.*]], %[[OUTER_LATCH]] ] |
| ; CHECK-NEXT: [[LOCAL_4_128:%.*]] = phi i32 [ 0, %[[OUTER_PREHEADER]] ], [ [[LCSSA_IV:%.*]], %[[OUTER_LATCH]] ] |
| ; CHECK-NEXT: [[LOCAL_3_127:%.*]] = phi i32 [ 0, %[[OUTER_PREHEADER]] ], [ [[LOCAL_3_16_LCSSA:%.*]], %[[OUTER_LATCH]] ] |
| ; CHECK-NEXT: br label %[[INNER_HEADER:.*]] |
| ; CHECK: [[INNER_HEADER]]: |
| ; CHECK-NEXT: %"$vphi.1418" = phi i32 [ %"$vphi.1", %[[OUTER_HEADER]] ], [ [[DOTSINK6_I:%.*]], %[[INNER_BODY:.*]] ] |
| ; CHECK-NEXT: %"$vphi.0419" = phi i32 [ %"$vphi.0", %[[OUTER_HEADER]] ], [ [[DOTSINK_I:%.*]], %[[INNER_BODY]] ] |
| ; CHECK-NEXT: [[LOCAL_4_128420:%.*]] = phi i32 [ [[LOCAL_4_128]], %[[OUTER_HEADER]] ], [ [[INC:%.*]], %[[INNER_BODY]] ] |
| ; CHECK-NEXT: [[LOCAL_3_127421:%.*]] = phi i32 [ [[LOCAL_3_127]], %[[OUTER_HEADER]] ], [ [[LOCAL_3_16:%.*]], %[[INNER_BODY]] ] |
| ; CHECK-NEXT: [[CHUNK_IV:%.*]] = phi i64 [ 0, %[[OUTER_HEADER]] ], [ [[CHUNK_IV_NEXT:%.*]], %[[INNER_BODY]] ] |
| ; CHECK-NEXT: [[C27:%.*]] = icmp ult i32 %"$vphi.0419", 17 |
| ; CHECK-NEXT: [[C28:%.*]] = icmp ult i32 %"$vphi.1418", 17 |
| ; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[C28]], [[C27]] |
| ; CHECK-NEXT: [[DOTNOT3_I17:%.*]] = icmp eq i32 %"$vphi.0419", 0 |
| ; CHECK-NEXT: [[V29:%.*]] = add i32 %"$vphi.0419", -1 |
| ; CHECK-NEXT: [[TMP11:%.*]] = select i1 [[DOTNOT3_I17]], i32 16, i32 [[V29]] |
| ; CHECK-NEXT: [[C30:%.*]] = icmp ult i32 [[TMP11]], 17 |
| ; CHECK-NEXT: [[WIDE_CHK354:%.*]] = and i1 [[WIDE_CHK]], [[C30]] |
| ; CHECK-NEXT: [[DOTNOT4_I19:%.*]] = icmp eq i32 %"$vphi.1418", 0 |
| ; CHECK-NEXT: [[V31:%.*]] = add i32 %"$vphi.1418", -1 |
| ; CHECK-NEXT: [[TMP12:%.*]] = select i1 [[DOTNOT4_I19]], i32 16, i32 [[V31]] |
| ; CHECK-NEXT: [[C32:%.*]] = icmp ult i32 [[TMP12]], 17 |
| ; CHECK-NEXT: [[TMP8:%.*]] = and i1 [[C32]], [[WIDE_CHK354]] |
| ; CHECK-NEXT: br i1 [[TMP8]], label %[[INNER_BODY]], label %[[DEOPT:.*]] |
| ; CHECK: [[OUTER_LATCH]]: |
| ; CHECK-NEXT: [[DOTSINK_I_LCSSA]] = phi i32 [ [[DOTSINK_I]], %[[INNER_BODY]] ] |
| ; CHECK-NEXT: [[DOTSINK6_I_LCSSA]] = phi i32 [ [[DOTSINK6_I]], %[[INNER_BODY]] ] |
| ; CHECK-NEXT: [[LOCAL_3_16_LCSSA]] = phi i32 [ [[LOCAL_3_16]], %[[INNER_BODY]] ] |
| ; CHECK-NEXT: [[LCSSA_IV]] = phi i32 [ [[INC]], %[[INNER_BODY]] ] |
| ; CHECK-NEXT: [[DOTNOT_LCSSA:%.*]] = phi i1 [ [[DOTNOT:%.*]], %[[INNER_BODY]] ] |
| ; CHECK-NEXT: br i1 [[DOTNOT_LCSSA]], label %[[OUTER_HEADER]], label %[[EXIT_LOOP:.*]] |
| ; CHECK: [[EXIT_LOOP]]: |
| ; CHECK-NEXT: [[FINAL:%.*]] = phi i32 [ [[LOCAL_3_16_LCSSA]], %[[OUTER_LATCH]] ] |
| ; CHECK-NEXT: [[RESULT:%.*]] = sitofp i32 [[FINAL]] to double |
| ; CHECK-NEXT: br label %[[EXIT]] |
| ; CHECK: [[INNER_BODY]]: |
| ; CHECK-NEXT: [[CHUNK_IV_NEXT]] = add nuw nsw i64 [[CHUNK_IV]], 1 |
| ; CHECK-NEXT: [[V34:%.*]] = zext nneg i32 %"$vphi.0419" to i64 |
| ; CHECK-NEXT: [[V35:%.*]] = getelementptr inbounds nuw [4 x i8], ptr [[ARR]], i64 [[V34]] |
| ; CHECK-NEXT: [[V36:%.*]] = load i32, ptr [[V35]], align 4 |
| ; CHECK-NEXT: [[V37:%.*]] = zext nneg i32 %"$vphi.1418" to i64 |
| ; CHECK-NEXT: [[V38:%.*]] = getelementptr inbounds nuw [4 x i8], ptr [[ARR]], i64 [[V37]] |
| ; CHECK-NEXT: [[V39:%.*]] = load i32, ptr [[V38]], align 4 |
| ; CHECK-NEXT: [[V40:%.*]] = sub i32 [[V36]], [[V39]] |
| ; CHECK-NEXT: [[V41:%.*]] = add nsw i32 [[V40]], 2147483647 |
| ; CHECK-NEXT: [[V42:%.*]] = icmp slt i32 [[V40]], 0 |
| ; CHECK-NEXT: [[SPEC_SELECT_I13:%.*]] = select i1 [[V42]], i32 [[V41]], i32 [[V40]] |
| ; CHECK-NEXT: store i32 [[SPEC_SELECT_I13]], ptr [[V38]], align 4 |
| ; CHECK-NEXT: [[V43:%.*]] = sitofp i32 [[SPEC_SELECT_I13]] to double |
| ; CHECK-NEXT: [[V44:%.*]] = fmul nnan double [[V43]], f0x3E00000000200000 |
| ; CHECK-NEXT: [[V45:%.*]] = zext nneg i32 [[TMP11]] to i64 |
| ; CHECK-NEXT: [[V46:%.*]] = getelementptr inbounds nuw [4 x i8], ptr [[ARR]], i64 [[V45]] |
| ; CHECK-NEXT: [[V47:%.*]] = load i32, ptr [[V46]], align 4 |
| ; CHECK-NEXT: [[V48:%.*]] = zext nneg i32 [[TMP12]] to i64 |
| ; CHECK-NEXT: [[V49:%.*]] = getelementptr inbounds nuw [4 x i8], ptr [[ARR]], i64 [[V48]] |
| ; CHECK-NEXT: [[V50:%.*]] = load i32, ptr [[V49]], align 4 |
| ; CHECK-NEXT: [[V51:%.*]] = sub i32 [[V47]], [[V50]] |
| ; CHECK-NEXT: [[V52:%.*]] = add nsw i32 [[V51]], 2147483647 |
| ; CHECK-NEXT: [[V53:%.*]] = icmp slt i32 [[V51]], 0 |
| ; CHECK-NEXT: [[SPEC_SELECT_I:%.*]] = select i1 [[V53]], i32 [[V52]], i32 [[V51]] |
| ; CHECK-NEXT: store i32 [[SPEC_SELECT_I]], ptr [[V49]], align 4 |
| ; CHECK-NEXT: [[DOTNOT3_I:%.*]] = icmp eq i32 [[TMP11]], 0 |
| ; CHECK-NEXT: [[V54:%.*]] = add nsw i32 [[TMP11]], -1 |
| ; CHECK-NEXT: [[DOTSINK_I]] = select i1 [[DOTNOT3_I]], i32 16, i32 [[V54]] |
| ; CHECK-NEXT: store i32 [[DOTSINK_I]], ptr [[POS1]], align 4 |
| ; CHECK-NEXT: [[DOTNOT4_I:%.*]] = icmp eq i32 [[TMP12]], 0 |
| ; CHECK-NEXT: [[V55:%.*]] = add nsw i32 [[TMP12]], -1 |
| ; CHECK-NEXT: [[DOTSINK6_I]] = select i1 [[DOTNOT4_I]], i32 16, i32 [[V55]] |
| ; CHECK-NEXT: store i32 [[DOTSINK6_I]], ptr [[POS2]], align 8 |
| ; CHECK-NEXT: [[V56:%.*]] = sitofp i32 [[SPEC_SELECT_I]] to double |
| ; CHECK-NEXT: [[V57:%.*]] = fmul nnan double [[V56]], f0x3E00000000200000 |
| ; CHECK-NEXT: [[V58:%.*]] = fmul nnan double [[V44]], [[V44]] |
| ; CHECK-NEXT: [[V59:%.*]] = fmul nnan double [[V57]], [[V57]] |
| ; CHECK-NEXT: [[V60:%.*]] = fadd double [[V58]], [[V59]] |
| ; CHECK-NEXT: [[V61:%.*]] = fcmp ole double [[V60]], 1.000000e+00 |
| ; CHECK-NEXT: [[V62:%.*]] = zext i1 [[V61]] to i32 |
| ; CHECK-NEXT: [[LOCAL_3_16]] = add i32 [[V62]], [[LOCAL_3_127421]] |
| ; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[LOCAL_4_128420]], 1 |
| ; CHECK-NEXT: [[DOTNOT]] = icmp slt i32 [[INC]], [[N]] |
| ; CHECK-NEXT: [[CHUNK_COND:%.*]] = icmp samesign ult i64 [[CHUNK_IV]], 32 |
| ; CHECK-NEXT: [[V64:%.*]] = and i1 [[DOTNOT]], [[CHUNK_COND]] |
| ; CHECK-NEXT: br i1 [[V64]], label %[[INNER_HEADER]], label %[[OUTER_LATCH]] |
| ; CHECK: [[DEOPT]]: |
| ; CHECK-NEXT: %"$vphi.0419.lcssa" = phi i32 [ %"$vphi.0419", %[[INNER_HEADER]] ] |
| ; CHECK-NEXT: [[LOCAL_4_128420_LCSSA:%.*]] = phi i32 [ [[LOCAL_4_128420]], %[[INNER_HEADER]] ] |
| ; CHECK-NEXT: [[LOCAL_3_127421_LCSSA:%.*]] = phi i32 [ [[LOCAL_3_127421]], %[[INNER_HEADER]] ] |
| ; CHECK-NEXT: call void @sink_use(i32 %"$vphi.0419.lcssa", i32 [[LOCAL_4_128420_LCSSA]], i32 [[LOCAL_3_127421_LCSSA]]) |
| ; CHECK-NEXT: ret double 0.000000e+00 |
| ; CHECK: [[EXIT]]: |
| ; CHECK-NEXT: [[RET_VAL:%.*]] = phi double [ 0.000000e+00, %[[ENTRY]] ], [ [[RESULT]], %[[EXIT_LOOP]] ] |
| ; CHECK-NEXT: [[NFP:%.*]] = sitofp i32 [[N]] to double |
| ; CHECK-NEXT: [[DIV:%.*]] = fdiv double [[RET_VAL]], [[NFP]] |
| ; CHECK-NEXT: [[MUL:%.*]] = fmul double [[DIV]], 4.000000e+00 |
| ; CHECK-NEXT: ret double [[MUL]] |
| ; |
| entry: |
| %pos1 = getelementptr inbounds i8, ptr %obj, i64 44 |
| %pos2 = getelementptr inbounds i8, ptr %obj, i64 48 |
| %cond.enter = icmp sgt i32 %n, 0 |
| br i1 %cond.enter, label %outer.preheader, label %exit |
| |
| outer.preheader: |
| br label %outer.header |
| |
| outer.header: |
| %"$vphi.1" = phi i32 [ 16, %outer.preheader ], [ %.sink6.i.lcssa, %outer.latch ] |
| %"$vphi.0" = phi i32 [ 4, %outer.preheader ], [ %.sink.i.lcssa, %outer.latch ] |
| %local_4_128 = phi i32 [ 0, %outer.preheader ], [ %lcssa.iv, %outer.latch ] |
| %local_3_127 = phi i32 [ 0, %outer.preheader ], [ %local_3_16.lcssa, %outer.latch ] |
| br label %inner.header |
| |
| inner.header: |
| %"$vphi.1418" = phi i32 [ %"$vphi.1", %outer.header ], [ %.sink6.i, %inner.body ] |
| %"$vphi.0419" = phi i32 [ %"$vphi.0", %outer.header ], [ %.sink.i, %inner.body ] |
| %local_4_128420 = phi i32 [ %local_4_128, %outer.header ], [ %inc, %inner.body ] |
| %local_3_127421 = phi i32 [ %local_3_127, %outer.header ], [ %local_3_16, %inner.body ] |
| %chunk.iv = phi i64 [ 0, %outer.header ], [ %chunk.iv.next, %inner.body ] |
| %c27 = icmp ult i32 %"$vphi.0419", 17 |
| %c28 = icmp ult i32 %"$vphi.1418", 17 |
| %wide.chk = and i1 %c28, %c27 |
| %.not3.i17 = icmp eq i32 %"$vphi.0419", 0 |
| %v29 = add i32 %"$vphi.0419", -1 |
| %.sink.i18 = select i1 %.not3.i17, i32 16, i32 %v29 |
| %c30 = icmp ult i32 %.sink.i18, 17 |
| %wide.chk354 = and i1 %wide.chk, %c30 |
| %.not4.i19 = icmp eq i32 %"$vphi.1418", 0 |
| %v31 = add i32 %"$vphi.1418", -1 |
| %.sink6.i20 = select i1 %.not4.i19, i32 16, i32 %v31 |
| %c32 = icmp ult i32 %.sink6.i20, 17 |
| %wide.chk355 = and i1 %c32, %wide.chk354 |
| br i1 %wide.chk355, label %inner.body, label %deopt |
| |
| ; outer.latch and exit.loop are placed BEFORE inner.body in this function. |
| ; When the LLVM IR parser reaches %.sink.i.lcssa here, it creates a forward |
| ; reference to %.sink.i (not yet defined). That forward-ref use is prepended |
| ; to %.sink.i's use list. Later, when inner.body is parsed, inner.body uses |
| ; of %.sink.i are prepended on top, so in-loop users appear first in the |
| ; reversed use list. |
| outer.latch: |
| %.sink.i.lcssa = phi i32 [ %.sink.i, %inner.body ] |
| %.sink6.i.lcssa = phi i32 [ %.sink6.i, %inner.body ] |
| %local_3_16.lcssa = phi i32 [ %local_3_16, %inner.body ] |
| %lcssa.iv = phi i32 [ %inc, %inner.body ] |
| %.not.lcssa = phi i1 [ %.not, %inner.body ] |
| br i1 %.not.lcssa, label %outer.header, label %exit.loop |
| |
| exit.loop: |
| %final = phi i32 [ %local_3_16.lcssa, %outer.latch ] |
| %result = sitofp i32 %final to double |
| br label %exit |
| |
| inner.body: |
| %chunk.iv.next = add nuw nsw i64 %chunk.iv, 1 |
| %v34 = zext nneg i32 %"$vphi.0419" to i64 |
| %v35 = getelementptr inbounds nuw [4 x i8], ptr %arr, i64 %v34 |
| %v36 = load i32, ptr %v35, align 4 |
| %v37 = zext nneg i32 %"$vphi.1418" to i64 |
| %v38 = getelementptr inbounds nuw [4 x i8], ptr %arr, i64 %v37 |
| %v39 = load i32, ptr %v38, align 4 |
| %v40 = sub i32 %v36, %v39 |
| %v41 = add nsw i32 %v40, 2147483647 |
| %v42 = icmp slt i32 %v40, 0 |
| %spec.select.i13 = select i1 %v42, i32 %v41, i32 %v40 |
| store i32 %spec.select.i13, ptr %v38, align 4 |
| %v43 = sitofp i32 %spec.select.i13 to double |
| %v44 = fmul nnan double %v43, 0x3E00000000200000 |
| %v45 = zext nneg i32 %.sink.i18 to i64 |
| %v46 = getelementptr inbounds nuw [4 x i8], ptr %arr, i64 %v45 |
| %v47 = load i32, ptr %v46, align 4 |
| %v48 = zext nneg i32 %.sink6.i20 to i64 |
| %v49 = getelementptr inbounds nuw [4 x i8], ptr %arr, i64 %v48 |
| %v50 = load i32, ptr %v49, align 4 |
| %v51 = sub i32 %v47, %v50 |
| %v52 = add nsw i32 %v51, 2147483647 |
| %v53 = icmp slt i32 %v51, 0 |
| %spec.select.i = select i1 %v53, i32 %v52, i32 %v51 |
| store i32 %spec.select.i, ptr %v49, align 4 |
| %.not3.i = icmp eq i32 %.sink.i18, 0 |
| %v54 = add nsw i32 %.sink.i18, -1 |
| %.sink.i = select i1 %.not3.i, i32 16, i32 %v54 |
| store i32 %.sink.i, ptr %pos1, align 4 |
| %.not4.i = icmp eq i32 %.sink6.i20, 0 |
| %v55 = add nsw i32 %.sink6.i20, -1 |
| %.sink6.i = select i1 %.not4.i, i32 16, i32 %v55 |
| store i32 %.sink6.i, ptr %pos2, align 8 |
| %v56 = sitofp i32 %spec.select.i to double |
| %v57 = fmul nnan double %v56, 0x3E00000000200000 |
| %v58 = fmul nnan double %v44, %v44 |
| %v59 = fmul nnan double %v57, %v57 |
| %v60 = fadd double %v58, %v59 |
| %v61 = fcmp ole double %v60, 1.000000e+00 |
| %v62 = zext i1 %v61 to i32 |
| %local_3_16 = add i32 %v62, %local_3_127421 |
| %inc = add nuw nsw i32 %local_4_128420, 1 |
| %.not = icmp slt i32 %inc, %n |
| %chunk.cond = icmp samesign ult i64 %chunk.iv, 32 |
| %v64 = and i1 %.not, %chunk.cond |
| br i1 %v64, label %inner.header, label %outer.latch |
| |
| deopt: |
| %"$vphi.0419.lcssa" = phi i32 [ %"$vphi.0419", %inner.header ] |
| %local_4_128420.lcssa = phi i32 [ %local_4_128420, %inner.header ] |
| %local_3_127421.lcssa = phi i32 [ %local_3_127421, %inner.header ] |
| call void @sink_use(i32 %"$vphi.0419.lcssa", i32 %local_4_128420.lcssa, i32 %local_3_127421.lcssa) |
| ret double 0.000000e+00 |
| |
| exit: |
| %ret.val = phi double [ 0.000000e+00, %entry ], [ %result, %exit.loop ] |
| %nfp = sitofp i32 %n to double |
| %div = fdiv double %ret.val, %nfp |
| %mul = fmul double %div, 4.000000e+00 |
| ret double %mul |
| } |