blob: 9b8520c1220665f4dfc18dd44d4b760c12938003 [file] [edit]
; 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
}