| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals none --filter-out-after "scalar.ph\:" --version 5 | |
| ; RUN: opt -p loop-vectorize -S %s | FileCheck --check-prefixes=COMMON,DEFAULT %s | |
| ; RUN: opt -p loop-vectorize -tail-folding-policy=prefer-fold-tail -S %s | FileCheck --check-prefixes=COMMON,PRED %s | |
| target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128" | |
| target triple = "arm64-apple-macosx14.0.0" | |
| define void @invar_cond_gep_store(ptr %dst, i32 %0) { | |
| ; COMMON-LABEL: define void @invar_cond_gep_store( | |
| ; COMMON-SAME: ptr [[DST:%.*]], i32 [[TMP0:%.*]]) { | |
| ; COMMON-NEXT: [[ENTRY:.*]]: | |
| ; COMMON-NEXT: br label %[[LOOP_HEADER:.*]] | |
| ; COMMON: [[LOOP_HEADER]]: | |
| ; COMMON-NEXT: [[IV:%.*]] = phi i64 [ 1, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ] | |
| ; COMMON-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1 | |
| ; COMMON-NEXT: [[CMP9:%.*]] = icmp eq i32 [[TMP0]], 0 | |
| ; COMMON-NEXT: br i1 [[CMP9]], label %[[THEN:.*]], label %[[LOOP_LATCH]] | |
| ; COMMON: [[THEN]]: | |
| ; COMMON-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[DST]], i64 [[IV_NEXT]] | |
| ; COMMON-NEXT: store i32 1, ptr [[GEP]], align 4 | |
| ; COMMON-NEXT: br label %[[LOOP_LATCH]] | |
| ; COMMON: [[LOOP_LATCH]]: | |
| ; COMMON-NEXT: [[EC:%.*]] = icmp eq i64 [[IV]], 100 | |
| ; COMMON-NEXT: br i1 [[EC]], label %[[EXIT:.*]], label %[[LOOP_HEADER]] | |
| ; COMMON: [[EXIT]]: | |
| ; COMMON-NEXT: ret void | |
| ; | |
| entry: | |
| br label %loop.header | |
| loop.header: | |
| %iv = phi i64 [ 1, %entry ], [ %iv.next, %loop.latch ] | |
| %iv.next = add i64 %iv, 1 | |
| %cmp9 = icmp eq i32 %0, 0 | |
| br i1 %cmp9, label %then, label %loop.latch | |
| then: | |
| %gep = getelementptr i32, ptr %dst, i64 %iv.next | |
| store i32 1, ptr %gep, align 4 | |
| br label %loop.latch | |
| loop.latch: | |
| %ec = icmp eq i64 %iv, 100 | |
| br i1 %ec, label %exit, label %loop.header | |
| exit: | |
| ret void | |
| } | |
| define void @loop_dependent_cond(ptr %src, ptr noalias %dst, i64 %N) { | |
| ; DEFAULT-LABEL: define void @loop_dependent_cond( | |
| ; DEFAULT-SAME: ptr [[SRC:%.*]], ptr noalias [[DST:%.*]], i64 [[N:%.*]]) { | |
| ; DEFAULT-NEXT: [[ENTRY:.*:]] | |
| ; DEFAULT-NEXT: [[TMP0:%.*]] = add i64 [[N]], 1 | |
| ; DEFAULT-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[TMP0]], 4 | |
| ; DEFAULT-NEXT: br i1 [[MIN_ITERS_CHECK]], label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]] | |
| ; DEFAULT: [[VECTOR_PH]]: | |
| ; DEFAULT-NEXT: [[N_MOD_VF:%.*]] = and i64 [[TMP0]], 3 | |
| ; DEFAULT-NEXT: [[N_VEC:%.*]] = sub i64 [[TMP0]], [[N_MOD_VF]] | |
| ; DEFAULT-NEXT: br label %[[VECTOR_BODY:.*]] | |
| ; DEFAULT: [[VECTOR_BODY]]: | |
| ; DEFAULT-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[PRED_STORE_CONTINUE7:.*]] ] | |
| ; DEFAULT-NEXT: [[TMP3:%.*]] = getelementptr double, ptr [[SRC]], i64 [[INDEX]] | |
| ; DEFAULT-NEXT: [[TMP6:%.*]] = getelementptr double, ptr [[TMP3]], i64 2 | |
| ; DEFAULT-NEXT: [[WIDE_LOAD:%.*]] = load <2 x double>, ptr [[TMP3]], align 8 | |
| ; DEFAULT-NEXT: [[WIDE_LOAD1:%.*]] = load <2 x double>, ptr [[TMP6]], align 8 | |
| ; DEFAULT-NEXT: [[TMP7:%.*]] = call <2 x double> @llvm.fabs.v2f64(<2 x double> [[WIDE_LOAD]]) | |
| ; DEFAULT-NEXT: [[TMP8:%.*]] = call <2 x double> @llvm.fabs.v2f64(<2 x double> [[WIDE_LOAD1]]) | |
| ; DEFAULT-NEXT: [[TMP9:%.*]] = fcmp ogt <2 x double> [[TMP7]], splat (double 1.000000e+00) | |
| ; DEFAULT-NEXT: [[TMP10:%.*]] = fcmp ogt <2 x double> [[TMP8]], splat (double 1.000000e+00) | |
| ; DEFAULT-NEXT: [[TMP11:%.*]] = extractelement <2 x i1> [[TMP9]], i64 0 | |
| ; DEFAULT-NEXT: br i1 [[TMP11]], label %[[PRED_STORE_IF:.*]], label %[[PRED_STORE_CONTINUE:.*]] | |
| ; DEFAULT: [[PRED_STORE_IF]]: | |
| ; DEFAULT-NEXT: store i32 0, ptr [[DST]], align 4 | |
| ; DEFAULT-NEXT: br label %[[PRED_STORE_CONTINUE]] | |
| ; DEFAULT: [[PRED_STORE_CONTINUE]]: | |
| ; DEFAULT-NEXT: [[TMP12:%.*]] = extractelement <2 x i1> [[TMP9]], i64 1 | |
| ; DEFAULT-NEXT: br i1 [[TMP12]], label %[[PRED_STORE_IF2:.*]], label %[[PRED_STORE_CONTINUE3:.*]] | |
| ; DEFAULT: [[PRED_STORE_IF2]]: | |
| ; DEFAULT-NEXT: store i32 0, ptr [[DST]], align 4 | |
| ; DEFAULT-NEXT: br label %[[PRED_STORE_CONTINUE3]] | |
| ; DEFAULT: [[PRED_STORE_CONTINUE3]]: | |
| ; DEFAULT-NEXT: [[TMP13:%.*]] = extractelement <2 x i1> [[TMP10]], i64 0 | |
| ; DEFAULT-NEXT: br i1 [[TMP13]], label %[[PRED_STORE_IF4:.*]], label %[[PRED_STORE_CONTINUE5:.*]] | |
| ; DEFAULT: [[PRED_STORE_IF4]]: | |
| ; DEFAULT-NEXT: store i32 0, ptr [[DST]], align 4 | |
| ; DEFAULT-NEXT: br label %[[PRED_STORE_CONTINUE5]] | |
| ; DEFAULT: [[PRED_STORE_CONTINUE5]]: | |
| ; DEFAULT-NEXT: [[TMP14:%.*]] = extractelement <2 x i1> [[TMP10]], i64 1 | |
| ; DEFAULT-NEXT: br i1 [[TMP14]], label %[[PRED_STORE_IF6:.*]], label %[[PRED_STORE_CONTINUE7]] | |
| ; DEFAULT: [[PRED_STORE_IF6]]: | |
| ; DEFAULT-NEXT: store i32 0, ptr [[DST]], align 4 | |
| ; DEFAULT-NEXT: br label %[[PRED_STORE_CONTINUE7]] | |
| ; DEFAULT: [[PRED_STORE_CONTINUE7]]: | |
| ; DEFAULT-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4 | |
| ; DEFAULT-NEXT: [[TMP15:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]] | |
| ; DEFAULT-NEXT: br i1 [[TMP15]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]] | |
| ; DEFAULT: [[MIDDLE_BLOCK]]: | |
| ; DEFAULT-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[TMP0]], [[N_VEC]] | |
| ; DEFAULT-NEXT: br i1 [[CMP_N]], [[EXIT:label %.*]], label %[[SCALAR_PH]] | |
| ; DEFAULT: [[SCALAR_PH]]: | |
| ; | |
| ; PRED-LABEL: define void @loop_dependent_cond( | |
| ; PRED-SAME: ptr [[SRC:%.*]], ptr noalias [[DST:%.*]], i64 [[N:%.*]]) { | |
| ; PRED-NEXT: [[ENTRY:.*]]: | |
| ; PRED-NEXT: br label %[[LOOP_HEADER:.*]] | |
| ; PRED: [[LOOP_HEADER]]: | |
| ; PRED-NEXT: [[IV175:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT176:%.*]], %[[LOOP_LATCH:.*]] ] | |
| ; PRED-NEXT: [[ARRAYIDX114:%.*]] = getelementptr double, ptr [[SRC]], i64 [[IV175]] | |
| ; PRED-NEXT: [[TMP0:%.*]] = load double, ptr [[ARRAYIDX114]], align 8 | |
| ; PRED-NEXT: [[TMP1:%.*]] = tail call double @llvm.fabs.f64(double [[TMP0]]) | |
| ; PRED-NEXT: [[CMP115:%.*]] = fcmp ogt double [[TMP1]], 1.000000e+00 | |
| ; PRED-NEXT: br i1 [[CMP115]], label %[[THEN:.*]], label %[[LOOP_LATCH]] | |
| ; PRED: [[THEN]]: | |
| ; PRED-NEXT: store i32 0, ptr [[DST]], align 4 | |
| ; PRED-NEXT: br label %[[LOOP_LATCH]] | |
| ; PRED: [[LOOP_LATCH]]: | |
| ; PRED-NEXT: [[IV_NEXT176]] = add i64 [[IV175]], 1 | |
| ; PRED-NEXT: [[EXITCOND180_NOT:%.*]] = icmp eq i64 [[IV175]], [[N]] | |
| ; PRED-NEXT: br i1 [[EXITCOND180_NOT]], label %[[EXIT:.*]], label %[[LOOP_HEADER]] | |
| ; PRED: [[EXIT]]: | |
| ; PRED-NEXT: ret void | |
| ; | |
| entry: | |
| br label %loop.header | |
| loop.header: | |
| %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ] | |
| %gep = getelementptr double, ptr %src, i64 %iv | |
| %l = load double, ptr %gep, align 8 | |
| %abs = tail call double @llvm.fabs.f64(double %l) | |
| %cmp = fcmp ogt double %abs, 1.000000e+00 | |
| br i1 %cmp, label %then, label %loop.latch | |
| then: | |
| store i32 0, ptr %dst, align 4 | |
| br label %loop.latch | |
| loop.latch: | |
| %iv.next = add i64 %iv, 1 | |
| %ec = icmp eq i64 %iv, %N | |
| br i1 %ec, label %exit, label %loop.header | |
| exit: | |
| ret void | |
| } | |
| define void @invar_cond_chain_1(ptr %I, ptr noalias %src, i1 %c) { | |
| ; COMMON-LABEL: define void @invar_cond_chain_1( | |
| ; COMMON-SAME: ptr [[I:%.*]], ptr noalias [[SRC:%.*]], i1 [[C:%.*]]) { | |
| ; COMMON-NEXT: [[ENTRY:.*]]: | |
| ; COMMON-NEXT: br label %[[LOOP_HEADER:.*]] | |
| ; COMMON: [[LOOP_HEADER]]: | |
| ; COMMON-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[SRC]], %[[ENTRY]] ], [ [[PTR_IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ] | |
| ; COMMON-NEXT: [[L:%.*]] = load i32, ptr [[PTR_IV]], align 4 | |
| ; COMMON-NEXT: br i1 true, label %[[ELSE_1:.*]], label %[[IF:.*]] | |
| ; COMMON: [[IF]]: | |
| ; COMMON-NEXT: br label %[[SPLIT:.*]] | |
| ; COMMON: [[ELSE_1]]: | |
| ; COMMON-NEXT: br i1 [[C]], label %[[ELSE_2:.*]], label %[[LOOP_LATCH]] | |
| ; COMMON: [[ELSE_2]]: | |
| ; COMMON-NEXT: br label %[[SPLIT]] | |
| ; COMMON: [[SPLIT]]: | |
| ; COMMON-NEXT: store i32 [[L]], ptr [[I]], align 4 | |
| ; COMMON-NEXT: br label %[[LOOP_LATCH]] | |
| ; COMMON: [[LOOP_LATCH]]: | |
| ; COMMON-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i8, ptr [[PTR_IV]], i64 4 | |
| ; COMMON-NEXT: [[EC:%.*]] = icmp eq ptr [[PTR_IV]], [[I]] | |
| ; COMMON-NEXT: br i1 [[EC]], label %[[EXIT:.*]], label %[[LOOP_HEADER]] | |
| ; COMMON: [[EXIT]]: | |
| ; COMMON-NEXT: ret void | |
| ; | |
| entry: | |
| br label %loop.header | |
| loop.header: | |
| %ptr.iv = phi ptr [ %src, %entry ], [ %ptr.iv.next, %loop.latch ] | |
| %l = load i32, ptr %ptr.iv, align 4 | |
| br i1 true, label %else.1, label %if | |
| if: | |
| br label %split | |
| else.1: | |
| br i1 %c, label %else.2, label %loop.latch | |
| else.2: | |
| br label %split | |
| split: | |
| store i32 %l, ptr %I, align 4 | |
| br label %loop.latch | |
| loop.latch: | |
| %ptr.iv.next = getelementptr inbounds i8, ptr %ptr.iv, i64 4 | |
| %ec = icmp eq ptr %ptr.iv, %I | |
| br i1 %ec, label %exit, label %loop.header | |
| exit: | |
| ret void | |
| } | |
| define void @invar_cond_chain_2(ptr %I, ptr noalias %src, ptr noalias %dst, i32 %a) { | |
| ; COMMON-LABEL: define void @invar_cond_chain_2( | |
| ; COMMON-SAME: ptr [[I:%.*]], ptr noalias [[SRC:%.*]], ptr noalias [[DST:%.*]], i32 [[A:%.*]]) { | |
| ; COMMON-NEXT: [[ENTRY:.*]]: | |
| ; COMMON-NEXT: br label %[[LOOP_HEADER:.*]] | |
| ; COMMON: [[LOOP_HEADER]]: | |
| ; COMMON-NEXT: [[PTR_IV:%.*]] = phi ptr [ [[SRC]], %[[ENTRY]] ], [ [[PTR_IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ] | |
| ; COMMON-NEXT: [[CMP315_NOT:%.*]] = icmp sgt i32 [[A]], 0 | |
| ; COMMON-NEXT: br i1 [[CMP315_NOT]], label %[[LOOP_LATCH]], label %[[IF:.*]] | |
| ; COMMON: [[IF]]: | |
| ; COMMON-NEXT: br label %[[ELSE:.*]] | |
| ; COMMON: [[ELSE]]: | |
| ; COMMON-NEXT: store i32 0, ptr [[DST]], align 4 | |
| ; COMMON-NEXT: br label %[[LOOP_LATCH]] | |
| ; COMMON: [[LOOP_LATCH]]: | |
| ; COMMON-NEXT: [[PTR_IV_NEXT]] = getelementptr inbounds i8, ptr [[PTR_IV]], i64 4 | |
| ; COMMON-NEXT: [[CMP311_NOT:%.*]] = icmp eq ptr [[PTR_IV]], [[I]] | |
| ; COMMON-NEXT: br i1 [[CMP311_NOT]], label %[[EXIT:.*]], label %[[LOOP_HEADER]] | |
| ; COMMON: [[EXIT]]: | |
| ; COMMON-NEXT: ret void | |
| ; | |
| entry: | |
| br label %loop.header | |
| loop.header: | |
| %ptr.iv = phi ptr [ %src, %entry ], [ %ptr.iv.next, %loop.latch ] | |
| %cmp315.not = icmp sgt i32 %a, 0 | |
| br i1 %cmp315.not, label %loop.latch, label %if | |
| if: | |
| br label %else | |
| else: | |
| store i32 0, ptr %dst, align 4 | |
| br label %loop.latch | |
| loop.latch: | |
| %ptr.iv.next = getelementptr inbounds i8, ptr %ptr.iv, i64 4 | |
| %cmp311.not = icmp eq ptr %ptr.iv, %I | |
| br i1 %cmp311.not, label %exit, label %loop.header | |
| exit: | |
| ret void | |
| } | |
| define void @latch_branch_cost(ptr %dst) { | |
| ; DEFAULT-LABEL: define void @latch_branch_cost( | |
| ; DEFAULT-SAME: ptr [[DST:%.*]]) { | |
| ; DEFAULT-NEXT: [[ITER_CHECK:.*:]] | |
| ; DEFAULT-NEXT: br i1 false, label %[[VEC_EPILOG_SCALAR_PH:.*]], label %[[VECTOR_MAIN_LOOP_ITER_CHECK:.*]] | |
| ; DEFAULT: [[VECTOR_MAIN_LOOP_ITER_CHECK]]: | |
| ; DEFAULT-NEXT: br i1 false, label %[[VEC_EPILOG_PH:.*]], label %[[VECTOR_PH:.*]] | |
| ; DEFAULT: [[VECTOR_PH]]: | |
| ; DEFAULT-NEXT: br label %[[VECTOR_BODY:.*]] | |
| ; DEFAULT: [[VECTOR_BODY]]: | |
| ; DEFAULT-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ] | |
| ; DEFAULT-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[DST]], i64 [[INDEX]] | |
| ; DEFAULT-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP2]], i64 16 | |
| ; DEFAULT-NEXT: store <16 x i8> zeroinitializer, ptr [[TMP2]], align 1 | |
| ; DEFAULT-NEXT: store <16 x i8> zeroinitializer, ptr [[TMP5]], align 1 | |
| ; DEFAULT-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 32 | |
| ; DEFAULT-NEXT: [[TMP4:%.*]] = icmp eq i64 [[INDEX_NEXT]], 96 | |
| ; DEFAULT-NEXT: br i1 [[TMP4]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP4:![0-9]+]] | |
| ; DEFAULT: [[MIDDLE_BLOCK]]: | |
| ; DEFAULT-NEXT: br i1 false, [[EXIT:label %.*]], label %[[VEC_EPILOG_ITER_CHECK:.*]] | |
| ; DEFAULT: [[VEC_EPILOG_ITER_CHECK]]: | |
| ; DEFAULT-NEXT: br i1 false, label %[[VEC_EPILOG_SCALAR_PH]], label %[[VEC_EPILOG_PH]], !prof [[PROF5:![0-9]+]] | |
| ; DEFAULT: [[VEC_EPILOG_PH]]: | |
| ; DEFAULT-NEXT: [[VEC_EPILOG_RESUME_VAL:%.*]] = phi i64 [ 96, %[[VEC_EPILOG_ITER_CHECK]] ], [ 0, %[[VECTOR_MAIN_LOOP_ITER_CHECK]] ] | |
| ; DEFAULT-NEXT: br label %[[VEC_EPILOG_VECTOR_BODY:.*]] | |
| ; DEFAULT: [[VEC_EPILOG_VECTOR_BODY]]: | |
| ; DEFAULT-NEXT: [[INDEX1:%.*]] = phi i64 [ [[VEC_EPILOG_RESUME_VAL]], %[[VEC_EPILOG_PH]] ], [ [[INDEX_NEXT2:%.*]], %[[VEC_EPILOG_VECTOR_BODY]] ] | |
| ; DEFAULT-NEXT: [[TMP8:%.*]] = getelementptr i8, ptr [[DST]], i64 [[INDEX1]] | |
| ; DEFAULT-NEXT: store <4 x i8> zeroinitializer, ptr [[TMP8]], align 1 | |
| ; DEFAULT-NEXT: [[INDEX_NEXT2]] = add nuw i64 [[INDEX1]], 4 | |
| ; DEFAULT-NEXT: [[TMP10:%.*]] = icmp eq i64 [[INDEX_NEXT2]], 100 | |
| ; DEFAULT-NEXT: br i1 [[TMP10]], label %[[VEC_EPILOG_MIDDLE_BLOCK:.*]], label %[[VEC_EPILOG_VECTOR_BODY]], !llvm.loop [[LOOP6:![0-9]+]] | |
| ; DEFAULT: [[VEC_EPILOG_MIDDLE_BLOCK]]: | |
| ; DEFAULT-NEXT: br i1 true, [[EXIT]], label %[[VEC_EPILOG_SCALAR_PH]] | |
| ; DEFAULT: [[VEC_EPILOG_SCALAR_PH]]: | |
| ; | |
| ; PRED-LABEL: define void @latch_branch_cost( | |
| ; PRED-SAME: ptr [[DST:%.*]]) { | |
| ; PRED-NEXT: [[ENTRY:.*:]] | |
| ; PRED-NEXT: br label %[[VECTOR_PH:.*]] | |
| ; PRED: [[VECTOR_PH]]: | |
| ; PRED-NEXT: br label %[[VECTOR_BODY:.*]] | |
| ; PRED: [[VECTOR_BODY]]: | |
| ; PRED-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[PRED_STORE_CONTINUE14:.*]] ] | |
| ; PRED-NEXT: [[VEC_IND:%.*]] = phi <8 x i8> [ <i8 0, i8 1, i8 2, i8 3, i8 4, i8 5, i8 6, i8 7>, %[[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], %[[PRED_STORE_CONTINUE14]] ] | |
| ; PRED-NEXT: [[TMP0:%.*]] = icmp ule <8 x i8> [[VEC_IND]], splat (i8 99) | |
| ; PRED-NEXT: [[TMP1:%.*]] = extractelement <8 x i1> [[TMP0]], i64 0 | |
| ; PRED-NEXT: br i1 [[TMP1]], label %[[PRED_STORE_IF:.*]], label %[[PRED_STORE_CONTINUE:.*]] | |
| ; PRED: [[PRED_STORE_IF]]: | |
| ; PRED-NEXT: [[TMP3:%.*]] = getelementptr i8, ptr [[DST]], i64 [[INDEX]] | |
| ; PRED-NEXT: store i8 0, ptr [[TMP3]], align 1 | |
| ; PRED-NEXT: br label %[[PRED_STORE_CONTINUE]] | |
| ; PRED: [[PRED_STORE_CONTINUE]]: | |
| ; PRED-NEXT: [[TMP4:%.*]] = extractelement <8 x i1> [[TMP0]], i64 1 | |
| ; PRED-NEXT: br i1 [[TMP4]], label %[[PRED_STORE_IF1:.*]], label %[[PRED_STORE_CONTINUE2:.*]] | |
| ; PRED: [[PRED_STORE_IF1]]: | |
| ; PRED-NEXT: [[TMP5:%.*]] = add i64 [[INDEX]], 1 | |
| ; PRED-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[DST]], i64 [[TMP5]] | |
| ; PRED-NEXT: store i8 0, ptr [[TMP6]], align 1 | |
| ; PRED-NEXT: br label %[[PRED_STORE_CONTINUE2]] | |
| ; PRED: [[PRED_STORE_CONTINUE2]]: | |
| ; PRED-NEXT: [[TMP7:%.*]] = extractelement <8 x i1> [[TMP0]], i64 2 | |
| ; PRED-NEXT: br i1 [[TMP7]], label %[[PRED_STORE_IF3:.*]], label %[[PRED_STORE_CONTINUE4:.*]] | |
| ; PRED: [[PRED_STORE_IF3]]: | |
| ; PRED-NEXT: [[TMP8:%.*]] = add i64 [[INDEX]], 2 | |
| ; PRED-NEXT: [[TMP9:%.*]] = getelementptr i8, ptr [[DST]], i64 [[TMP8]] | |
| ; PRED-NEXT: store i8 0, ptr [[TMP9]], align 1 | |
| ; PRED-NEXT: br label %[[PRED_STORE_CONTINUE4]] | |
| ; PRED: [[PRED_STORE_CONTINUE4]]: | |
| ; PRED-NEXT: [[TMP10:%.*]] = extractelement <8 x i1> [[TMP0]], i64 3 | |
| ; PRED-NEXT: br i1 [[TMP10]], label %[[PRED_STORE_IF5:.*]], label %[[PRED_STORE_CONTINUE6:.*]] | |
| ; PRED: [[PRED_STORE_IF5]]: | |
| ; PRED-NEXT: [[TMP11:%.*]] = add i64 [[INDEX]], 3 | |
| ; PRED-NEXT: [[TMP24:%.*]] = getelementptr i8, ptr [[DST]], i64 [[TMP11]] | |
| ; PRED-NEXT: store i8 0, ptr [[TMP24]], align 1 | |
| ; PRED-NEXT: br label %[[PRED_STORE_CONTINUE6]] | |
| ; PRED: [[PRED_STORE_CONTINUE6]]: | |
| ; PRED-NEXT: [[TMP12:%.*]] = extractelement <8 x i1> [[TMP0]], i64 4 | |
| ; PRED-NEXT: br i1 [[TMP12]], label %[[MIDDLE_BLOCK:.*]], label %[[EXIT:.*]] | |
| ; PRED: [[MIDDLE_BLOCK]]: | |
| ; PRED-NEXT: [[TMP13:%.*]] = add i64 [[INDEX]], 4 | |
| ; PRED-NEXT: [[TMP14:%.*]] = getelementptr i8, ptr [[DST]], i64 [[TMP13]] | |
| ; PRED-NEXT: store i8 0, ptr [[TMP14]], align 1 | |
| ; PRED-NEXT: br label %[[EXIT]] | |
| ; PRED: [[EXIT]]: | |
| ; PRED-NEXT: [[TMP15:%.*]] = extractelement <8 x i1> [[TMP0]], i64 5 | |
| ; PRED-NEXT: br i1 [[TMP15]], label %[[PRED_STORE_IF9:.*]], label %[[PRED_STORE_CONTINUE10:.*]] | |
| ; PRED: [[PRED_STORE_IF9]]: | |
| ; PRED-NEXT: [[TMP16:%.*]] = add i64 [[INDEX]], 5 | |
| ; PRED-NEXT: [[TMP17:%.*]] = getelementptr i8, ptr [[DST]], i64 [[TMP16]] | |
| ; PRED-NEXT: store i8 0, ptr [[TMP17]], align 1 | |
| ; PRED-NEXT: br label %[[PRED_STORE_CONTINUE10]] | |
| ; PRED: [[PRED_STORE_CONTINUE10]]: | |
| ; PRED-NEXT: [[TMP18:%.*]] = extractelement <8 x i1> [[TMP0]], i64 6 | |
| ; PRED-NEXT: br i1 [[TMP18]], label %[[PRED_STORE_IF11:.*]], label %[[PRED_STORE_CONTINUE12:.*]] | |
| ; PRED: [[PRED_STORE_IF11]]: | |
| ; PRED-NEXT: [[TMP19:%.*]] = add i64 [[INDEX]], 6 | |
| ; PRED-NEXT: [[TMP20:%.*]] = getelementptr i8, ptr [[DST]], i64 [[TMP19]] | |
| ; PRED-NEXT: store i8 0, ptr [[TMP20]], align 1 | |
| ; PRED-NEXT: br label %[[PRED_STORE_CONTINUE12]] | |
| ; PRED: [[PRED_STORE_CONTINUE12]]: | |
| ; PRED-NEXT: [[TMP21:%.*]] = extractelement <8 x i1> [[TMP0]], i64 7 | |
| ; PRED-NEXT: br i1 [[TMP21]], label %[[PRED_STORE_IF13:.*]], label %[[PRED_STORE_CONTINUE14]] | |
| ; PRED: [[PRED_STORE_IF13]]: | |
| ; PRED-NEXT: [[TMP22:%.*]] = add i64 [[INDEX]], 7 | |
| ; PRED-NEXT: [[TMP23:%.*]] = getelementptr i8, ptr [[DST]], i64 [[TMP22]] | |
| ; PRED-NEXT: store i8 0, ptr [[TMP23]], align 1 | |
| ; PRED-NEXT: br label %[[PRED_STORE_CONTINUE14]] | |
| ; PRED: [[PRED_STORE_CONTINUE14]]: | |
| ; PRED-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 8 | |
| ; PRED-NEXT: [[VEC_IND_NEXT]] = add nuw <8 x i8> [[VEC_IND]], splat (i8 8) | |
| ; PRED-NEXT: [[TMP25:%.*]] = icmp eq i64 [[INDEX_NEXT]], 104 | |
| ; PRED-NEXT: br i1 [[TMP25]], label %[[MIDDLE_BLOCK1:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]] | |
| ; PRED: [[MIDDLE_BLOCK1]]: | |
| ; PRED-NEXT: br label %[[EXIT1:.*]] | |
| ; PRED: [[EXIT1]]: | |
| ; PRED-NEXT: ret void | |
| ; | |
| entry: | |
| br label %loop | |
| loop: | |
| %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] | |
| %gep = getelementptr i8, ptr %dst, i64 %iv | |
| store i8 0, ptr %gep, align 1 | |
| %iv.next = add i64 %iv, 1 | |
| %ec = icmp eq i64 %iv.next, 100 | |
| br i1 %ec, label %exit, label %loop | |
| exit: | |
| ret void | |
| } | |
| define i32 @header_mask_and_invariant_compare(ptr %A, ptr %B, ptr %C, ptr %D, ptr %E, i64 %N) "target-features"="+sve" { | |
| ; DEFAULT-LABEL: define i32 @header_mask_and_invariant_compare( | |
| ; DEFAULT-SAME: ptr [[A:%.*]], ptr [[B:%.*]], ptr [[C:%.*]], ptr [[D:%.*]], ptr [[E:%.*]], i64 [[N:%.*]]) #[[ATTR0:[0-9]+]] { | |
| ; DEFAULT-NEXT: [[ENTRY:.*:]] | |
| ; DEFAULT-NEXT: [[TMP0:%.*]] = add i64 [[N]], 1 | |
| ; DEFAULT-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[TMP0]], 28 | |
| ; DEFAULT-NEXT: br i1 [[MIN_ITERS_CHECK]], label %[[SCALAR_PH:.*]], label %[[VECTOR_MEMCHECK:.*]] | |
| ; DEFAULT: [[VECTOR_MEMCHECK]]: | |
| ; DEFAULT-NEXT: [[SCEVGEP:%.*]] = getelementptr i8, ptr [[E]], i64 4 | |
| ; DEFAULT-NEXT: [[TMP1:%.*]] = shl i64 [[N]], 2 | |
| ; DEFAULT-NEXT: [[TMP2:%.*]] = add i64 [[TMP1]], 4 | |
| ; DEFAULT-NEXT: [[SCEVGEP1:%.*]] = getelementptr i8, ptr [[D]], i64 [[TMP2]] | |
| ; DEFAULT-NEXT: [[SCEVGEP2:%.*]] = getelementptr i8, ptr [[A]], i64 4 | |
| ; DEFAULT-NEXT: [[SCEVGEP3:%.*]] = getelementptr i8, ptr [[B]], i64 4 | |
| ; DEFAULT-NEXT: [[SCEVGEP4:%.*]] = getelementptr i8, ptr [[C]], i64 4 | |
| ; DEFAULT-NEXT: [[BOUND0:%.*]] = icmp ult ptr [[E]], [[SCEVGEP1]] | |
| ; DEFAULT-NEXT: [[BOUND1:%.*]] = icmp ult ptr [[D]], [[SCEVGEP]] | |
| ; DEFAULT-NEXT: [[FOUND_CONFLICT:%.*]] = and i1 [[BOUND0]], [[BOUND1]] | |
| ; DEFAULT-NEXT: [[BOUND05:%.*]] = icmp ult ptr [[E]], [[SCEVGEP2]] | |
| ; DEFAULT-NEXT: [[BOUND16:%.*]] = icmp ult ptr [[A]], [[SCEVGEP]] | |
| ; DEFAULT-NEXT: [[FOUND_CONFLICT7:%.*]] = and i1 [[BOUND05]], [[BOUND16]] | |
| ; DEFAULT-NEXT: [[CONFLICT_RDX:%.*]] = or i1 [[FOUND_CONFLICT]], [[FOUND_CONFLICT7]] | |
| ; DEFAULT-NEXT: [[BOUND08:%.*]] = icmp ult ptr [[E]], [[SCEVGEP3]] | |
| ; DEFAULT-NEXT: [[BOUND19:%.*]] = icmp ult ptr [[B]], [[SCEVGEP]] | |
| ; DEFAULT-NEXT: [[FOUND_CONFLICT10:%.*]] = and i1 [[BOUND08]], [[BOUND19]] | |
| ; DEFAULT-NEXT: [[CONFLICT_RDX11:%.*]] = or i1 [[CONFLICT_RDX]], [[FOUND_CONFLICT10]] | |
| ; DEFAULT-NEXT: [[BOUND012:%.*]] = icmp ult ptr [[E]], [[SCEVGEP4]] | |
| ; DEFAULT-NEXT: [[BOUND113:%.*]] = icmp ult ptr [[C]], [[SCEVGEP]] | |
| ; DEFAULT-NEXT: [[FOUND_CONFLICT14:%.*]] = and i1 [[BOUND012]], [[BOUND113]] | |
| ; DEFAULT-NEXT: [[CONFLICT_RDX15:%.*]] = or i1 [[CONFLICT_RDX11]], [[FOUND_CONFLICT14]] | |
| ; DEFAULT-NEXT: [[BOUND016:%.*]] = icmp ult ptr [[D]], [[SCEVGEP2]] | |
| ; DEFAULT-NEXT: [[BOUND117:%.*]] = icmp ult ptr [[A]], [[SCEVGEP1]] | |
| ; DEFAULT-NEXT: [[FOUND_CONFLICT18:%.*]] = and i1 [[BOUND016]], [[BOUND117]] | |
| ; DEFAULT-NEXT: [[CONFLICT_RDX19:%.*]] = or i1 [[CONFLICT_RDX15]], [[FOUND_CONFLICT18]] | |
| ; DEFAULT-NEXT: [[BOUND020:%.*]] = icmp ult ptr [[D]], [[SCEVGEP3]] | |
| ; DEFAULT-NEXT: [[BOUND121:%.*]] = icmp ult ptr [[B]], [[SCEVGEP1]] | |
| ; DEFAULT-NEXT: [[FOUND_CONFLICT22:%.*]] = and i1 [[BOUND020]], [[BOUND121]] | |
| ; DEFAULT-NEXT: [[CONFLICT_RDX23:%.*]] = or i1 [[CONFLICT_RDX19]], [[FOUND_CONFLICT22]] | |
| ; DEFAULT-NEXT: [[BOUND024:%.*]] = icmp ult ptr [[D]], [[SCEVGEP4]] | |
| ; DEFAULT-NEXT: [[BOUND125:%.*]] = icmp ult ptr [[C]], [[SCEVGEP1]] | |
| ; DEFAULT-NEXT: [[FOUND_CONFLICT26:%.*]] = and i1 [[BOUND024]], [[BOUND125]] | |
| ; DEFAULT-NEXT: [[CONFLICT_RDX27:%.*]] = or i1 [[CONFLICT_RDX23]], [[FOUND_CONFLICT26]] | |
| ; DEFAULT-NEXT: br i1 [[CONFLICT_RDX27]], label %[[SCALAR_PH]], label %[[VECTOR_PH:.*]] | |
| ; DEFAULT: [[VECTOR_PH]]: | |
| ; DEFAULT-NEXT: [[N_MOD_VF:%.*]] = and i64 [[TMP0]], 3 | |
| ; DEFAULT-NEXT: [[N_VEC:%.*]] = sub i64 [[TMP0]], [[N_MOD_VF]] | |
| ; DEFAULT-NEXT: [[TMP3:%.*]] = load i32, ptr [[A]], align 4, !alias.scope [[META8:![0-9]+]] | |
| ; DEFAULT-NEXT: [[TMP4:%.*]] = load i32, ptr [[B]], align 4, !alias.scope [[META11:![0-9]+]] | |
| ; DEFAULT-NEXT: [[TMP5:%.*]] = or i32 [[TMP4]], [[TMP3]] | |
| ; DEFAULT-NEXT: [[TMP6:%.*]] = load i32, ptr [[C]], align 4, !alias.scope [[META13:![0-9]+]] | |
| ; DEFAULT-NEXT: [[TMP7:%.*]] = icmp ugt i32 [[TMP6]], [[TMP5]] | |
| ; DEFAULT-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement <4 x i1> poison, i1 [[TMP7]], i64 0 | |
| ; DEFAULT-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector <4 x i1> [[BROADCAST_SPLATINSERT]], <4 x i1> poison, <4 x i32> zeroinitializer | |
| ; DEFAULT-NEXT: br label %[[VECTOR_BODY:.*]] | |
| ; DEFAULT: [[VECTOR_BODY]]: | |
| ; DEFAULT-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[PRED_STORE_CONTINUE33:.*]] ] | |
| ; DEFAULT-NEXT: [[TMP16:%.*]] = getelementptr i32, ptr [[D]], i64 [[INDEX]] | |
| ; DEFAULT-NEXT: br i1 [[TMP7]], label %[[PRED_STORE_IF:.*]], label %[[PRED_STORE_CONTINUE:.*]] | |
| ; DEFAULT: [[PRED_STORE_IF]]: | |
| ; DEFAULT-NEXT: store i32 [[TMP5]], ptr [[E]], align 4, !alias.scope [[META15:![0-9]+]], !noalias [[META17:![0-9]+]] | |
| ; DEFAULT-NEXT: br label %[[PRED_STORE_CONTINUE]] | |
| ; DEFAULT: [[PRED_STORE_CONTINUE]]: | |
| ; DEFAULT-NEXT: br i1 [[TMP7]], label %[[PRED_STORE_IF28:.*]], label %[[PRED_STORE_CONTINUE29:.*]] | |
| ; DEFAULT: [[PRED_STORE_IF28]]: | |
| ; DEFAULT-NEXT: store i32 [[TMP5]], ptr [[E]], align 4, !alias.scope [[META15]], !noalias [[META17]] | |
| ; DEFAULT-NEXT: br label %[[PRED_STORE_CONTINUE29]] | |
| ; DEFAULT: [[PRED_STORE_CONTINUE29]]: | |
| ; DEFAULT-NEXT: br i1 [[TMP7]], label %[[PRED_STORE_IF30:.*]], label %[[PRED_STORE_CONTINUE31:.*]] | |
| ; DEFAULT: [[PRED_STORE_IF30]]: | |
| ; DEFAULT-NEXT: store i32 [[TMP5]], ptr [[E]], align 4, !alias.scope [[META15]], !noalias [[META17]] | |
| ; DEFAULT-NEXT: br label %[[PRED_STORE_CONTINUE31]] | |
| ; DEFAULT: [[PRED_STORE_CONTINUE31]]: | |
| ; DEFAULT-NEXT: br i1 [[TMP7]], label %[[PRED_STORE_IF32:.*]], label %[[PRED_STORE_CONTINUE33]] | |
| ; DEFAULT: [[PRED_STORE_IF32]]: | |
| ; DEFAULT-NEXT: store i32 [[TMP5]], ptr [[E]], align 4, !alias.scope [[META15]], !noalias [[META17]] | |
| ; DEFAULT-NEXT: br label %[[PRED_STORE_CONTINUE33]] | |
| ; DEFAULT: [[PRED_STORE_CONTINUE33]]: | |
| ; DEFAULT-NEXT: call void @llvm.masked.store.v4i32.p0(<4 x i32> zeroinitializer, ptr align 4 [[TMP16]], <4 x i1> [[BROADCAST_SPLAT]]), !alias.scope [[META19:![0-9]+]], !noalias [[META20:![0-9]+]] | |
| ; DEFAULT-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4 | |
| ; DEFAULT-NEXT: [[TMP18:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]] | |
| ; DEFAULT-NEXT: br i1 [[TMP18]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP21:![0-9]+]] | |
| ; DEFAULT: [[MIDDLE_BLOCK]]: | |
| ; DEFAULT-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[TMP0]], [[N_VEC]] | |
| ; DEFAULT-NEXT: br i1 [[CMP_N]], [[EXIT:label %.*]], label %[[SCALAR_PH]] | |
| ; DEFAULT: [[SCALAR_PH]]: | |
| ; | |
| ; PRED-LABEL: define i32 @header_mask_and_invariant_compare( | |
| ; PRED-SAME: ptr [[A:%.*]], ptr [[B:%.*]], ptr [[C:%.*]], ptr [[D:%.*]], ptr [[E:%.*]], i64 [[N:%.*]]) #[[ATTR0:[0-9]+]] { | |
| ; PRED-NEXT: [[ENTRY:.*:]] | |
| ; PRED-NEXT: [[TMP0:%.*]] = add i64 [[N]], 1 | |
| ; PRED-NEXT: br label %[[VECTOR_MEMCHECK:.*]] | |
| ; PRED: [[VECTOR_MEMCHECK]]: | |
| ; PRED-NEXT: [[SCEVGEP:%.*]] = getelementptr i8, ptr [[E]], i64 4 | |
| ; PRED-NEXT: [[TMP1:%.*]] = shl i64 [[N]], 2 | |
| ; PRED-NEXT: [[TMP2:%.*]] = add i64 [[TMP1]], 4 | |
| ; PRED-NEXT: [[SCEVGEP1:%.*]] = getelementptr i8, ptr [[D]], i64 [[TMP2]] | |
| ; PRED-NEXT: [[SCEVGEP2:%.*]] = getelementptr i8, ptr [[A]], i64 4 | |
| ; PRED-NEXT: [[SCEVGEP3:%.*]] = getelementptr i8, ptr [[B]], i64 4 | |
| ; PRED-NEXT: [[SCEVGEP4:%.*]] = getelementptr i8, ptr [[C]], i64 4 | |
| ; PRED-NEXT: [[BOUND0:%.*]] = icmp ult ptr [[E]], [[SCEVGEP1]] | |
| ; PRED-NEXT: [[BOUND1:%.*]] = icmp ult ptr [[D]], [[SCEVGEP]] | |
| ; PRED-NEXT: [[FOUND_CONFLICT:%.*]] = and i1 [[BOUND0]], [[BOUND1]] | |
| ; PRED-NEXT: [[BOUND05:%.*]] = icmp ult ptr [[E]], [[SCEVGEP2]] | |
| ; PRED-NEXT: [[BOUND16:%.*]] = icmp ult ptr [[A]], [[SCEVGEP]] | |
| ; PRED-NEXT: [[FOUND_CONFLICT7:%.*]] = and i1 [[BOUND05]], [[BOUND16]] | |
| ; PRED-NEXT: [[CONFLICT_RDX:%.*]] = or i1 [[FOUND_CONFLICT]], [[FOUND_CONFLICT7]] | |
| ; PRED-NEXT: [[BOUND08:%.*]] = icmp ult ptr [[E]], [[SCEVGEP3]] | |
| ; PRED-NEXT: [[BOUND19:%.*]] = icmp ult ptr [[B]], [[SCEVGEP]] | |
| ; PRED-NEXT: [[FOUND_CONFLICT10:%.*]] = and i1 [[BOUND08]], [[BOUND19]] | |
| ; PRED-NEXT: [[CONFLICT_RDX11:%.*]] = or i1 [[CONFLICT_RDX]], [[FOUND_CONFLICT10]] | |
| ; PRED-NEXT: [[BOUND012:%.*]] = icmp ult ptr [[E]], [[SCEVGEP4]] | |
| ; PRED-NEXT: [[BOUND113:%.*]] = icmp ult ptr [[C]], [[SCEVGEP]] | |
| ; PRED-NEXT: [[FOUND_CONFLICT14:%.*]] = and i1 [[BOUND012]], [[BOUND113]] | |
| ; PRED-NEXT: [[CONFLICT_RDX15:%.*]] = or i1 [[CONFLICT_RDX11]], [[FOUND_CONFLICT14]] | |
| ; PRED-NEXT: [[BOUND016:%.*]] = icmp ult ptr [[D]], [[SCEVGEP2]] | |
| ; PRED-NEXT: [[BOUND117:%.*]] = icmp ult ptr [[A]], [[SCEVGEP1]] | |
| ; PRED-NEXT: [[FOUND_CONFLICT18:%.*]] = and i1 [[BOUND016]], [[BOUND117]] | |
| ; PRED-NEXT: [[CONFLICT_RDX19:%.*]] = or i1 [[CONFLICT_RDX15]], [[FOUND_CONFLICT18]] | |
| ; PRED-NEXT: [[BOUND020:%.*]] = icmp ult ptr [[D]], [[SCEVGEP3]] | |
| ; PRED-NEXT: [[BOUND121:%.*]] = icmp ult ptr [[B]], [[SCEVGEP1]] | |
| ; PRED-NEXT: [[FOUND_CONFLICT22:%.*]] = and i1 [[BOUND020]], [[BOUND121]] | |
| ; PRED-NEXT: [[CONFLICT_RDX23:%.*]] = or i1 [[CONFLICT_RDX19]], [[FOUND_CONFLICT22]] | |
| ; PRED-NEXT: [[BOUND024:%.*]] = icmp ult ptr [[D]], [[SCEVGEP4]] | |
| ; PRED-NEXT: [[BOUND125:%.*]] = icmp ult ptr [[C]], [[SCEVGEP1]] | |
| ; PRED-NEXT: [[FOUND_CONFLICT26:%.*]] = and i1 [[BOUND024]], [[BOUND125]] | |
| ; PRED-NEXT: [[CONFLICT_RDX27:%.*]] = or i1 [[CONFLICT_RDX23]], [[FOUND_CONFLICT26]] | |
| ; PRED-NEXT: br i1 [[CONFLICT_RDX27]], label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]] | |
| ; PRED: [[VECTOR_PH]]: | |
| ; PRED-NEXT: [[TMP8:%.*]] = call i64 @llvm.vscale.i64() | |
| ; PRED-NEXT: [[TMP9:%.*]] = shl nuw i64 [[TMP8]], 2 | |
| ; PRED-NEXT: [[L_A:%.*]] = load i32, ptr [[A]], align 4, !alias.scope [[META3:![0-9]+]] | |
| ; PRED-NEXT: [[L_B:%.*]] = load i32, ptr [[B]], align 4, !alias.scope [[META6:![0-9]+]] | |
| ; PRED-NEXT: [[OR:%.*]] = or i32 [[L_B]], [[L_A]] | |
| ; PRED-NEXT: [[BROADCAST_SPLATINSERT30:%.*]] = insertelement <vscale x 4 x i32> poison, i32 [[OR]], i64 0 | |
| ; PRED-NEXT: [[BROADCAST_SPLAT31:%.*]] = shufflevector <vscale x 4 x i32> [[BROADCAST_SPLATINSERT30]], <vscale x 4 x i32> poison, <vscale x 4 x i32> zeroinitializer | |
| ; PRED-NEXT: [[L_C:%.*]] = load i32, ptr [[C]], align 4, !alias.scope [[META8:![0-9]+]] | |
| ; PRED-NEXT: [[C_0:%.*]] = icmp ugt i32 [[L_C]], [[OR]] | |
| ; PRED-NEXT: [[BROADCAST_SPLATINSERT28:%.*]] = insertelement <vscale x 4 x i1> poison, i1 [[C_0]], i64 0 | |
| ; PRED-NEXT: [[BROADCAST_SPLAT29:%.*]] = shufflevector <vscale x 4 x i1> [[BROADCAST_SPLATINSERT28]], <vscale x 4 x i1> poison, <vscale x 4 x i32> zeroinitializer | |
| ; PRED-NEXT: [[ACTIVE_LANE_MASK_ENTRY:%.*]] = call <vscale x 4 x i1> @llvm.get.active.lane.mask.nxv4i1.i64(i64 0, i64 [[TMP0]]) | |
| ; PRED-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement <vscale x 4 x ptr> poison, ptr [[E]], i64 0 | |
| ; PRED-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector <vscale x 4 x ptr> [[BROADCAST_SPLATINSERT]], <vscale x 4 x ptr> poison, <vscale x 4 x i32> zeroinitializer | |
| ; PRED-NEXT: br label %[[VECTOR_BODY:.*]] | |
| ; PRED: [[VECTOR_BODY]]: | |
| ; PRED-NEXT: [[IV:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ] | |
| ; PRED-NEXT: [[ACTIVE_LANE_MASK:%.*]] = phi <vscale x 4 x i1> [ [[ACTIVE_LANE_MASK_ENTRY]], %[[VECTOR_PH]] ], [ [[ACTIVE_LANE_MASK_NEXT:%.*]], %[[VECTOR_BODY]] ] | |
| ; PRED-NEXT: [[TMP15:%.*]] = select <vscale x 4 x i1> [[ACTIVE_LANE_MASK]], <vscale x 4 x i1> [[BROADCAST_SPLAT29]], <vscale x 4 x i1> zeroinitializer | |
| ; PRED-NEXT: [[GEP_D:%.*]] = getelementptr i32, ptr [[D]], i64 [[IV]] | |
| ; PRED-NEXT: call void @llvm.masked.scatter.nxv4i32.nxv4p0(<vscale x 4 x i32> [[BROADCAST_SPLAT31]], <vscale x 4 x ptr> align 4 [[BROADCAST_SPLAT]], <vscale x 4 x i1> [[TMP15]]), !alias.scope [[META10:![0-9]+]], !noalias [[META12:![0-9]+]] | |
| ; PRED-NEXT: call void @llvm.masked.store.nxv4i32.p0(<vscale x 4 x i32> zeroinitializer, ptr align 4 [[GEP_D]], <vscale x 4 x i1> [[TMP15]]), !alias.scope [[META14:![0-9]+]], !noalias [[META15:![0-9]+]] | |
| ; PRED-NEXT: [[INDEX_NEXT]] = add i64 [[IV]], [[TMP9]] | |
| ; PRED-NEXT: [[ACTIVE_LANE_MASK_NEXT]] = call <vscale x 4 x i1> @llvm.get.active.lane.mask.nxv4i1.i64(i64 [[INDEX_NEXT]], i64 [[TMP0]]) | |
| ; PRED-NEXT: [[TMP17:%.*]] = extractelement <vscale x 4 x i1> [[ACTIVE_LANE_MASK_NEXT]], i64 0 | |
| ; PRED-NEXT: [[TMP18:%.*]] = xor i1 [[TMP17]], true | |
| ; PRED-NEXT: br i1 [[TMP18]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP16:![0-9]+]] | |
| ; PRED: [[MIDDLE_BLOCK]]: | |
| ; PRED-NEXT: br [[EXIT:label %.*]] | |
| ; PRED: [[SCALAR_PH]]: | |
| ; | |
| entry: | |
| br label %loop.header | |
| loop.header: | |
| %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ] | |
| %l.A = load i32, ptr %A, align 4 | |
| %l.B = load i32, ptr %B, align 4 | |
| %or = or i32 %l.B, %l.A | |
| %l.C = load i32, ptr %C, align 4 | |
| %c.0 = icmp ugt i32 %l.C, %or | |
| br i1 %c.0, label %if.then, label %loop.latch | |
| if.then: | |
| %gep.D = getelementptr i32, ptr %D, i64 %iv | |
| store i32 %or, ptr %E, align 4 | |
| store i32 0, ptr %gep.D, align 4 | |
| br label %loop.latch | |
| loop.latch: | |
| %iv.next = add i64 %iv, 1 | |
| %c.1 = icmp eq i64 %iv, %N | |
| br i1 %c.1, label %exit, label %loop.header | |
| exit: | |
| ret i32 0 | |
| } | |
| define void @multiple_exit_conditions(ptr %src, ptr noalias %dst) #1 { | |
| ; DEFAULT-LABEL: define void @multiple_exit_conditions( | |
| ; DEFAULT-SAME: ptr [[SRC:%.*]], ptr noalias [[DST:%.*]]) #[[ATTR1:[0-9]+]] { | |
| ; DEFAULT-NEXT: [[ENTRY:.*:]] | |
| ; DEFAULT-NEXT: [[TMP2:%.*]] = call i64 @llvm.vscale.i64() | |
| ; DEFAULT-NEXT: [[TMP3:%.*]] = shl nuw i64 [[TMP2]], 4 | |
| ; DEFAULT-NEXT: [[MIN_ITERS_CHECK1:%.*]] = icmp ult i64 257, [[TMP3]] | |
| ; DEFAULT-NEXT: br i1 [[MIN_ITERS_CHECK1]], label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]] | |
| ; DEFAULT: [[VECTOR_PH]]: | |
| ; DEFAULT-NEXT: [[TMP11:%.*]] = shl nuw i64 [[TMP2]], 2 | |
| ; DEFAULT-NEXT: [[N_MOD_VF:%.*]] = urem i64 257, [[TMP3]] | |
| ; DEFAULT-NEXT: [[N_VEC:%.*]] = sub i64 257, [[N_MOD_VF]] | |
| ; DEFAULT-NEXT: [[OFFSET_IDX:%.*]] = shl i64 [[N_VEC]], 3 | |
| ; DEFAULT-NEXT: [[NEXT_GEP:%.*]] = getelementptr i8, ptr [[DST]], i64 [[OFFSET_IDX]] | |
| ; DEFAULT-NEXT: [[TMP7:%.*]] = shl i64 [[N_VEC]], 1 | |
| ; DEFAULT-NEXT: br label %[[VECTOR_BODY:.*]] | |
| ; DEFAULT: [[VECTOR_BODY]]: | |
| ; DEFAULT-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ] | |
| ; DEFAULT-NEXT: [[OFFSET_IDX1:%.*]] = shl i64 [[INDEX]], 3 | |
| ; DEFAULT-NEXT: [[NEXT_GEP1:%.*]] = getelementptr i8, ptr [[DST]], i64 [[OFFSET_IDX1]] | |
| ; DEFAULT-NEXT: [[TMP1:%.*]] = load i16, ptr [[SRC]], align 2 | |
| ; DEFAULT-NEXT: [[TMP8:%.*]] = or i16 [[TMP1]], 1 | |
| ; DEFAULT-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement <vscale x 4 x i16> poison, i16 [[TMP8]], i64 0 | |
| ; DEFAULT-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector <vscale x 4 x i16> [[BROADCAST_SPLATINSERT]], <vscale x 4 x i16> poison, <vscale x 4 x i32> zeroinitializer | |
| ; DEFAULT-NEXT: [[TMP9:%.*]] = uitofp <vscale x 4 x i16> [[BROADCAST_SPLAT]] to <vscale x 4 x double> | |
| ; DEFAULT-NEXT: [[TMP14:%.*]] = shl nuw nsw i64 [[TMP11]], 1 | |
| ; DEFAULT-NEXT: [[TMP17:%.*]] = mul nuw nsw i64 [[TMP11]], 3 | |
| ; DEFAULT-NEXT: [[TMP12:%.*]] = getelementptr double, ptr [[NEXT_GEP1]], i64 [[TMP11]] | |
| ; DEFAULT-NEXT: [[TMP15:%.*]] = getelementptr double, ptr [[NEXT_GEP1]], i64 [[TMP14]] | |
| ; DEFAULT-NEXT: [[TMP18:%.*]] = getelementptr double, ptr [[NEXT_GEP1]], i64 [[TMP17]] | |
| ; DEFAULT-NEXT: store <vscale x 4 x double> [[TMP9]], ptr [[NEXT_GEP1]], align 8 | |
| ; DEFAULT-NEXT: store <vscale x 4 x double> [[TMP9]], ptr [[TMP12]], align 8 | |
| ; DEFAULT-NEXT: store <vscale x 4 x double> [[TMP9]], ptr [[TMP15]], align 8 | |
| ; DEFAULT-NEXT: store <vscale x 4 x double> [[TMP9]], ptr [[TMP18]], align 8 | |
| ; DEFAULT-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], [[TMP3]] | |
| ; DEFAULT-NEXT: [[TMP19:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]] | |
| ; DEFAULT-NEXT: br i1 [[TMP19]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP23:![0-9]+]] | |
| ; DEFAULT: [[MIDDLE_BLOCK]]: | |
| ; DEFAULT-NEXT: [[CMP_N:%.*]] = icmp eq i64 257, [[N_VEC]] | |
| ; DEFAULT-NEXT: br i1 [[CMP_N]], [[EXIT:label %.*]], label %[[SCALAR_PH]] | |
| ; DEFAULT: [[SCALAR_PH]]: | |
| ; | |
| ; PRED-LABEL: define void @multiple_exit_conditions( | |
| ; PRED-SAME: ptr [[SRC:%.*]], ptr noalias [[DST:%.*]]) #[[ATTR1:[0-9]+]] { | |
| ; PRED-NEXT: [[ENTRY:.*:]] | |
| ; PRED-NEXT: br label %[[VECTOR_PH:.*]] | |
| ; PRED: [[VECTOR_PH]]: | |
| ; PRED-NEXT: [[TMP6:%.*]] = call i64 @llvm.vscale.i64() | |
| ; PRED-NEXT: [[TMP7:%.*]] = shl nuw i64 [[TMP6]], 1 | |
| ; PRED-NEXT: [[ACTIVE_LANE_MASK_ENTRY:%.*]] = call <vscale x 2 x i1> @llvm.get.active.lane.mask.nxv2i1.i64(i64 0, i64 257) | |
| ; PRED-NEXT: br label %[[VECTOR_BODY:.*]] | |
| ; PRED: [[VECTOR_BODY]]: | |
| ; PRED-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ] | |
| ; PRED-NEXT: [[ACTIVE_LANE_MASK:%.*]] = phi <vscale x 2 x i1> [ [[ACTIVE_LANE_MASK_ENTRY]], %[[VECTOR_PH]] ], [ [[ACTIVE_LANE_MASK_NEXT:%.*]], %[[VECTOR_BODY]] ] | |
| ; PRED-NEXT: [[OFFSET_IDX:%.*]] = shl i64 [[INDEX]], 3 | |
| ; PRED-NEXT: [[NEXT_GEP:%.*]] = getelementptr i8, ptr [[DST]], i64 [[OFFSET_IDX]] | |
| ; PRED-NEXT: [[TMP12:%.*]] = load i16, ptr [[SRC]], align 2 | |
| ; PRED-NEXT: [[TMP11:%.*]] = or i16 [[TMP12]], 1 | |
| ; PRED-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement <vscale x 2 x i16> poison, i16 [[TMP11]], i64 0 | |
| ; PRED-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector <vscale x 2 x i16> [[BROADCAST_SPLATINSERT]], <vscale x 2 x i16> poison, <vscale x 2 x i32> zeroinitializer | |
| ; PRED-NEXT: [[TMP5:%.*]] = uitofp <vscale x 2 x i16> [[BROADCAST_SPLAT]] to <vscale x 2 x double> | |
| ; PRED-NEXT: call void @llvm.masked.store.nxv2f64.p0(<vscale x 2 x double> [[TMP5]], ptr align 8 [[NEXT_GEP]], <vscale x 2 x i1> [[ACTIVE_LANE_MASK]]) | |
| ; PRED-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], [[TMP7]] | |
| ; PRED-NEXT: [[ACTIVE_LANE_MASK_NEXT]] = call <vscale x 2 x i1> @llvm.get.active.lane.mask.nxv2i1.i64(i64 [[INDEX_NEXT]], i64 257) | |
| ; PRED-NEXT: [[TMP15:%.*]] = extractelement <vscale x 2 x i1> [[ACTIVE_LANE_MASK_NEXT]], i64 0 | |
| ; PRED-NEXT: [[TMP16:%.*]] = xor i1 [[TMP15]], true | |
| ; PRED-NEXT: br i1 [[TMP16]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP18:![0-9]+]] | |
| ; PRED: [[MIDDLE_BLOCK]]: | |
| ; PRED-NEXT: br label %[[EXIT:.*]] | |
| ; PRED: [[EXIT]]: | |
| ; PRED-NEXT: ret void | |
| ; | |
| entry: | |
| br label %loop | |
| loop: | |
| %ptr.iv = phi ptr [ %dst, %entry ], [ %ptr.iv.next, %loop ] | |
| %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] | |
| %l = load i16, ptr %src, align 2 | |
| %o = or i16 %l, 1 | |
| %conv = uitofp i16 %o to double | |
| store double %conv, ptr %ptr.iv, align 8 | |
| %iv.next = add nsw i64 %iv, 2 | |
| %ptr.iv.next = getelementptr i8, ptr %ptr.iv, i64 8 | |
| %iv.clamp = and i64 %iv, 4294967294 | |
| %ec = icmp eq i64 %iv.clamp, 512 | |
| br i1 %ec, label %exit, label %loop | |
| exit: | |
| ret void | |
| } | |
| define void @low_trip_count_fold_tail_scalarized_store(ptr %dst) { | |
| ; COMMON-LABEL: define void @low_trip_count_fold_tail_scalarized_store( | |
| ; COMMON-SAME: ptr [[DST:%.*]]) { | |
| ; COMMON-NEXT: [[ENTRY:.*]]: | |
| ; COMMON-NEXT: br label %[[LOOP:.*]] | |
| ; COMMON: [[LOOP]]: | |
| ; COMMON-NEXT: [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ] | |
| ; COMMON-NEXT: [[IV_TRUNC:%.*]] = trunc i64 [[IV]] to i8 | |
| ; COMMON-NEXT: [[GEP:%.*]] = getelementptr i8, ptr [[DST]], i64 [[IV]] | |
| ; COMMON-NEXT: store i8 [[IV_TRUNC]], ptr [[GEP]], align 1 | |
| ; COMMON-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1 | |
| ; COMMON-NEXT: [[EC:%.*]] = icmp eq i64 [[IV_NEXT]], 7 | |
| ; COMMON-NEXT: br i1 [[EC]], label %[[EXIT:.*]], label %[[LOOP]] | |
| ; COMMON: [[EXIT]]: | |
| ; COMMON-NEXT: ret void | |
| ; | |
| entry: | |
| br label %loop | |
| loop: | |
| %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] | |
| %iv.trunc = trunc i64 %iv to i8 | |
| %gep = getelementptr i8, ptr %dst, i64 %iv | |
| store i8 %iv.trunc, ptr %gep, align 1 | |
| %iv.next = add i64 %iv, 1 | |
| %ec = icmp eq i64 %iv.next, 7 | |
| br i1 %ec, label %exit, label %loop | |
| exit: | |
| ret void | |
| } | |
| define void @test_conditional_interleave_group (ptr noalias %src.1, ptr noalias %src.2, ptr noalias %src.3, ptr noalias %src.4, ptr noalias %dst, i64 %N) #2 { | |
| ; DEFAULT-LABEL: define void @test_conditional_interleave_group( | |
| ; DEFAULT-SAME: ptr noalias [[SRC_1:%.*]], ptr noalias [[SRC_2:%.*]], ptr noalias [[SRC_3:%.*]], ptr noalias [[SRC_4:%.*]], ptr noalias [[DST:%.*]], i64 [[N:%.*]]) #[[ATTR2:[0-9]+]] { | |
| ; DEFAULT-NEXT: [[ENTRY:.*:]] | |
| ; DEFAULT-NEXT: [[TMP0:%.*]] = add i64 [[N]], 1 | |
| ; DEFAULT-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[TMP0]], 8 | |
| ; DEFAULT-NEXT: br i1 [[MIN_ITERS_CHECK]], label %[[SCALAR_PH:.*]], label %[[VECTOR_SCEVCHECK:.*]] | |
| ; DEFAULT: [[VECTOR_SCEVCHECK]]: | |
| ; DEFAULT-NEXT: [[MUL:%.*]] = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 16, i64 [[N]]) | |
| ; DEFAULT-NEXT: [[MUL_RESULT:%.*]] = extractvalue { i64, i1 } [[MUL]], 0 | |
| ; DEFAULT-NEXT: [[MUL_OVERFLOW:%.*]] = extractvalue { i64, i1 } [[MUL]], 1 | |
| ; DEFAULT-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[DST]], i64 [[MUL_RESULT]] | |
| ; DEFAULT-NEXT: [[TMP3:%.*]] = icmp ult ptr [[TMP2]], [[DST]] | |
| ; DEFAULT-NEXT: [[TMP4:%.*]] = or i1 [[TMP3]], [[MUL_OVERFLOW]] | |
| ; DEFAULT-NEXT: [[SCEVGEP:%.*]] = getelementptr i8, ptr [[DST]], i64 4 | |
| ; DEFAULT-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[SCEVGEP]], i64 [[MUL_RESULT]] | |
| ; DEFAULT-NEXT: [[TMP7:%.*]] = icmp ult ptr [[TMP6]], [[SCEVGEP]] | |
| ; DEFAULT-NEXT: [[TMP8:%.*]] = or i1 [[TMP7]], [[MUL_OVERFLOW]] | |
| ; DEFAULT-NEXT: [[SCEVGEP4:%.*]] = getelementptr i8, ptr [[DST]], i64 8 | |
| ; DEFAULT-NEXT: [[TMP10:%.*]] = getelementptr i8, ptr [[SCEVGEP4]], i64 [[MUL_RESULT]] | |
| ; DEFAULT-NEXT: [[TMP11:%.*]] = icmp ult ptr [[TMP10]], [[SCEVGEP4]] | |
| ; DEFAULT-NEXT: [[TMP12:%.*]] = or i1 [[TMP11]], [[MUL_OVERFLOW]] | |
| ; DEFAULT-NEXT: [[TMP13:%.*]] = or i1 [[TMP4]], [[TMP8]] | |
| ; DEFAULT-NEXT: [[TMP14:%.*]] = or i1 [[TMP13]], [[TMP12]] | |
| ; DEFAULT-NEXT: br i1 [[TMP14]], label %[[SCALAR_PH]], label %[[VECTOR_PH:.*]] | |
| ; DEFAULT: [[VECTOR_PH]]: | |
| ; DEFAULT-NEXT: [[N_MOD_VF:%.*]] = and i64 [[TMP0]], 7 | |
| ; DEFAULT-NEXT: [[N_VEC:%.*]] = sub i64 [[TMP0]], [[N_MOD_VF]] | |
| ; DEFAULT-NEXT: br label %[[VECTOR_BODY:.*]] | |
| ; DEFAULT: [[VECTOR_BODY]]: | |
| ; DEFAULT-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[PRED_STORE_CONTINUE27:.*]] ] | |
| ; DEFAULT-NEXT: [[VEC_IND:%.*]] = phi <8 x i64> [ <i64 0, i64 1, i64 2, i64 3, i64 4, i64 5, i64 6, i64 7>, %[[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], %[[PRED_STORE_CONTINUE27]] ] | |
| ; DEFAULT-NEXT: [[TMP15:%.*]] = load float, ptr [[SRC_1]], align 4 | |
| ; DEFAULT-NEXT: [[BROADCAST_SPLATINSERT8:%.*]] = insertelement <8 x float> poison, float [[TMP15]], i64 0 | |
| ; DEFAULT-NEXT: [[BROADCAST_SPLAT9:%.*]] = shufflevector <8 x float> [[BROADCAST_SPLATINSERT8]], <8 x float> poison, <8 x i32> zeroinitializer | |
| ; DEFAULT-NEXT: [[TMP16:%.*]] = load float, ptr [[SRC_2]], align 4 | |
| ; DEFAULT-NEXT: [[TMP17:%.*]] = fmul float [[TMP16]], 0.000000e+00 | |
| ; DEFAULT-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement <8 x float> poison, float [[TMP17]], i64 0 | |
| ; DEFAULT-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector <8 x float> [[BROADCAST_SPLATINSERT]], <8 x float> poison, <8 x i32> zeroinitializer | |
| ; DEFAULT-NEXT: [[TMP18:%.*]] = call <8 x float> @llvm.fmuladd.v8f32(<8 x float> [[BROADCAST_SPLAT9]], <8 x float> zeroinitializer, <8 x float> [[BROADCAST_SPLAT]]) | |
| ; DEFAULT-NEXT: [[TMP19:%.*]] = load float, ptr [[SRC_3]], align 4 | |
| ; DEFAULT-NEXT: [[BROADCAST_SPLATINSERT10:%.*]] = insertelement <8 x float> poison, float [[TMP19]], i64 0 | |
| ; DEFAULT-NEXT: [[BROADCAST_SPLAT11:%.*]] = shufflevector <8 x float> [[BROADCAST_SPLATINSERT10]], <8 x float> poison, <8 x i32> zeroinitializer | |
| ; DEFAULT-NEXT: [[TMP20:%.*]] = call <8 x float> @llvm.fmuladd.v8f32(<8 x float> [[BROADCAST_SPLAT11]], <8 x float> zeroinitializer, <8 x float> [[TMP18]]) | |
| ; DEFAULT-NEXT: [[TMP21:%.*]] = load float, ptr [[SRC_3]], align 4 | |
| ; DEFAULT-NEXT: [[BROADCAST_SPLATINSERT12:%.*]] = insertelement <8 x float> poison, float [[TMP21]], i64 0 | |
| ; DEFAULT-NEXT: [[BROADCAST_SPLAT13:%.*]] = shufflevector <8 x float> [[BROADCAST_SPLATINSERT12]], <8 x float> poison, <8 x i32> zeroinitializer | |
| ; DEFAULT-NEXT: [[TMP22:%.*]] = fcmp ogt <8 x float> [[TMP20]], [[BROADCAST_SPLAT13]] | |
| ; DEFAULT-NEXT: [[TMP23:%.*]] = getelementptr { [4 x float] }, ptr [[DST]], <8 x i64> [[VEC_IND]] | |
| ; DEFAULT-NEXT: [[TMP24:%.*]] = extractelement <8 x i1> [[TMP22]], i64 0 | |
| ; DEFAULT-NEXT: br i1 [[TMP24]], label %[[PRED_STORE_IF:.*]], label %[[PRED_STORE_CONTINUE:.*]] | |
| ; DEFAULT: [[PRED_STORE_IF]]: | |
| ; DEFAULT-NEXT: [[TMP25:%.*]] = extractelement <8 x ptr> [[TMP23]], i64 0 | |
| ; DEFAULT-NEXT: store float 0.000000e+00, ptr [[TMP25]], align 4 | |
| ; DEFAULT-NEXT: [[TMP27:%.*]] = getelementptr i8, ptr [[TMP25]], i64 4 | |
| ; DEFAULT-NEXT: store float 0.000000e+00, ptr [[TMP27]], align 4 | |
| ; DEFAULT-NEXT: [[TMP29:%.*]] = getelementptr i8, ptr [[TMP25]], i64 8 | |
| ; DEFAULT-NEXT: store float 0.000000e+00, ptr [[TMP29]], align 4 | |
| ; DEFAULT-NEXT: store float 0.000000e+00, ptr [[TMP25]], align 4 | |
| ; DEFAULT-NEXT: br label %[[PRED_STORE_CONTINUE]] | |
| ; DEFAULT: [[PRED_STORE_CONTINUE]]: | |
| ; DEFAULT-NEXT: [[TMP31:%.*]] = extractelement <8 x i1> [[TMP22]], i64 1 | |
| ; DEFAULT-NEXT: br i1 [[TMP31]], label %[[PRED_STORE_IF14:.*]], label %[[PRED_STORE_CONTINUE15:.*]] | |
| ; DEFAULT: [[PRED_STORE_IF14]]: | |
| ; DEFAULT-NEXT: [[TMP32:%.*]] = extractelement <8 x ptr> [[TMP23]], i64 1 | |
| ; DEFAULT-NEXT: store float 0.000000e+00, ptr [[TMP32]], align 4 | |
| ; DEFAULT-NEXT: [[TMP34:%.*]] = getelementptr i8, ptr [[TMP32]], i64 4 | |
| ; DEFAULT-NEXT: store float 0.000000e+00, ptr [[TMP34]], align 4 | |
| ; DEFAULT-NEXT: [[TMP36:%.*]] = getelementptr i8, ptr [[TMP32]], i64 8 | |
| ; DEFAULT-NEXT: store float 0.000000e+00, ptr [[TMP36]], align 4 | |
| ; DEFAULT-NEXT: store float 0.000000e+00, ptr [[TMP32]], align 4 | |
| ; DEFAULT-NEXT: br label %[[PRED_STORE_CONTINUE15]] | |
| ; DEFAULT: [[PRED_STORE_CONTINUE15]]: | |
| ; DEFAULT-NEXT: [[TMP38:%.*]] = extractelement <8 x i1> [[TMP22]], i64 2 | |
| ; DEFAULT-NEXT: br i1 [[TMP38]], label %[[PRED_STORE_IF16:.*]], label %[[PRED_STORE_CONTINUE17:.*]] | |
| ; DEFAULT: [[PRED_STORE_IF16]]: | |
| ; DEFAULT-NEXT: [[TMP39:%.*]] = extractelement <8 x ptr> [[TMP23]], i64 2 | |
| ; DEFAULT-NEXT: store float 0.000000e+00, ptr [[TMP39]], align 4 | |
| ; DEFAULT-NEXT: [[TMP41:%.*]] = getelementptr i8, ptr [[TMP39]], i64 4 | |
| ; DEFAULT-NEXT: store float 0.000000e+00, ptr [[TMP41]], align 4 | |
| ; DEFAULT-NEXT: [[TMP43:%.*]] = getelementptr i8, ptr [[TMP39]], i64 8 | |
| ; DEFAULT-NEXT: store float 0.000000e+00, ptr [[TMP43]], align 4 | |
| ; DEFAULT-NEXT: store float 0.000000e+00, ptr [[TMP39]], align 4 | |
| ; DEFAULT-NEXT: br label %[[PRED_STORE_CONTINUE17]] | |
| ; DEFAULT: [[PRED_STORE_CONTINUE17]]: | |
| ; DEFAULT-NEXT: [[TMP45:%.*]] = extractelement <8 x i1> [[TMP22]], i64 3 | |
| ; DEFAULT-NEXT: br i1 [[TMP45]], label %[[PRED_STORE_IF18:.*]], label %[[PRED_STORE_CONTINUE19:.*]] | |
| ; DEFAULT: [[PRED_STORE_IF18]]: | |
| ; DEFAULT-NEXT: [[TMP46:%.*]] = extractelement <8 x ptr> [[TMP23]], i64 3 | |
| ; DEFAULT-NEXT: store float 0.000000e+00, ptr [[TMP46]], align 4 | |
| ; DEFAULT-NEXT: [[TMP48:%.*]] = getelementptr i8, ptr [[TMP46]], i64 4 | |
| ; DEFAULT-NEXT: store float 0.000000e+00, ptr [[TMP48]], align 4 | |
| ; DEFAULT-NEXT: [[TMP50:%.*]] = getelementptr i8, ptr [[TMP46]], i64 8 | |
| ; DEFAULT-NEXT: store float 0.000000e+00, ptr [[TMP50]], align 4 | |
| ; DEFAULT-NEXT: store float 0.000000e+00, ptr [[TMP46]], align 4 | |
| ; DEFAULT-NEXT: br label %[[PRED_STORE_CONTINUE19]] | |
| ; DEFAULT: [[PRED_STORE_CONTINUE19]]: | |
| ; DEFAULT-NEXT: [[TMP52:%.*]] = extractelement <8 x i1> [[TMP22]], i64 4 | |
| ; DEFAULT-NEXT: br i1 [[TMP52]], label %[[PRED_STORE_IF20:.*]], label %[[PRED_STORE_CONTINUE21:.*]] | |
| ; DEFAULT: [[PRED_STORE_IF20]]: | |
| ; DEFAULT-NEXT: [[TMP53:%.*]] = extractelement <8 x ptr> [[TMP23]], i64 4 | |
| ; DEFAULT-NEXT: store float 0.000000e+00, ptr [[TMP53]], align 4 | |
| ; DEFAULT-NEXT: [[TMP55:%.*]] = getelementptr i8, ptr [[TMP53]], i64 4 | |
| ; DEFAULT-NEXT: store float 0.000000e+00, ptr [[TMP55]], align 4 | |
| ; DEFAULT-NEXT: [[TMP57:%.*]] = getelementptr i8, ptr [[TMP53]], i64 8 | |
| ; DEFAULT-NEXT: store float 0.000000e+00, ptr [[TMP57]], align 4 | |
| ; DEFAULT-NEXT: store float 0.000000e+00, ptr [[TMP53]], align 4 | |
| ; DEFAULT-NEXT: br label %[[PRED_STORE_CONTINUE21]] | |
| ; DEFAULT: [[PRED_STORE_CONTINUE21]]: | |
| ; DEFAULT-NEXT: [[TMP59:%.*]] = extractelement <8 x i1> [[TMP22]], i64 5 | |
| ; DEFAULT-NEXT: br i1 [[TMP59]], label %[[PRED_STORE_IF22:.*]], label %[[PRED_STORE_CONTINUE23:.*]] | |
| ; DEFAULT: [[PRED_STORE_IF22]]: | |
| ; DEFAULT-NEXT: [[TMP60:%.*]] = extractelement <8 x ptr> [[TMP23]], i64 5 | |
| ; DEFAULT-NEXT: store float 0.000000e+00, ptr [[TMP60]], align 4 | |
| ; DEFAULT-NEXT: [[TMP62:%.*]] = getelementptr i8, ptr [[TMP60]], i64 4 | |
| ; DEFAULT-NEXT: store float 0.000000e+00, ptr [[TMP62]], align 4 | |
| ; DEFAULT-NEXT: [[TMP64:%.*]] = getelementptr i8, ptr [[TMP60]], i64 8 | |
| ; DEFAULT-NEXT: store float 0.000000e+00, ptr [[TMP64]], align 4 | |
| ; DEFAULT-NEXT: store float 0.000000e+00, ptr [[TMP60]], align 4 | |
| ; DEFAULT-NEXT: br label %[[PRED_STORE_CONTINUE23]] | |
| ; DEFAULT: [[PRED_STORE_CONTINUE23]]: | |
| ; DEFAULT-NEXT: [[TMP66:%.*]] = extractelement <8 x i1> [[TMP22]], i64 6 | |
| ; DEFAULT-NEXT: br i1 [[TMP66]], label %[[PRED_STORE_IF24:.*]], label %[[PRED_STORE_CONTINUE25:.*]] | |
| ; DEFAULT: [[PRED_STORE_IF24]]: | |
| ; DEFAULT-NEXT: [[TMP67:%.*]] = extractelement <8 x ptr> [[TMP23]], i64 6 | |
| ; DEFAULT-NEXT: store float 0.000000e+00, ptr [[TMP67]], align 4 | |
| ; DEFAULT-NEXT: [[TMP69:%.*]] = getelementptr i8, ptr [[TMP67]], i64 4 | |
| ; DEFAULT-NEXT: store float 0.000000e+00, ptr [[TMP69]], align 4 | |
| ; DEFAULT-NEXT: [[TMP71:%.*]] = getelementptr i8, ptr [[TMP67]], i64 8 | |
| ; DEFAULT-NEXT: store float 0.000000e+00, ptr [[TMP71]], align 4 | |
| ; DEFAULT-NEXT: store float 0.000000e+00, ptr [[TMP67]], align 4 | |
| ; DEFAULT-NEXT: br label %[[PRED_STORE_CONTINUE25]] | |
| ; DEFAULT: [[PRED_STORE_CONTINUE25]]: | |
| ; DEFAULT-NEXT: [[TMP73:%.*]] = extractelement <8 x i1> [[TMP22]], i64 7 | |
| ; DEFAULT-NEXT: br i1 [[TMP73]], label %[[PRED_STORE_IF26:.*]], label %[[PRED_STORE_CONTINUE27]] | |
| ; DEFAULT: [[PRED_STORE_IF26]]: | |
| ; DEFAULT-NEXT: [[TMP74:%.*]] = extractelement <8 x ptr> [[TMP23]], i64 7 | |
| ; DEFAULT-NEXT: store float 0.000000e+00, ptr [[TMP74]], align 4 | |
| ; DEFAULT-NEXT: [[TMP76:%.*]] = getelementptr i8, ptr [[TMP74]], i64 4 | |
| ; DEFAULT-NEXT: store float 0.000000e+00, ptr [[TMP76]], align 4 | |
| ; DEFAULT-NEXT: [[TMP78:%.*]] = getelementptr i8, ptr [[TMP74]], i64 8 | |
| ; DEFAULT-NEXT: store float 0.000000e+00, ptr [[TMP78]], align 4 | |
| ; DEFAULT-NEXT: store float 0.000000e+00, ptr [[TMP74]], align 4 | |
| ; DEFAULT-NEXT: br label %[[PRED_STORE_CONTINUE27]] | |
| ; DEFAULT: [[PRED_STORE_CONTINUE27]]: | |
| ; DEFAULT-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 8 | |
| ; DEFAULT-NEXT: [[VEC_IND_NEXT]] = add <8 x i64> [[VEC_IND]], splat (i64 8) | |
| ; DEFAULT-NEXT: [[TMP80:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]] | |
| ; DEFAULT-NEXT: br i1 [[TMP80]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP25:![0-9]+]] | |
| ; DEFAULT: [[MIDDLE_BLOCK]]: | |
| ; DEFAULT-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[TMP0]], [[N_VEC]] | |
| ; DEFAULT-NEXT: br i1 [[CMP_N]], [[EXIT:label %.*]], label %[[SCALAR_PH]] | |
| ; DEFAULT: [[SCALAR_PH]]: | |
| ; | |
| ; PRED-LABEL: define void @test_conditional_interleave_group( | |
| ; PRED-SAME: ptr noalias [[SRC_1:%.*]], ptr noalias [[SRC_2:%.*]], ptr noalias [[SRC_3:%.*]], ptr noalias [[SRC_4:%.*]], ptr noalias [[DST:%.*]], i64 [[N:%.*]]) #[[ATTR2:[0-9]+]] { | |
| ; PRED-NEXT: [[ENTRY:.*:]] | |
| ; PRED-NEXT: [[TMP0:%.*]] = add i64 [[N]], 1 | |
| ; PRED-NEXT: br label %[[VECTOR_SCEVCHECK:.*]] | |
| ; PRED: [[VECTOR_SCEVCHECK]]: | |
| ; PRED-NEXT: [[MUL:%.*]] = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 16, i64 [[N]]) | |
| ; PRED-NEXT: [[MUL_RESULT:%.*]] = extractvalue { i64, i1 } [[MUL]], 0 | |
| ; PRED-NEXT: [[MUL_OVERFLOW:%.*]] = extractvalue { i64, i1 } [[MUL]], 1 | |
| ; PRED-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[DST]], i64 [[MUL_RESULT]] | |
| ; PRED-NEXT: [[TMP3:%.*]] = icmp ult ptr [[TMP2]], [[DST]] | |
| ; PRED-NEXT: [[TMP4:%.*]] = or i1 [[TMP3]], [[MUL_OVERFLOW]] | |
| ; PRED-NEXT: [[SCEVGEP:%.*]] = getelementptr i8, ptr [[DST]], i64 4 | |
| ; PRED-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[SCEVGEP]], i64 [[MUL_RESULT]] | |
| ; PRED-NEXT: [[TMP7:%.*]] = icmp ult ptr [[TMP6]], [[SCEVGEP]] | |
| ; PRED-NEXT: [[TMP8:%.*]] = or i1 [[TMP7]], [[MUL_OVERFLOW]] | |
| ; PRED-NEXT: [[SCEVGEP4:%.*]] = getelementptr i8, ptr [[DST]], i64 8 | |
| ; PRED-NEXT: [[TMP10:%.*]] = getelementptr i8, ptr [[SCEVGEP4]], i64 [[MUL_RESULT]] | |
| ; PRED-NEXT: [[TMP11:%.*]] = icmp ult ptr [[TMP10]], [[SCEVGEP4]] | |
| ; PRED-NEXT: [[TMP12:%.*]] = or i1 [[TMP11]], [[MUL_OVERFLOW]] | |
| ; PRED-NEXT: [[TMP13:%.*]] = or i1 [[TMP4]], [[TMP8]] | |
| ; PRED-NEXT: [[TMP14:%.*]] = or i1 [[TMP13]], [[TMP12]] | |
| ; PRED-NEXT: br i1 [[TMP14]], label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]] | |
| ; PRED: [[VECTOR_PH]]: | |
| ; PRED-NEXT: [[ACTIVE_LANE_MASK_ENTRY:%.*]] = call <8 x i1> @llvm.get.active.lane.mask.v8i1.i64(i64 0, i64 [[TMP0]]) | |
| ; PRED-NEXT: br label %[[VECTOR_BODY:.*]] | |
| ; PRED: [[VECTOR_BODY]]: | |
| ; PRED-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[PRED_STORE_CONTINUE27:.*]] ] | |
| ; PRED-NEXT: [[ACTIVE_LANE_MASK:%.*]] = phi <8 x i1> [ [[ACTIVE_LANE_MASK_ENTRY]], %[[VECTOR_PH]] ], [ [[ACTIVE_LANE_MASK_NEXT:%.*]], %[[PRED_STORE_CONTINUE27]] ] | |
| ; PRED-NEXT: [[VEC_IND:%.*]] = phi <8 x i64> [ <i64 0, i64 1, i64 2, i64 3, i64 4, i64 5, i64 6, i64 7>, %[[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], %[[PRED_STORE_CONTINUE27]] ] | |
| ; PRED-NEXT: [[TMP18:%.*]] = load float, ptr [[SRC_1]], align 4 | |
| ; PRED-NEXT: [[BROADCAST_SPLATINSERT8:%.*]] = insertelement <8 x float> poison, float [[TMP18]], i64 0 | |
| ; PRED-NEXT: [[BROADCAST_SPLAT9:%.*]] = shufflevector <8 x float> [[BROADCAST_SPLATINSERT8]], <8 x float> poison, <8 x i32> zeroinitializer | |
| ; PRED-NEXT: [[TMP19:%.*]] = load float, ptr [[SRC_2]], align 4 | |
| ; PRED-NEXT: [[TMP20:%.*]] = fmul float [[TMP19]], 0.000000e+00 | |
| ; PRED-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement <8 x float> poison, float [[TMP20]], i64 0 | |
| ; PRED-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector <8 x float> [[BROADCAST_SPLATINSERT]], <8 x float> poison, <8 x i32> zeroinitializer | |
| ; PRED-NEXT: [[TMP21:%.*]] = call <8 x float> @llvm.fmuladd.v8f32(<8 x float> [[BROADCAST_SPLAT9]], <8 x float> zeroinitializer, <8 x float> [[BROADCAST_SPLAT]]) | |
| ; PRED-NEXT: [[TMP22:%.*]] = load float, ptr [[SRC_3]], align 4 | |
| ; PRED-NEXT: [[BROADCAST_SPLATINSERT10:%.*]] = insertelement <8 x float> poison, float [[TMP22]], i64 0 | |
| ; PRED-NEXT: [[BROADCAST_SPLAT11:%.*]] = shufflevector <8 x float> [[BROADCAST_SPLATINSERT10]], <8 x float> poison, <8 x i32> zeroinitializer | |
| ; PRED-NEXT: [[TMP23:%.*]] = call <8 x float> @llvm.fmuladd.v8f32(<8 x float> [[BROADCAST_SPLAT11]], <8 x float> zeroinitializer, <8 x float> [[TMP21]]) | |
| ; PRED-NEXT: [[TMP24:%.*]] = load float, ptr [[SRC_3]], align 4 | |
| ; PRED-NEXT: [[BROADCAST_SPLATINSERT12:%.*]] = insertelement <8 x float> poison, float [[TMP24]], i64 0 | |
| ; PRED-NEXT: [[BROADCAST_SPLAT13:%.*]] = shufflevector <8 x float> [[BROADCAST_SPLATINSERT12]], <8 x float> poison, <8 x i32> zeroinitializer | |
| ; PRED-NEXT: [[TMP25:%.*]] = fcmp ogt <8 x float> [[TMP23]], [[BROADCAST_SPLAT13]] | |
| ; PRED-NEXT: [[TMP26:%.*]] = select <8 x i1> [[ACTIVE_LANE_MASK]], <8 x i1> [[TMP25]], <8 x i1> zeroinitializer | |
| ; PRED-NEXT: [[TMP27:%.*]] = getelementptr { [4 x float] }, ptr [[DST]], <8 x i64> [[VEC_IND]] | |
| ; PRED-NEXT: [[TMP28:%.*]] = extractelement <8 x i1> [[TMP26]], i64 0 | |
| ; PRED-NEXT: br i1 [[TMP28]], label %[[PRED_STORE_IF:.*]], label %[[PRED_STORE_CONTINUE:.*]] | |
| ; PRED: [[PRED_STORE_IF]]: | |
| ; PRED-NEXT: [[TMP29:%.*]] = extractelement <8 x ptr> [[TMP27]], i64 0 | |
| ; PRED-NEXT: store float 0.000000e+00, ptr [[TMP29]], align 4 | |
| ; PRED-NEXT: [[TMP31:%.*]] = getelementptr i8, ptr [[TMP29]], i64 4 | |
| ; PRED-NEXT: store float 0.000000e+00, ptr [[TMP31]], align 4 | |
| ; PRED-NEXT: [[TMP33:%.*]] = getelementptr i8, ptr [[TMP29]], i64 8 | |
| ; PRED-NEXT: store float 0.000000e+00, ptr [[TMP33]], align 4 | |
| ; PRED-NEXT: store float 0.000000e+00, ptr [[TMP29]], align 4 | |
| ; PRED-NEXT: br label %[[PRED_STORE_CONTINUE]] | |
| ; PRED: [[PRED_STORE_CONTINUE]]: | |
| ; PRED-NEXT: [[TMP35:%.*]] = extractelement <8 x i1> [[TMP26]], i64 1 | |
| ; PRED-NEXT: br i1 [[TMP35]], label %[[PRED_STORE_IF14:.*]], label %[[PRED_STORE_CONTINUE15:.*]] | |
| ; PRED: [[PRED_STORE_IF14]]: | |
| ; PRED-NEXT: [[TMP36:%.*]] = extractelement <8 x ptr> [[TMP27]], i64 1 | |
| ; PRED-NEXT: store float 0.000000e+00, ptr [[TMP36]], align 4 | |
| ; PRED-NEXT: [[TMP38:%.*]] = getelementptr i8, ptr [[TMP36]], i64 4 | |
| ; PRED-NEXT: store float 0.000000e+00, ptr [[TMP38]], align 4 | |
| ; PRED-NEXT: [[TMP40:%.*]] = getelementptr i8, ptr [[TMP36]], i64 8 | |
| ; PRED-NEXT: store float 0.000000e+00, ptr [[TMP40]], align 4 | |
| ; PRED-NEXT: store float 0.000000e+00, ptr [[TMP36]], align 4 | |
| ; PRED-NEXT: br label %[[PRED_STORE_CONTINUE15]] | |
| ; PRED: [[PRED_STORE_CONTINUE15]]: | |
| ; PRED-NEXT: [[TMP42:%.*]] = extractelement <8 x i1> [[TMP26]], i64 2 | |
| ; PRED-NEXT: br i1 [[TMP42]], label %[[PRED_STORE_IF16:.*]], label %[[PRED_STORE_CONTINUE17:.*]] | |
| ; PRED: [[PRED_STORE_IF16]]: | |
| ; PRED-NEXT: [[TMP43:%.*]] = extractelement <8 x ptr> [[TMP27]], i64 2 | |
| ; PRED-NEXT: store float 0.000000e+00, ptr [[TMP43]], align 4 | |
| ; PRED-NEXT: [[TMP45:%.*]] = getelementptr i8, ptr [[TMP43]], i64 4 | |
| ; PRED-NEXT: store float 0.000000e+00, ptr [[TMP45]], align 4 | |
| ; PRED-NEXT: [[TMP47:%.*]] = getelementptr i8, ptr [[TMP43]], i64 8 | |
| ; PRED-NEXT: store float 0.000000e+00, ptr [[TMP47]], align 4 | |
| ; PRED-NEXT: store float 0.000000e+00, ptr [[TMP43]], align 4 | |
| ; PRED-NEXT: br label %[[PRED_STORE_CONTINUE17]] | |
| ; PRED: [[PRED_STORE_CONTINUE17]]: | |
| ; PRED-NEXT: [[TMP49:%.*]] = extractelement <8 x i1> [[TMP26]], i64 3 | |
| ; PRED-NEXT: br i1 [[TMP49]], label %[[PRED_STORE_IF18:.*]], label %[[PRED_STORE_CONTINUE19:.*]] | |
| ; PRED: [[PRED_STORE_IF18]]: | |
| ; PRED-NEXT: [[TMP50:%.*]] = extractelement <8 x ptr> [[TMP27]], i64 3 | |
| ; PRED-NEXT: store float 0.000000e+00, ptr [[TMP50]], align 4 | |
| ; PRED-NEXT: [[TMP52:%.*]] = getelementptr i8, ptr [[TMP50]], i64 4 | |
| ; PRED-NEXT: store float 0.000000e+00, ptr [[TMP52]], align 4 | |
| ; PRED-NEXT: [[TMP54:%.*]] = getelementptr i8, ptr [[TMP50]], i64 8 | |
| ; PRED-NEXT: store float 0.000000e+00, ptr [[TMP54]], align 4 | |
| ; PRED-NEXT: store float 0.000000e+00, ptr [[TMP50]], align 4 | |
| ; PRED-NEXT: br label %[[PRED_STORE_CONTINUE19]] | |
| ; PRED: [[PRED_STORE_CONTINUE19]]: | |
| ; PRED-NEXT: [[TMP56:%.*]] = extractelement <8 x i1> [[TMP26]], i64 4 | |
| ; PRED-NEXT: br i1 [[TMP56]], label %[[PRED_STORE_IF20:.*]], label %[[PRED_STORE_CONTINUE21:.*]] | |
| ; PRED: [[PRED_STORE_IF20]]: | |
| ; PRED-NEXT: [[TMP57:%.*]] = extractelement <8 x ptr> [[TMP27]], i64 4 | |
| ; PRED-NEXT: store float 0.000000e+00, ptr [[TMP57]], align 4 | |
| ; PRED-NEXT: [[TMP59:%.*]] = getelementptr i8, ptr [[TMP57]], i64 4 | |
| ; PRED-NEXT: store float 0.000000e+00, ptr [[TMP59]], align 4 | |
| ; PRED-NEXT: [[TMP61:%.*]] = getelementptr i8, ptr [[TMP57]], i64 8 | |
| ; PRED-NEXT: store float 0.000000e+00, ptr [[TMP61]], align 4 | |
| ; PRED-NEXT: store float 0.000000e+00, ptr [[TMP57]], align 4 | |
| ; PRED-NEXT: br label %[[PRED_STORE_CONTINUE21]] | |
| ; PRED: [[PRED_STORE_CONTINUE21]]: | |
| ; PRED-NEXT: [[TMP63:%.*]] = extractelement <8 x i1> [[TMP26]], i64 5 | |
| ; PRED-NEXT: br i1 [[TMP63]], label %[[PRED_STORE_IF22:.*]], label %[[PRED_STORE_CONTINUE23:.*]] | |
| ; PRED: [[PRED_STORE_IF22]]: | |
| ; PRED-NEXT: [[TMP64:%.*]] = extractelement <8 x ptr> [[TMP27]], i64 5 | |
| ; PRED-NEXT: store float 0.000000e+00, ptr [[TMP64]], align 4 | |
| ; PRED-NEXT: [[TMP66:%.*]] = getelementptr i8, ptr [[TMP64]], i64 4 | |
| ; PRED-NEXT: store float 0.000000e+00, ptr [[TMP66]], align 4 | |
| ; PRED-NEXT: [[TMP68:%.*]] = getelementptr i8, ptr [[TMP64]], i64 8 | |
| ; PRED-NEXT: store float 0.000000e+00, ptr [[TMP68]], align 4 | |
| ; PRED-NEXT: store float 0.000000e+00, ptr [[TMP64]], align 4 | |
| ; PRED-NEXT: br label %[[PRED_STORE_CONTINUE23]] | |
| ; PRED: [[PRED_STORE_CONTINUE23]]: | |
| ; PRED-NEXT: [[TMP70:%.*]] = extractelement <8 x i1> [[TMP26]], i64 6 | |
| ; PRED-NEXT: br i1 [[TMP70]], label %[[PRED_STORE_IF24:.*]], label %[[PRED_STORE_CONTINUE25:.*]] | |
| ; PRED: [[PRED_STORE_IF24]]: | |
| ; PRED-NEXT: [[TMP71:%.*]] = extractelement <8 x ptr> [[TMP27]], i64 6 | |
| ; PRED-NEXT: store float 0.000000e+00, ptr [[TMP71]], align 4 | |
| ; PRED-NEXT: [[TMP73:%.*]] = getelementptr i8, ptr [[TMP71]], i64 4 | |
| ; PRED-NEXT: store float 0.000000e+00, ptr [[TMP73]], align 4 | |
| ; PRED-NEXT: [[TMP75:%.*]] = getelementptr i8, ptr [[TMP71]], i64 8 | |
| ; PRED-NEXT: store float 0.000000e+00, ptr [[TMP75]], align 4 | |
| ; PRED-NEXT: store float 0.000000e+00, ptr [[TMP71]], align 4 | |
| ; PRED-NEXT: br label %[[PRED_STORE_CONTINUE25]] | |
| ; PRED: [[PRED_STORE_CONTINUE25]]: | |
| ; PRED-NEXT: [[TMP77:%.*]] = extractelement <8 x i1> [[TMP26]], i64 7 | |
| ; PRED-NEXT: br i1 [[TMP77]], label %[[PRED_STORE_IF26:.*]], label %[[PRED_STORE_CONTINUE27]] | |
| ; PRED: [[PRED_STORE_IF26]]: | |
| ; PRED-NEXT: [[TMP78:%.*]] = extractelement <8 x ptr> [[TMP27]], i64 7 | |
| ; PRED-NEXT: store float 0.000000e+00, ptr [[TMP78]], align 4 | |
| ; PRED-NEXT: [[TMP80:%.*]] = getelementptr i8, ptr [[TMP78]], i64 4 | |
| ; PRED-NEXT: store float 0.000000e+00, ptr [[TMP80]], align 4 | |
| ; PRED-NEXT: [[TMP82:%.*]] = getelementptr i8, ptr [[TMP78]], i64 8 | |
| ; PRED-NEXT: store float 0.000000e+00, ptr [[TMP82]], align 4 | |
| ; PRED-NEXT: store float 0.000000e+00, ptr [[TMP78]], align 4 | |
| ; PRED-NEXT: br label %[[PRED_STORE_CONTINUE27]] | |
| ; PRED: [[PRED_STORE_CONTINUE27]]: | |
| ; PRED-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 8 | |
| ; PRED-NEXT: [[ACTIVE_LANE_MASK_NEXT]] = call <8 x i1> @llvm.get.active.lane.mask.v8i1.i64(i64 [[INDEX_NEXT]], i64 [[TMP0]]) | |
| ; PRED-NEXT: [[TMP84:%.*]] = extractelement <8 x i1> [[ACTIVE_LANE_MASK_NEXT]], i64 0 | |
| ; PRED-NEXT: [[TMP85:%.*]] = xor i1 [[TMP84]], true | |
| ; PRED-NEXT: [[VEC_IND_NEXT]] = add <8 x i64> [[VEC_IND]], splat (i64 8) | |
| ; PRED-NEXT: br i1 [[TMP85]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP19:![0-9]+]] | |
| ; PRED: [[MIDDLE_BLOCK]]: | |
| ; PRED-NEXT: br [[EXIT:label %.*]] | |
| ; PRED: [[SCALAR_PH]]: | |
| ; | |
| entry: | |
| br label %loop.header | |
| loop.header: | |
| %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ] | |
| %0 = load float, ptr %src.1, align 4 | |
| %1 = load float, ptr %src.2, align 4 | |
| %mul8.i.us = fmul float %1, 0.000000e+00 | |
| %2 = tail call float @llvm.fmuladd.f32(float %0, float 0.000000e+00, float %mul8.i.us) | |
| %3 = load float, ptr %src.3, align 4 | |
| %4 = tail call float @llvm.fmuladd.f32(float %3, float 0.000000e+00, float %2) | |
| %5 = load float, ptr %src.3, align 4 | |
| %c = fcmp ogt float %4, %5 | |
| br i1 %c, label %if.then, label %loop.latch | |
| if.then: | |
| %dst.0 = getelementptr { [4 x float] }, ptr %dst, i64 %iv | |
| store float 0.000000e+00, ptr %dst.0, align 4 | |
| %dst.1 = getelementptr i8, ptr %dst.0, i64 4 | |
| store float 0.000000e+00, ptr %dst.1, align 4 | |
| %dst.2 = getelementptr i8, ptr %dst.0, i64 8 | |
| store float 0.000000e+00, ptr %dst.2, align 4 | |
| %dst.3 = getelementptr i8, ptr %dst.0, i64 16 | |
| store float 0.000000e+00, ptr %dst.0, align 4 | |
| br label %loop.latch | |
| loop.latch: | |
| %iv.next = add i64 %iv, 1 | |
| %ec = icmp eq i64 %iv, %N | |
| br i1 %ec, label %exit, label %loop.header, !llvm.loop !0 | |
| exit: | |
| ret void | |
| } | |
| define void @redundant_branch_and_tail_folding(ptr %dst, i1 %c) { | |
| ; DEFAULT-LABEL: define void @redundant_branch_and_tail_folding( | |
| ; DEFAULT-SAME: ptr [[DST:%.*]], i1 [[C:%.*]]) { | |
| ; DEFAULT-NEXT: [[ENTRY:.*:]] | |
| ; DEFAULT-NEXT: br label %[[VECTOR_PH:.*]] | |
| ; DEFAULT: [[VECTOR_PH]]: | |
| ; DEFAULT-NEXT: br label %[[VECTOR_BODY:.*]] | |
| ; DEFAULT: [[VECTOR_BODY]]: | |
| ; DEFAULT-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ] | |
| ; DEFAULT-NEXT: [[VEC_IND:%.*]] = phi <4 x i64> [ <i64 0, i64 1, i64 2, i64 3>, %[[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], %[[VECTOR_BODY]] ] | |
| ; DEFAULT-NEXT: [[STEP_ADD:%.*]] = add nuw <4 x i64> [[VEC_IND]], splat (i64 4) | |
| ; DEFAULT-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 8 | |
| ; DEFAULT-NEXT: [[VEC_IND_NEXT]] = add nuw nsw <4 x i64> [[STEP_ADD]], splat (i64 4) | |
| ; DEFAULT-NEXT: [[TMP3:%.*]] = icmp eq i64 [[INDEX_NEXT]], 16 | |
| ; DEFAULT-NEXT: br i1 [[TMP3]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP27:![0-9]+]] | |
| ; DEFAULT: [[MIDDLE_BLOCK]]: | |
| ; DEFAULT-NEXT: [[TMP1:%.*]] = add nuw nsw <4 x i64> [[STEP_ADD]], splat (i64 1) | |
| ; DEFAULT-NEXT: [[TMP2:%.*]] = trunc nuw nsw <4 x i64> [[TMP1]] to <4 x i32> | |
| ; DEFAULT-NEXT: [[TMP4:%.*]] = extractelement <4 x i32> [[TMP2]], i64 3 | |
| ; DEFAULT-NEXT: store i32 [[TMP4]], ptr [[DST]], align 4 | |
| ; DEFAULT-NEXT: br label %[[SCALAR_PH:.*]] | |
| ; DEFAULT: [[SCALAR_PH]]: | |
| ; | |
| ; PRED-LABEL: define void @redundant_branch_and_tail_folding( | |
| ; PRED-SAME: ptr [[DST:%.*]], i1 [[C:%.*]]) { | |
| ; PRED-NEXT: [[PRED_STORE_IF:.*]]: | |
| ; PRED-NEXT: br label %[[PRED_STORE_CONTINUE:.*]] | |
| ; PRED: [[PRED_STORE_CONTINUE]]: | |
| ; PRED-NEXT: [[IV:%.*]] = phi i64 [ 0, %[[PRED_STORE_IF]] ], [ [[IV_NEXT:%.*]], %[[PRED_STORE_CONTINUE2:.*]] ] | |
| ; PRED-NEXT: br i1 [[C]], label %[[PRED_STORE_CONTINUE2]], label %[[PRED_STORE_IF1:.*]] | |
| ; PRED: [[PRED_STORE_IF1]]: | |
| ; PRED-NEXT: br label %[[PRED_STORE_CONTINUE2]] | |
| ; PRED: [[PRED_STORE_CONTINUE2]]: | |
| ; PRED-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1 | |
| ; PRED-NEXT: [[TMP8:%.*]] = trunc nuw nsw i64 [[IV_NEXT]] to i32 | |
| ; PRED-NEXT: store i32 [[TMP8]], ptr [[DST]], align 4 | |
| ; PRED-NEXT: [[EC:%.*]] = icmp eq i64 [[IV_NEXT]], 21 | |
| ; PRED-NEXT: br i1 [[EC]], label %[[EXIT:.*]], label %[[PRED_STORE_CONTINUE]] | |
| ; PRED: [[EXIT]]: | |
| ; PRED-NEXT: ret void | |
| ; | |
| entry: | |
| br label %loop.header | |
| loop.header: | |
| %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ] | |
| br i1 %c, label %loop.latch, label %then | |
| then: | |
| br label %loop.latch | |
| loop.latch: | |
| %iv.next = add nuw nsw i64 %iv, 1 | |
| %t = trunc nuw nsw i64 %iv.next to i32 | |
| store i32 %t, ptr %dst, align 4 | |
| %ec = icmp eq i64 %iv.next, 21 | |
| br i1 %ec, label %exit, label %loop.header | |
| exit: | |
| ret void | |
| } | |
| define double @test_cond_intrinsics(ptr %A, i1 %c) { | |
| ; COMMON-LABEL: define double @test_cond_intrinsics( | |
| ; COMMON-SAME: ptr [[A:%.*]], i1 [[C:%.*]]) { | |
| ; COMMON-NEXT: [[ENTRY:.*]]: | |
| ; COMMON-NEXT: br label %[[LOOP_HEADER:.*]] | |
| ; COMMON: [[LOOP_HEADER]]: | |
| ; COMMON-NEXT: [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ] | |
| ; COMMON-NEXT: br i1 [[C]], label %[[THEN:.*]], label %[[LOOP_LATCH]] | |
| ; COMMON: [[THEN]]: | |
| ; COMMON-NEXT: [[GEP:%.*]] = getelementptr inbounds double, ptr [[A]], i64 [[IV]] | |
| ; COMMON-NEXT: [[L:%.*]] = load double, ptr [[GEP]], align 8 | |
| ; COMMON-NEXT: [[POW:%.*]] = tail call double @llvm.pow.f64(double 2.000000e+00, double [[L]]) | |
| ; COMMON-NEXT: store double [[POW]], ptr [[GEP]], align 8 | |
| ; COMMON-NEXT: br label %[[LOOP_LATCH]] | |
| ; COMMON: [[LOOP_LATCH]]: | |
| ; COMMON-NEXT: [[P:%.*]] = phi double [ 0.000000e+00, %[[LOOP_HEADER]] ], [ [[POW]], %[[THEN]] ] | |
| ; COMMON-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1 | |
| ; COMMON-NEXT: [[EC:%.*]] = icmp eq i64 [[IV]], 1024 | |
| ; COMMON-NEXT: br i1 [[EC]], label %[[EXIT:.*]], label %[[LOOP_HEADER]] | |
| ; COMMON: [[EXIT]]: | |
| ; COMMON-NEXT: [[P_LCSSA:%.*]] = phi double [ [[P]], %[[LOOP_LATCH]] ] | |
| ; COMMON-NEXT: ret double [[P_LCSSA]] | |
| ; | |
| entry: | |
| br label %loop.header | |
| loop.header: | |
| %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ] | |
| br i1 %c, label %then, label %loop.latch | |
| then: | |
| %gep = getelementptr inbounds double, ptr %A, i64 %iv | |
| %l = load double, ptr %gep, align 8 | |
| %pow = tail call double @llvm.pow.f64(double 2.0, double %l) | |
| store double %pow, ptr %gep | |
| br label %loop.latch | |
| loop.latch: | |
| %p = phi double [ 0.000000e+00, %loop.header ], [ %pow, %then ] | |
| %iv.next = add i64 %iv, 1 | |
| %ec = icmp eq i64 %iv, 1024 | |
| br i1 %ec, label %exit, label %loop.header | |
| exit: | |
| ret double %p | |
| } | |
| define void @pred_udiv_select_cost(ptr %A, ptr %B, ptr %C, i64 %n, i8 %y) #1 { | |
| ; DEFAULT-LABEL: define void @pred_udiv_select_cost( | |
| ; DEFAULT-SAME: ptr [[A:%.*]], ptr [[B:%.*]], ptr [[C:%.*]], i64 [[N:%.*]], i8 [[Y:%.*]]) #[[ATTR1]] { | |
| ; DEFAULT-NEXT: [[ENTRY:.*:]] | |
| ; DEFAULT-NEXT: [[B3:%.*]] = ptrtoaddr ptr [[B]] to i64 | |
| ; DEFAULT-NEXT: [[A2:%.*]] = ptrtoaddr ptr [[A]] to i64 | |
| ; DEFAULT-NEXT: [[C1:%.*]] = ptrtoaddr ptr [[C]] to i64 | |
| ; DEFAULT-NEXT: [[TMP0:%.*]] = add i64 [[N]], 1 | |
| ; DEFAULT-NEXT: [[TMP1:%.*]] = call i64 @llvm.vscale.i64() | |
| ; DEFAULT-NEXT: [[TMP2:%.*]] = shl nuw i64 [[TMP1]], 2 | |
| ; DEFAULT-NEXT: [[TMP3:%.*]] = call i64 @llvm.umax.i64(i64 [[TMP2]], i64 8) | |
| ; DEFAULT-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[TMP0]], [[TMP3]] | |
| ; DEFAULT-NEXT: br i1 [[MIN_ITERS_CHECK]], label %[[SCALAR_PH:.*]], label %[[VECTOR_MEMCHECK:.*]] | |
| ; DEFAULT: [[VECTOR_MEMCHECK]]: | |
| ; DEFAULT-NEXT: [[TMP4:%.*]] = call i64 @llvm.vscale.i64() | |
| ; DEFAULT-NEXT: [[TMP5:%.*]] = shl i64 [[TMP4]], 2 | |
| ; DEFAULT-NEXT: [[TMP8:%.*]] = add i64 [[TMP5]], -1 | |
| ; DEFAULT-NEXT: [[TMP6:%.*]] = sub i64 [[C1]], [[A2]] | |
| ; DEFAULT-NEXT: [[TMP11:%.*]] = sub i64 [[TMP6]], 1 | |
| ; DEFAULT-NEXT: [[DIFF_CHECK:%.*]] = icmp ult i64 [[TMP11]], [[TMP8]] | |
| ; DEFAULT-NEXT: [[TMP7:%.*]] = sub i64 [[C1]], [[B3]] | |
| ; DEFAULT-NEXT: [[TMP13:%.*]] = sub i64 [[TMP7]], 1 | |
| ; DEFAULT-NEXT: [[DIFF_CHECK4:%.*]] = icmp ult i64 [[TMP13]], [[TMP8]] | |
| ; DEFAULT-NEXT: [[CONFLICT_RDX:%.*]] = or i1 [[DIFF_CHECK]], [[DIFF_CHECK4]] | |
| ; DEFAULT-NEXT: br i1 [[CONFLICT_RDX]], label %[[SCALAR_PH]], label %[[VECTOR_PH1:.*]] | |
| ; DEFAULT: [[VECTOR_PH1]]: | |
| ; DEFAULT-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[TMP0]], [[TMP2]] | |
| ; DEFAULT-NEXT: [[N_VEC:%.*]] = sub i64 [[TMP0]], [[N_MOD_VF]] | |
| ; DEFAULT-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement <vscale x 4 x i8> poison, i8 [[Y]], i64 0 | |
| ; DEFAULT-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector <vscale x 4 x i8> [[BROADCAST_SPLATINSERT]], <vscale x 4 x i8> poison, <vscale x 4 x i32> zeroinitializer | |
| ; DEFAULT-NEXT: br label %[[VECTOR_BODY:.*]] | |
| ; DEFAULT: [[VECTOR_BODY]]: | |
| ; DEFAULT-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH1]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ] | |
| ; DEFAULT-NEXT: [[TMP10:%.*]] = getelementptr i8, ptr [[A]], i64 [[INDEX]] | |
| ; DEFAULT-NEXT: [[WIDE_LOAD8:%.*]] = load <vscale x 4 x i8>, ptr [[TMP10]], align 1 | |
| ; DEFAULT-NEXT: [[TMP91:%.*]] = uitofp <vscale x 4 x i8> [[WIDE_LOAD8]] to <vscale x 4 x float> | |
| ; DEFAULT-NEXT: [[TMP12:%.*]] = getelementptr i8, ptr [[B]], i64 [[INDEX]] | |
| ; DEFAULT-NEXT: [[WIDE_LOAD12:%.*]] = load <vscale x 4 x i8>, ptr [[TMP12]], align 1 | |
| ; DEFAULT-NEXT: [[TMP32:%.*]] = icmp ne <vscale x 4 x i8> [[WIDE_LOAD12]], zeroinitializer | |
| ; DEFAULT-NEXT: [[TMP36:%.*]] = xor <vscale x 4 x i8> [[WIDE_LOAD8]], splat (i8 1) | |
| ; DEFAULT-NEXT: [[TMP40:%.*]] = call <vscale x 4 x i8> @llvm.masked.udiv.nxv4i8(<vscale x 4 x i8> [[TMP36]], <vscale x 4 x i8> [[BROADCAST_SPLAT]], <vscale x 4 x i1> [[TMP32]]) | |
| ; DEFAULT-NEXT: [[TMP44:%.*]] = icmp ugt <vscale x 4 x i8> [[TMP40]], splat (i8 1) | |
| ; DEFAULT-NEXT: [[TMP48:%.*]] = select <vscale x 4 x i1> [[TMP44]], <vscale x 4 x i32> zeroinitializer, <vscale x 4 x i32> splat (i32 255) | |
| ; DEFAULT-NEXT: [[PREDPHI15:%.*]] = select <vscale x 4 x i1> [[TMP32]], <vscale x 4 x i32> [[TMP48]], <vscale x 4 x i32> zeroinitializer | |
| ; DEFAULT-NEXT: [[TMP52:%.*]] = zext <vscale x 4 x i8> [[WIDE_LOAD8]] to <vscale x 4 x i32> | |
| ; DEFAULT-NEXT: [[TMP56:%.*]] = sub <vscale x 4 x i32> [[PREDPHI15]], [[TMP52]] | |
| ; DEFAULT-NEXT: [[TMP60:%.*]] = sitofp <vscale x 4 x i32> [[TMP56]] to <vscale x 4 x float> | |
| ; DEFAULT-NEXT: [[TMP64:%.*]] = call <vscale x 4 x float> @llvm.fmuladd.nxv4f32(<vscale x 4 x float> [[TMP60]], <vscale x 4 x float> splat (float 3.000000e+00), <vscale x 4 x float> [[TMP91]]) | |
| ; DEFAULT-NEXT: [[TMP68:%.*]] = fptoui <vscale x 4 x float> [[TMP64]] to <vscale x 4 x i8> | |
| ; DEFAULT-NEXT: [[TMP24:%.*]] = getelementptr i8, ptr [[C]], i64 [[INDEX]] | |
| ; DEFAULT-NEXT: store <vscale x 4 x i8> [[TMP68]], ptr [[TMP24]], align 1 | |
| ; DEFAULT-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], [[TMP2]] | |
| ; DEFAULT-NEXT: [[TMP25:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]] | |
| ; DEFAULT-NEXT: br i1 [[TMP25]], label %[[VEC_EPILOG_MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP29:![0-9]+]] | |
| ; DEFAULT: [[VEC_EPILOG_MIDDLE_BLOCK]]: | |
| ; DEFAULT-NEXT: [[CMP_N25:%.*]] = icmp eq i64 [[TMP0]], [[N_VEC]] | |
| ; DEFAULT-NEXT: br i1 [[CMP_N25]], [[EXIT:label %.*]], label %[[SCALAR_PH]] | |
| ; DEFAULT: [[SCALAR_PH]]: | |
| ; | |
| ; PRED-LABEL: define void @pred_udiv_select_cost( | |
| ; PRED-SAME: ptr [[A:%.*]], ptr [[B:%.*]], ptr [[C:%.*]], i64 [[N:%.*]], i8 [[Y:%.*]]) #[[ATTR1]] { | |
| ; PRED-NEXT: [[ENTRY:.*:]] | |
| ; PRED-NEXT: [[B3:%.*]] = ptrtoaddr ptr [[B]] to i64 | |
| ; PRED-NEXT: [[A2:%.*]] = ptrtoaddr ptr [[A]] to i64 | |
| ; PRED-NEXT: [[C1:%.*]] = ptrtoaddr ptr [[C]] to i64 | |
| ; PRED-NEXT: [[TMP0:%.*]] = add i64 [[N]], 1 | |
| ; PRED-NEXT: br label %[[VECTOR_MEMCHECK:.*]] | |
| ; PRED: [[VECTOR_MEMCHECK]]: | |
| ; PRED-NEXT: [[TMP1:%.*]] = call i64 @llvm.vscale.i64() | |
| ; PRED-NEXT: [[TMP2:%.*]] = shl i64 [[TMP1]], 2 | |
| ; PRED-NEXT: [[TMP5:%.*]] = add i64 [[TMP2]], -1 | |
| ; PRED-NEXT: [[TMP3:%.*]] = sub i64 [[C1]], [[A2]] | |
| ; PRED-NEXT: [[TMP6:%.*]] = sub i64 [[TMP3]], 1 | |
| ; PRED-NEXT: [[DIFF_CHECK:%.*]] = icmp ult i64 [[TMP6]], [[TMP5]] | |
| ; PRED-NEXT: [[TMP4:%.*]] = sub i64 [[C1]], [[B3]] | |
| ; PRED-NEXT: [[TMP23:%.*]] = sub i64 [[TMP4]], 1 | |
| ; PRED-NEXT: [[DIFF_CHECK4:%.*]] = icmp ult i64 [[TMP23]], [[TMP5]] | |
| ; PRED-NEXT: [[CONFLICT_RDX:%.*]] = or i1 [[DIFF_CHECK]], [[DIFF_CHECK4]] | |
| ; PRED-NEXT: br i1 [[CONFLICT_RDX]], label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]] | |
| ; PRED: [[VECTOR_PH]]: | |
| ; PRED-NEXT: [[TMP7:%.*]] = call i64 @llvm.vscale.i64() | |
| ; PRED-NEXT: [[TMP8:%.*]] = shl nuw i64 [[TMP7]], 2 | |
| ; PRED-NEXT: [[ACTIVE_LANE_MASK_ENTRY:%.*]] = call <vscale x 4 x i1> @llvm.get.active.lane.mask.nxv4i1.i64(i64 0, i64 [[TMP0]]) | |
| ; PRED-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement <vscale x 4 x i8> poison, i8 [[Y]], i64 0 | |
| ; PRED-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector <vscale x 4 x i8> [[BROADCAST_SPLATINSERT]], <vscale x 4 x i8> poison, <vscale x 4 x i32> zeroinitializer | |
| ; PRED-NEXT: br label %[[VECTOR_BODY:.*]] | |
| ; PRED: [[VECTOR_BODY]]: | |
| ; PRED-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ] | |
| ; PRED-NEXT: [[ACTIVE_LANE_MASK:%.*]] = phi <vscale x 4 x i1> [ [[ACTIVE_LANE_MASK_ENTRY]], %[[VECTOR_PH]] ], [ [[ACTIVE_LANE_MASK_NEXT:%.*]], %[[VECTOR_BODY]] ] | |
| ; PRED-NEXT: [[TMP12:%.*]] = getelementptr i8, ptr [[A]], i64 [[INDEX]] | |
| ; PRED-NEXT: [[WIDE_MASKED_LOAD:%.*]] = call <vscale x 4 x i8> @llvm.masked.load.nxv4i8.p0(ptr align 1 [[TMP12]], <vscale x 4 x i1> [[ACTIVE_LANE_MASK]], <vscale x 4 x i8> poison) | |
| ; PRED-NEXT: [[TMP9:%.*]] = uitofp <vscale x 4 x i8> [[WIDE_MASKED_LOAD]] to <vscale x 4 x float> | |
| ; PRED-NEXT: [[TMP14:%.*]] = getelementptr i8, ptr [[B]], i64 [[INDEX]] | |
| ; PRED-NEXT: [[WIDE_MASKED_LOAD5:%.*]] = call <vscale x 4 x i8> @llvm.masked.load.nxv4i8.p0(ptr align 1 [[TMP14]], <vscale x 4 x i1> [[ACTIVE_LANE_MASK]], <vscale x 4 x i8> poison) | |
| ; PRED-NEXT: [[TMP10:%.*]] = icmp ne <vscale x 4 x i8> [[WIDE_MASKED_LOAD5]], zeroinitializer | |
| ; PRED-NEXT: [[TMP11:%.*]] = select <vscale x 4 x i1> [[ACTIVE_LANE_MASK]], <vscale x 4 x i1> [[TMP10]], <vscale x 4 x i1> zeroinitializer | |
| ; PRED-NEXT: [[TMP21:%.*]] = xor <vscale x 4 x i8> [[WIDE_MASKED_LOAD]], splat (i8 1) | |
| ; PRED-NEXT: [[TMP13:%.*]] = call <vscale x 4 x i8> @llvm.masked.udiv.nxv4i8(<vscale x 4 x i8> [[TMP21]], <vscale x 4 x i8> [[BROADCAST_SPLAT]], <vscale x 4 x i1> [[TMP11]]) | |
| ; PRED-NEXT: [[TMP22:%.*]] = icmp ugt <vscale x 4 x i8> [[TMP13]], splat (i8 1) | |
| ; PRED-NEXT: [[TMP15:%.*]] = select <vscale x 4 x i1> [[TMP22]], <vscale x 4 x i32> zeroinitializer, <vscale x 4 x i32> splat (i32 255) | |
| ; PRED-NEXT: [[PREDPHI:%.*]] = select <vscale x 4 x i1> [[TMP10]], <vscale x 4 x i32> [[TMP15]], <vscale x 4 x i32> zeroinitializer | |
| ; PRED-NEXT: [[TMP16:%.*]] = zext <vscale x 4 x i8> [[WIDE_MASKED_LOAD]] to <vscale x 4 x i32> | |
| ; PRED-NEXT: [[TMP17:%.*]] = sub <vscale x 4 x i32> [[PREDPHI]], [[TMP16]] | |
| ; PRED-NEXT: [[TMP18:%.*]] = sitofp <vscale x 4 x i32> [[TMP17]] to <vscale x 4 x float> | |
| ; PRED-NEXT: [[TMP19:%.*]] = call <vscale x 4 x float> @llvm.fmuladd.nxv4f32(<vscale x 4 x float> [[TMP18]], <vscale x 4 x float> splat (float 3.000000e+00), <vscale x 4 x float> [[TMP9]]) | |
| ; PRED-NEXT: [[TMP20:%.*]] = fptoui <vscale x 4 x float> [[TMP19]] to <vscale x 4 x i8> | |
| ; PRED-NEXT: [[TMP27:%.*]] = getelementptr i8, ptr [[C]], i64 [[INDEX]] | |
| ; PRED-NEXT: call void @llvm.masked.store.nxv4i8.p0(<vscale x 4 x i8> [[TMP20]], ptr align 1 [[TMP27]], <vscale x 4 x i1> [[ACTIVE_LANE_MASK]]) | |
| ; PRED-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], [[TMP8]] | |
| ; PRED-NEXT: [[ACTIVE_LANE_MASK_NEXT]] = call <vscale x 4 x i1> @llvm.get.active.lane.mask.nxv4i1.i64(i64 [[INDEX_NEXT]], i64 [[TMP0]]) | |
| ; PRED-NEXT: [[TMP28:%.*]] = extractelement <vscale x 4 x i1> [[ACTIVE_LANE_MASK_NEXT]], i64 0 | |
| ; PRED-NEXT: [[TMP29:%.*]] = xor i1 [[TMP28]], true | |
| ; PRED-NEXT: br i1 [[TMP29]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP21:![0-9]+]] | |
| ; PRED: [[MIDDLE_BLOCK]]: | |
| ; PRED-NEXT: br [[EXIT:label %.*]] | |
| ; PRED: [[SCALAR_PH]]: | |
| ; | |
| entry: | |
| br label %loop.header | |
| loop.header: | |
| %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ] | |
| %gep.A = getelementptr i8, ptr %A, i64 %iv | |
| %l.1 = load i8, ptr %gep.A, align 1 | |
| %l.1.to.float = uitofp i8 %l.1 to float | |
| %gep.B = getelementptr i8, ptr %B, i64 %iv | |
| %l.2 = load i8, ptr %gep.B, align 1 | |
| %c = icmp eq i8 %l.2, 0 | |
| br i1 %c, label %loop.latch, label %else | |
| else: | |
| %x = xor i8 %l.1, 1 | |
| %ud = udiv i8 %x, %y | |
| %c.sel = icmp ugt i8 %ud, 1 | |
| %sel = select i1 %c.sel, i32 0, i32 255 | |
| br label %loop.latch | |
| loop.latch: | |
| %p = phi i32 [ %sel, %else ], [ 0, %loop.header ] | |
| %l.1.ext = zext i8 %l.1 to i32 | |
| %sub = sub i32 %p, %l.1.ext | |
| %sub.to.float = sitofp i32 %sub to float | |
| %muladd = tail call float @llvm.fmuladd.f32(float %sub.to.float, float 3.000000e+00, float %l.1.to.float) | |
| %muladd.conv = fptoui float %muladd to i8 | |
| %gep.C = getelementptr i8, ptr %C, i64 %iv | |
| store i8 %muladd.conv, ptr %gep.C, align 1 | |
| %iv.next = add i64 %iv, 1 | |
| %ec = icmp eq i64 %iv, %n | |
| br i1 %ec, label %exit, label %loop.header | |
| exit: | |
| ret void | |
| } | |
| define void @predicated_store(ptr %A, ptr noalias %B, ptr noalias %C, ptr %D, ptr %E, double %divisor, i64 %loop.count) #3 { | |
| ; COMMON-LABEL: define void @predicated_store( | |
| ; COMMON-SAME: ptr [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]], ptr [[D:%.*]], ptr [[E:%.*]], double [[DIVISOR:%.*]], i64 [[LOOP_COUNT:%.*]]) #[[ATTR3:[0-9]+]] { | |
| ; COMMON-NEXT: [[ENTRY:.*]]: | |
| ; COMMON-NEXT: br label %[[LOOP_HEADER:.*]] | |
| ; COMMON: [[LOOP_HEADER]]: | |
| ; COMMON-NEXT: [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ] | |
| ; COMMON-NEXT: [[GEP_B:%.*]] = getelementptr double, ptr [[B]], i64 [[IV]] | |
| ; COMMON-NEXT: [[FIRST_VAL:%.*]] = load double, ptr [[B]], align 8 | |
| ; COMMON-NEXT: store double 0.000000e+00, ptr [[D]], align 8 | |
| ; COMMON-NEXT: [[COEFF:%.*]] = load double, ptr [[C]], align 8 | |
| ; COMMON-NEXT: [[NEG:%.*]] = fneg double [[FIRST_VAL]] | |
| ; COMMON-NEXT: [[NORM:%.*]] = fdiv double [[NEG]], [[DIVISOR]] | |
| ; COMMON-NEXT: [[SCALED_COEFF:%.*]] = fmul double [[COEFF]], [[NORM]] | |
| ; COMMON-NEXT: [[INPUT_VAL:%.*]] = load double, ptr [[GEP_B]], align 8 | |
| ; COMMON-NEXT: [[SCALED_INPUT:%.*]] = fmul double [[INPUT_VAL]], [[DIVISOR]] | |
| ; COMMON-NEXT: [[PRODUCT:%.*]] = fmul double [[SCALED_COEFF]], [[SCALED_INPUT]] | |
| ; COMMON-NEXT: [[FINAL:%.*]] = fmul double [[PRODUCT]], [[DIVISOR]] | |
| ; COMMON-NEXT: [[IS_POS:%.*]] = fcmp ogt double [[FINAL]], 0.000000e+00 | |
| ; COMMON-NEXT: br i1 [[IS_POS]], label %[[THEN:.*]], label %[[LOOP_LATCH]] | |
| ; COMMON: [[THEN]]: | |
| ; COMMON-NEXT: store double 0.000000e+00, ptr [[A]], align 8 | |
| ; COMMON-NEXT: [[GEP_E:%.*]] = getelementptr i8, ptr [[E]], i64 [[IV]] | |
| ; COMMON-NEXT: store double 0.000000e+00, ptr [[GEP_E]], align 8 | |
| ; COMMON-NEXT: br label %[[LOOP_LATCH]] | |
| ; COMMON: [[LOOP_LATCH]]: | |
| ; COMMON-NEXT: store double 0.000000e+00, ptr null, align 8 | |
| ; COMMON-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1 | |
| ; COMMON-NEXT: [[EC:%.*]] = icmp eq i64 [[IV]], [[LOOP_COUNT]] | |
| ; COMMON-NEXT: br i1 [[EC]], label %[[EXIT:.*]], label %[[LOOP_HEADER]] | |
| ; COMMON: [[EXIT]]: | |
| ; COMMON-NEXT: ret void | |
| ; | |
| entry: | |
| br label %loop.header | |
| loop.header: | |
| %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ] | |
| %gep.B = getelementptr double, ptr %B, i64 %iv | |
| %first.val = load double, ptr %B, align 8 | |
| store double 0.000000e+00, ptr %D, align 8 | |
| %coeff = load double, ptr %C, align 8 | |
| %neg = fneg double %first.val | |
| %norm = fdiv double %neg, %divisor | |
| %scaled.coeff = fmul double %coeff, %norm | |
| %input.val = load double, ptr %gep.B, align 8 | |
| %scaled.input = fmul double %input.val, %divisor | |
| %product = fmul double %scaled.coeff, %scaled.input | |
| %final = fmul double %product, %divisor | |
| %is.pos = fcmp ogt double %final, 0.000000e+00 | |
| br i1 %is.pos, label %then, label %loop.latch | |
| then: | |
| store double 0.000000e+00, ptr %A, align 8 | |
| %gep.E = getelementptr i8, ptr %E, i64 %iv | |
| store double 0.000000e+00, ptr %gep.E, align 8 | |
| br label %loop.latch | |
| loop.latch: | |
| store double 0.000000e+00, ptr null, align 8 | |
| %iv.next = add i64 %iv, 1 | |
| %ec = icmp eq i64 %iv, %loop.count | |
| br i1 %ec, label %exit, label %loop.header | |
| exit: | |
| ret void | |
| } | |
| attributes #1 = { "target-cpu"="neoverse-512tvb" } | |
| attributes #2 = { vscale_range(2,2) "target-cpu"="neoverse-512tvb" } | |
| attributes #3 = { "target-cpu"="neoverse-v2" } | |
| !0 = distinct !{!0, !1, !2, !3} | |
| !1 = !{!"llvm.loop.vectorize.width", i32 8} | |
| !2 = !{!"llvm.loop.vectorize.scalable.disable"} | |
| !3 = !{!"llvm.loop.vectorize.enable"} |