| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py | |
| ; RUN: opt < %s -passes=loop-vectorize -mtriple=x86_64-apple-macosx10.8.0 -mcpu=corei7-avx -S | FileCheck %s | |
| target triple = "x86_64-apple-macosx10.8.0" | |
| ; Test case for https://github.com/llvm/llvm-project/issues/156091. | |
| define void @test_replicate_call_chain(float %x, ptr noalias %A, ptr noalias %B, ptr align 4 noalias %C, ptr align 4 noalias %D, ptr noalias %E) #0 { | |
| ; CHECK-LABEL: @test_replicate_call_chain( | |
| ; CHECK-NEXT: entry: | |
| ; CHECK-NEXT: br label [[VECTOR_PH:%.*]] | |
| ; CHECK: vector.ph: | |
| ; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] | |
| ; CHECK: vector.body: | |
| ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ] | |
| ; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[INDEX]], 1 | |
| ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds float, ptr [[A:%.*]], i64 [[INDEX]] | |
| ; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <16 x float>, ptr [[TMP1]], align 4 | |
| ; CHECK-NEXT: [[TMP2:%.*]] = fcmp ogt <16 x float> [[WIDE_LOAD]], zeroinitializer | |
| ; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds float, ptr [[B:%.*]], i64 [[INDEX]] | |
| ; CHECK-NEXT: [[WIDE_LOAD1:%.*]] = load <16 x float>, ptr [[TMP3]], align 4 | |
| ; CHECK-NEXT: [[TMP4:%.*]] = fcmp ogt <16 x float> [[WIDE_LOAD1]], zeroinitializer | |
| ; CHECK-NEXT: [[TMP5:%.*]] = getelementptr float, ptr [[C:%.*]], i64 [[TMP0]] | |
| ; CHECK-NEXT: [[TMP6:%.*]] = and <16 x i1> [[TMP2]], [[TMP4]] | |
| ; CHECK-NEXT: [[TMP7:%.*]] = xor <16 x i1> [[TMP6]], splat (i1 true) | |
| ; CHECK-NEXT: [[TMP8:%.*]] = shl i64 [[INDEX]], 2 | |
| ; CHECK-NEXT: [[TMP9:%.*]] = getelementptr i8, ptr [[D:%.*]], i64 [[TMP8]] | |
| ; CHECK-NEXT: [[WIDE_MASKED_LOAD:%.*]] = call <16 x float> @llvm.masked.load.v16f32.p0(ptr align 4 [[TMP9]], <16 x i1> [[TMP7]], <16 x float> poison) | |
| ; CHECK-NEXT: [[TMP10:%.*]] = fmul <16 x float> [[WIDE_MASKED_LOAD]], splat (float 2.000000e+00) | |
| ; CHECK-NEXT: [[TMP11:%.*]] = extractelement <16 x float> [[TMP10]], i64 0 | |
| ; CHECK-NEXT: [[TMP12:%.*]] = tail call float @llvm.pow.f32(float [[TMP11]], float [[X:%.*]]) | |
| ; CHECK-NEXT: [[TMP13:%.*]] = extractelement <16 x float> [[TMP10]], i64 1 | |
| ; CHECK-NEXT: [[TMP14:%.*]] = tail call float @llvm.pow.f32(float [[TMP13]], float [[X]]) | |
| ; CHECK-NEXT: [[TMP15:%.*]] = extractelement <16 x float> [[TMP10]], i64 2 | |
| ; CHECK-NEXT: [[TMP16:%.*]] = tail call float @llvm.pow.f32(float [[TMP15]], float [[X]]) | |
| ; CHECK-NEXT: [[TMP17:%.*]] = extractelement <16 x float> [[TMP10]], i64 3 | |
| ; CHECK-NEXT: [[TMP18:%.*]] = tail call float @llvm.pow.f32(float [[TMP17]], float [[X]]) | |
| ; CHECK-NEXT: [[TMP19:%.*]] = extractelement <16 x float> [[TMP10]], i64 4 | |
| ; CHECK-NEXT: [[TMP20:%.*]] = tail call float @llvm.pow.f32(float [[TMP19]], float [[X]]) | |
| ; CHECK-NEXT: [[TMP21:%.*]] = extractelement <16 x float> [[TMP10]], i64 5 | |
| ; CHECK-NEXT: [[TMP22:%.*]] = tail call float @llvm.pow.f32(float [[TMP21]], float [[X]]) | |
| ; CHECK-NEXT: [[TMP23:%.*]] = extractelement <16 x float> [[TMP10]], i64 6 | |
| ; CHECK-NEXT: [[TMP24:%.*]] = tail call float @llvm.pow.f32(float [[TMP23]], float [[X]]) | |
| ; CHECK-NEXT: [[TMP25:%.*]] = extractelement <16 x float> [[TMP10]], i64 7 | |
| ; CHECK-NEXT: [[TMP26:%.*]] = tail call float @llvm.pow.f32(float [[TMP25]], float [[X]]) | |
| ; CHECK-NEXT: [[TMP27:%.*]] = extractelement <16 x float> [[TMP10]], i64 8 | |
| ; CHECK-NEXT: [[TMP28:%.*]] = tail call float @llvm.pow.f32(float [[TMP27]], float [[X]]) | |
| ; CHECK-NEXT: [[TMP29:%.*]] = extractelement <16 x float> [[TMP10]], i64 9 | |
| ; CHECK-NEXT: [[TMP30:%.*]] = tail call float @llvm.pow.f32(float [[TMP29]], float [[X]]) | |
| ; CHECK-NEXT: [[TMP31:%.*]] = extractelement <16 x float> [[TMP10]], i64 10 | |
| ; CHECK-NEXT: [[TMP32:%.*]] = tail call float @llvm.pow.f32(float [[TMP31]], float [[X]]) | |
| ; CHECK-NEXT: [[TMP33:%.*]] = extractelement <16 x float> [[TMP10]], i64 11 | |
| ; CHECK-NEXT: [[TMP34:%.*]] = tail call float @llvm.pow.f32(float [[TMP33]], float [[X]]) | |
| ; CHECK-NEXT: [[TMP35:%.*]] = extractelement <16 x float> [[TMP10]], i64 12 | |
| ; CHECK-NEXT: [[TMP36:%.*]] = tail call float @llvm.pow.f32(float [[TMP35]], float [[X]]) | |
| ; CHECK-NEXT: [[TMP37:%.*]] = extractelement <16 x float> [[TMP10]], i64 13 | |
| ; CHECK-NEXT: [[TMP38:%.*]] = tail call float @llvm.pow.f32(float [[TMP37]], float [[X]]) | |
| ; CHECK-NEXT: [[TMP39:%.*]] = extractelement <16 x float> [[TMP10]], i64 14 | |
| ; CHECK-NEXT: [[TMP40:%.*]] = tail call float @llvm.pow.f32(float [[TMP39]], float [[X]]) | |
| ; CHECK-NEXT: [[TMP41:%.*]] = extractelement <16 x float> [[TMP10]], i64 15 | |
| ; CHECK-NEXT: [[TMP42:%.*]] = tail call float @llvm.pow.f32(float [[TMP41]], float [[X]]) | |
| ; CHECK-NEXT: [[TMP43:%.*]] = tail call float @llvm.pow.f32(float [[TMP12]], float [[X]]) | |
| ; CHECK-NEXT: [[TMP44:%.*]] = tail call float @llvm.pow.f32(float [[TMP14]], float [[X]]) | |
| ; CHECK-NEXT: [[TMP45:%.*]] = tail call float @llvm.pow.f32(float [[TMP16]], float [[X]]) | |
| ; CHECK-NEXT: [[TMP46:%.*]] = tail call float @llvm.pow.f32(float [[TMP18]], float [[X]]) | |
| ; CHECK-NEXT: [[TMP47:%.*]] = tail call float @llvm.pow.f32(float [[TMP20]], float [[X]]) | |
| ; CHECK-NEXT: [[TMP48:%.*]] = tail call float @llvm.pow.f32(float [[TMP22]], float [[X]]) | |
| ; CHECK-NEXT: [[TMP49:%.*]] = tail call float @llvm.pow.f32(float [[TMP24]], float [[X]]) | |
| ; CHECK-NEXT: [[TMP50:%.*]] = tail call float @llvm.pow.f32(float [[TMP26]], float [[X]]) | |
| ; CHECK-NEXT: [[TMP51:%.*]] = tail call float @llvm.pow.f32(float [[TMP28]], float [[X]]) | |
| ; CHECK-NEXT: [[TMP52:%.*]] = tail call float @llvm.pow.f32(float [[TMP30]], float [[X]]) | |
| ; CHECK-NEXT: [[TMP53:%.*]] = tail call float @llvm.pow.f32(float [[TMP32]], float [[X]]) | |
| ; CHECK-NEXT: [[TMP54:%.*]] = tail call float @llvm.pow.f32(float [[TMP34]], float [[X]]) | |
| ; CHECK-NEXT: [[TMP55:%.*]] = tail call float @llvm.pow.f32(float [[TMP36]], float [[X]]) | |
| ; CHECK-NEXT: [[TMP56:%.*]] = tail call float @llvm.pow.f32(float [[TMP38]], float [[X]]) | |
| ; CHECK-NEXT: [[TMP57:%.*]] = tail call float @llvm.pow.f32(float [[TMP40]], float [[X]]) | |
| ; CHECK-NEXT: [[TMP58:%.*]] = tail call float @llvm.pow.f32(float [[TMP42]], float [[X]]) | |
| ; CHECK-NEXT: [[TMP59:%.*]] = insertelement <16 x float> poison, float [[TMP43]], i64 0 | |
| ; CHECK-NEXT: [[TMP60:%.*]] = insertelement <16 x float> [[TMP59]], float [[TMP44]], i64 1 | |
| ; CHECK-NEXT: [[TMP61:%.*]] = insertelement <16 x float> [[TMP60]], float [[TMP45]], i64 2 | |
| ; CHECK-NEXT: [[TMP62:%.*]] = insertelement <16 x float> [[TMP61]], float [[TMP46]], i64 3 | |
| ; CHECK-NEXT: [[TMP63:%.*]] = insertelement <16 x float> [[TMP62]], float [[TMP47]], i64 4 | |
| ; CHECK-NEXT: [[TMP64:%.*]] = insertelement <16 x float> [[TMP63]], float [[TMP48]], i64 5 | |
| ; CHECK-NEXT: [[TMP65:%.*]] = insertelement <16 x float> [[TMP64]], float [[TMP49]], i64 6 | |
| ; CHECK-NEXT: [[TMP66:%.*]] = insertelement <16 x float> [[TMP65]], float [[TMP50]], i64 7 | |
| ; CHECK-NEXT: [[TMP67:%.*]] = insertelement <16 x float> [[TMP66]], float [[TMP51]], i64 8 | |
| ; CHECK-NEXT: [[TMP68:%.*]] = insertelement <16 x float> [[TMP67]], float [[TMP52]], i64 9 | |
| ; CHECK-NEXT: [[TMP69:%.*]] = insertelement <16 x float> [[TMP68]], float [[TMP53]], i64 10 | |
| ; CHECK-NEXT: [[TMP70:%.*]] = insertelement <16 x float> [[TMP69]], float [[TMP54]], i64 11 | |
| ; CHECK-NEXT: [[TMP71:%.*]] = insertelement <16 x float> [[TMP70]], float [[TMP55]], i64 12 | |
| ; CHECK-NEXT: [[TMP72:%.*]] = insertelement <16 x float> [[TMP71]], float [[TMP56]], i64 13 | |
| ; CHECK-NEXT: [[TMP73:%.*]] = insertelement <16 x float> [[TMP72]], float [[TMP57]], i64 14 | |
| ; CHECK-NEXT: [[TMP74:%.*]] = insertelement <16 x float> [[TMP73]], float [[TMP58]], i64 15 | |
| ; CHECK-NEXT: call void @llvm.masked.store.v16f32.p0(<16 x float> [[TMP74]], ptr align 4 [[TMP5]], <16 x i1> [[TMP7]]) | |
| ; CHECK-NEXT: call void @llvm.masked.store.v16f32.p0(<16 x float> zeroinitializer, ptr align 4 [[TMP5]], <16 x i1> [[TMP6]]) | |
| ; CHECK-NEXT: store float 0.000000e+00, ptr [[E:%.*]], align 4 | |
| ; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 16 | |
| ; CHECK-NEXT: [[TMP75:%.*]] = icmp eq i64 [[INDEX_NEXT]], 96 | |
| ; CHECK-NEXT: br i1 [[TMP75]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]] | |
| ; CHECK: middle.block: | |
| ; CHECK-NEXT: br label [[SCALAR_PH:%.*]] | |
| ; CHECK: scalar.ph: | |
| ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] | |
| ; CHECK: loop.header: | |
| ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 96, [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] | |
| ; CHECK-NEXT: [[DEC_IV:%.*]] = phi i64 [ 4, [[SCALAR_PH]] ], [ [[DEC_IV_NEXT:%.*]], [[LOOP_LATCH]] ] | |
| ; CHECK-NEXT: [[IV_INC:%.*]] = add i64 [[IV]], 1 | |
| ; CHECK-NEXT: [[GEP_A:%.*]] = getelementptr inbounds float, ptr [[A]], i64 [[IV]] | |
| ; CHECK-NEXT: [[L_A:%.*]] = load float, ptr [[GEP_A]], align 4 | |
| ; CHECK-NEXT: [[C_A:%.*]] = fcmp ogt float [[L_A]], 0.000000e+00 | |
| ; CHECK-NEXT: [[GEP_B:%.*]] = getelementptr inbounds float, ptr [[B]], i64 [[IV]] | |
| ; CHECK-NEXT: [[L_B:%.*]] = load float, ptr [[GEP_B]], align 4 | |
| ; CHECK-NEXT: [[C_B:%.*]] = fcmp ogt float [[L_B]], 0.000000e+00 | |
| ; CHECK-NEXT: [[GEP_C:%.*]] = getelementptr float, ptr [[C]], i64 [[IV_INC]] | |
| ; CHECK-NEXT: [[AND:%.*]] = and i1 [[C_A]], [[C_B]] | |
| ; CHECK-NEXT: br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]] | |
| ; CHECK: then: | |
| ; CHECK-NEXT: store float 0.000000e+00, ptr [[GEP_C]], align 4 | |
| ; CHECK-NEXT: br label [[LOOP_LATCH]] | |
| ; CHECK: else: | |
| ; CHECK-NEXT: [[IV_MUL_2:%.*]] = shl i64 [[IV]], 2 | |
| ; CHECK-NEXT: [[GEP_D:%.*]] = getelementptr i8, ptr [[D]], i64 [[IV_MUL_2]] | |
| ; CHECK-NEXT: [[L_D:%.*]] = load float, ptr [[GEP_D]], align 4 | |
| ; CHECK-NEXT: [[MUL:%.*]] = fmul float [[L_D]], 2.000000e+00 | |
| ; CHECK-NEXT: [[POW_1:%.*]] = tail call float @llvm.pow.f32(float [[MUL]], float [[X]]) | |
| ; CHECK-NEXT: [[POW_2:%.*]] = tail call float @llvm.pow.f32(float [[POW_1]], float [[X]]) | |
| ; CHECK-NEXT: store float [[POW_2]], ptr [[GEP_C]], align 4 | |
| ; CHECK-NEXT: br label [[LOOP_LATCH]] | |
| ; CHECK: loop.latch: | |
| ; CHECK-NEXT: store float 0.000000e+00, ptr [[E]], align 4 | |
| ; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1 | |
| ; CHECK-NEXT: [[DEC_IV_NEXT]] = add i64 [[DEC_IV]], -1 | |
| ; CHECK-NEXT: [[EC:%.*]] = icmp ne i64 [[DEC_IV_NEXT]], 0 | |
| ; CHECK-NEXT: br i1 [[EC]], label [[LOOP_HEADER]], label [[EXIT:%.*]], !llvm.loop [[LOOP3:![0-9]+]] | |
| ; CHECK: exit: | |
| ; CHECK-NEXT: ret void | |
| ; | |
| entry: | |
| br label %loop.header | |
| loop.header: | |
| %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ] | |
| %dec.iv = phi i64 [ 100, %entry ], [ %dec.iv.next, %loop.latch ] | |
| %iv.inc = add i64 %iv, 1 | |
| %gep.A = getelementptr inbounds float, ptr %A, i64 %iv | |
| %l.A = load float, ptr %gep.A, align 4 | |
| %c.A = fcmp ogt float %l.A, 0.0 | |
| %gep.B = getelementptr inbounds float, ptr %B, i64 %iv | |
| %l.B = load float, ptr %gep.B, align 4 | |
| %c.B = fcmp ogt float %l.B, 0.0 | |
| %gep.C = getelementptr float, ptr %C, i64 %iv.inc | |
| %and = and i1 %c.A, %c.B | |
| br i1 %and, label %then, label %else | |
| then: | |
| store float 0.0, ptr %gep.C, align 4 | |
| br label %loop.latch | |
| else: | |
| %iv.mul.2 = shl i64 %iv, 2 | |
| %gep.D = getelementptr i8, ptr %D, i64 %iv.mul.2 | |
| %l.D = load float, ptr %gep.D, align 4 | |
| %mul = fmul float %l.D, 2.0 | |
| %pow.1 = tail call float @llvm.pow.f32(float %mul, float %x) | |
| %pow.2 = tail call float @llvm.pow.f32(float %pow.1, float %x) | |
| store float %pow.2, ptr %gep.C, align 4 | |
| br label %loop.latch | |
| loop.latch: | |
| store float 0.000000e+00, ptr %E, align 4 | |
| %iv.next = add i64 %iv, 1 | |
| %dec.iv.next = add i64 %dec.iv, -1 | |
| %ec = icmp ne i64 %dec.iv.next, 0 | |
| br i1 %ec, label %loop.header, label %exit | |
| exit: | |
| ret void | |
| } | |
| define i64 @avx512_cond_load_cost(ptr %src, i32 %a, i64 %b, i32 %c, i32 %d) #1 { | |
| ; CHECK-LABEL: @avx512_cond_load_cost( | |
| ; CHECK-NEXT: entry: | |
| ; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[C:%.*]], 1 | |
| ; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i32 [[TMP0]], 8 | |
| ; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] | |
| ; CHECK: vector.ph: | |
| ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[TMP0]], 7 | |
| ; CHECK-NEXT: [[N_VEC:%.*]] = sub i32 [[TMP0]], [[TMP1]] | |
| ; CHECK-NEXT: [[BROADCAST_SPLATINSERT2:%.*]] = insertelement <8 x i32> poison, i32 [[A:%.*]], i64 0 | |
| ; CHECK-NEXT: [[BROADCAST_SPLAT1:%.*]] = shufflevector <8 x i32> [[BROADCAST_SPLATINSERT2]], <8 x i32> poison, <8 x i32> zeroinitializer | |
| ; CHECK-NEXT: [[BROADCAST_SPLATINSERT1:%.*]] = insertelement <8 x i32> poison, i32 [[C]], i64 0 | |
| ; CHECK-NEXT: [[BROADCAST_SPLAT2:%.*]] = shufflevector <8 x i32> [[BROADCAST_SPLATINSERT1]], <8 x i32> poison, <8 x i32> zeroinitializer | |
| ; CHECK-NEXT: [[BROADCAST_SPLATINSERT3:%.*]] = insertelement <8 x i32> poison, i32 [[D:%.*]], i64 0 | |
| ; CHECK-NEXT: [[BROADCAST_SPLAT4:%.*]] = shufflevector <8 x i32> [[BROADCAST_SPLATINSERT3]], <8 x i32> poison, <8 x i32> zeroinitializer | |
| ; CHECK-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement <8 x i64> poison, i64 [[B:%.*]], i64 0 | |
| ; CHECK-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector <8 x i64> [[BROADCAST_SPLATINSERT]], <8 x i64> poison, <8 x i32> zeroinitializer | |
| ; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] | |
| ; CHECK: vector.body: | |
| ; CHECK-NEXT: [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ] | |
| ; CHECK-NEXT: [[VEC_IND:%.*]] = phi <8 x i32> [ <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>, [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[VECTOR_BODY]] ] | |
| ; CHECK-NEXT: [[TMP2:%.*]] = icmp slt <8 x i32> [[VEC_IND]], zeroinitializer | |
| ; CHECK-NEXT: [[TMP34:%.*]] = call <8 x i32> @llvm.masked.urem.v8i32(<8 x i32> [[BROADCAST_SPLAT1]], <8 x i32> [[BROADCAST_SPLAT2]], <8 x i1> [[TMP2]]) | |
| ; CHECK-NEXT: [[TMP35:%.*]] = sub <8 x i32> zeroinitializer, [[TMP34]] | |
| ; CHECK-NEXT: [[TMP59:%.*]] = call <8 x i32> @llvm.masked.udiv.v8i32(<8 x i32> [[BROADCAST_SPLAT2]], <8 x i32> [[BROADCAST_SPLAT4]], <8 x i1> [[TMP2]]) | |
| ; CHECK-NEXT: [[TMP60:%.*]] = or <8 x i32> [[TMP59]], [[TMP35]] | |
| ; CHECK-NEXT: [[TMP61:%.*]] = sext <8 x i32> [[TMP60]] to <8 x i64> | |
| ; CHECK-NEXT: [[WIDE_GEP:%.*]] = getelementptr { i64, i64, i64 }, ptr [[SRC:%.*]], <8 x i64> [[TMP61]], i32 2 | |
| ; CHECK-NEXT: [[WIDE_MASKED_GATHER:%.*]] = call <8 x i64> @llvm.masked.gather.v8i64.v8p0(<8 x ptr> align 8 [[WIDE_GEP]], <8 x i1> [[TMP2]], <8 x i64> poison) | |
| ; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 8 | |
| ; CHECK-NEXT: [[VEC_IND_NEXT]] = add <8 x i32> [[VEC_IND]], splat (i32 8) | |
| ; CHECK-NEXT: [[TMP62:%.*]] = icmp eq i32 [[INDEX_NEXT]], [[N_VEC]] | |
| ; CHECK-NEXT: br i1 [[TMP62]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP4:![0-9]+]] | |
| ; CHECK: middle.block: | |
| ; CHECK-NEXT: [[TMP63:%.*]] = or <8 x i64> [[WIDE_MASKED_GATHER]], [[BROADCAST_SPLAT]] | |
| ; CHECK-NEXT: [[PREDPHI:%.*]] = select <8 x i1> [[TMP2]], <8 x i64> [[TMP63]], <8 x i64> zeroinitializer | |
| ; CHECK-NEXT: [[TMP64:%.*]] = extractelement <8 x i64> [[PREDPHI]], i64 7 | |
| ; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i32 [[TMP0]], [[N_VEC]] | |
| ; CHECK-NEXT: br i1 [[CMP_N]], label [[EXIT:%.*]], label [[SCALAR_PH]] | |
| ; CHECK: scalar.ph: | |
| ; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i32 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ] | |
| ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] | |
| ; CHECK: loop.header: | |
| ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] | |
| ; CHECK-NEXT: [[C_1:%.*]] = icmp slt i32 [[IV]], 0 | |
| ; CHECK-NEXT: br i1 [[C_1]], label [[IF_THEN:%.*]], label [[LOOP_LATCH]] | |
| ; CHECK: if.then: | |
| ; CHECK-NEXT: [[TMP65:%.*]] = urem i32 [[A]], [[C]] | |
| ; CHECK-NEXT: [[MUL:%.*]] = sub i32 0, [[TMP65]] | |
| ; CHECK-NEXT: [[DIV:%.*]] = udiv i32 [[C]], [[D]] | |
| ; CHECK-NEXT: [[OR:%.*]] = or i32 [[DIV]], [[MUL]] | |
| ; CHECK-NEXT: [[EXT:%.*]] = sext i32 [[OR]] to i64 | |
| ; CHECK-NEXT: [[GEP:%.*]] = getelementptr { i64, i64, i64 }, ptr [[SRC]], i64 [[EXT]], i32 2 | |
| ; CHECK-NEXT: [[L:%.*]] = load i64, ptr [[GEP]], align 8 | |
| ; CHECK-NEXT: [[OR_2:%.*]] = or i64 [[L]], [[B]] | |
| ; CHECK-NEXT: br label [[LOOP_LATCH]] | |
| ; CHECK: loop.latch: | |
| ; CHECK-NEXT: [[RES:%.*]] = phi i64 [ 0, [[LOOP_HEADER]] ], [ [[OR_2]], [[IF_THEN]] ] | |
| ; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 | |
| ; CHECK-NEXT: [[EC:%.*]] = icmp ult i32 [[IV]], [[C]] | |
| ; CHECK-NEXT: br i1 [[EC]], label [[LOOP_HEADER]], label [[EXIT]], !llvm.loop [[LOOP5:![0-9]+]] | |
| ; CHECK: exit: | |
| ; CHECK-NEXT: [[RES_LCSSA:%.*]] = phi i64 [ [[RES]], [[LOOP_LATCH]] ], [ [[TMP64]], [[MIDDLE_BLOCK]] ] | |
| ; CHECK-NEXT: ret i64 [[RES_LCSSA]] | |
| ; | |
| entry: | |
| br label %loop.header | |
| loop.header: | |
| %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] | |
| %c.1 = icmp slt i32 %iv, 0 | |
| br i1 %c.1, label %if.then, label %loop.latch | |
| if.then: | |
| %1 = urem i32 %a, %c | |
| %mul = sub i32 0, %1 | |
| %div = udiv i32 %c, %d | |
| %or = or i32 %div, %mul | |
| %ext = sext i32 %or to i64 | |
| %gep = getelementptr { i64, i64, i64 }, ptr %src, i64 %ext, i32 2 | |
| %l = load i64, ptr %gep, align 8 | |
| %or.2 = or i64 %l, %b | |
| br label %loop.latch | |
| loop.latch: | |
| %res = phi i64 [ 0, %loop.header ], [ %or.2, %if.then ] | |
| %iv.next = add i32 %iv, 1 | |
| %ec = icmp ult i32 %iv, %c | |
| br i1 %ec, label %loop.header, label %exit | |
| exit: | |
| ret i64 %res | |
| } | |
| define void @cost_duplicate_recipe_for_sinking(ptr %A, i64 %N) #2 { | |
| ; CHECK-LABEL: @cost_duplicate_recipe_for_sinking( | |
| ; CHECK-NEXT: iter.check: | |
| ; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[N:%.*]], 1 | |
| ; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ule i64 [[TMP0]], 4 | |
| ; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[VEC_EPILOG_SCALAR_PH:%.*]], label [[VECTOR_MAIN_LOOP_ITER_CHECK:%.*]] | |
| ; CHECK: vector.main.loop.iter.check: | |
| ; CHECK-NEXT: [[MIN_ITERS_CHECK1:%.*]] = icmp ule i64 [[TMP0]], 16 | |
| ; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK1]], label [[VEC_EPILOG_PH:%.*]], label [[VECTOR_PH:%.*]] | |
| ; CHECK: vector.ph: | |
| ; CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 15 | |
| ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 0 | |
| ; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP2]], i64 16, i64 [[TMP1]] | |
| ; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 [[TMP0]], [[TMP3]] | |
| ; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] | |
| ; CHECK: vector.body: | |
| ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[PRED_STORE_CONTINUE37:%.*]] ] | |
| ; CHECK-NEXT: [[TMP4:%.*]] = add i64 [[INDEX]], 4 | |
| ; CHECK-NEXT: [[TMP5:%.*]] = add i64 [[INDEX]], 8 | |
| ; CHECK-NEXT: [[TMP6:%.*]] = add i64 [[INDEX]], 12 | |
| ; CHECK-NEXT: [[TMP7:%.*]] = shl nsw i64 [[INDEX]], 2 | |
| ; CHECK-NEXT: [[TMP8:%.*]] = shl nsw i64 [[TMP4]], 2 | |
| ; CHECK-NEXT: [[TMP9:%.*]] = shl nsw i64 [[TMP5]], 2 | |
| ; CHECK-NEXT: [[TMP10:%.*]] = shl nsw i64 [[TMP6]], 2 | |
| ; CHECK-NEXT: [[TMP11:%.*]] = getelementptr double, ptr [[A:%.*]], i64 [[TMP7]] | |
| ; CHECK-NEXT: [[TMP12:%.*]] = getelementptr double, ptr [[A]], i64 [[TMP8]] | |
| ; CHECK-NEXT: [[TMP13:%.*]] = getelementptr double, ptr [[A]], i64 [[TMP9]] | |
| ; CHECK-NEXT: [[TMP14:%.*]] = getelementptr double, ptr [[A]], i64 [[TMP10]] | |
| ; CHECK-NEXT: [[WIDE_VEC:%.*]] = load <16 x double>, ptr [[TMP11]], align 8 | |
| ; CHECK-NEXT: [[STRIDED_VEC:%.*]] = shufflevector <16 x double> [[WIDE_VEC]], <16 x double> poison, <4 x i32> <i32 0, i32 4, i32 8, i32 12> | |
| ; CHECK-NEXT: [[WIDE_VEC2:%.*]] = load <16 x double>, ptr [[TMP12]], align 8 | |
| ; CHECK-NEXT: [[STRIDED_VEC3:%.*]] = shufflevector <16 x double> [[WIDE_VEC2]], <16 x double> poison, <4 x i32> <i32 0, i32 4, i32 8, i32 12> | |
| ; CHECK-NEXT: [[WIDE_VEC4:%.*]] = load <16 x double>, ptr [[TMP13]], align 8 | |
| ; CHECK-NEXT: [[STRIDED_VEC5:%.*]] = shufflevector <16 x double> [[WIDE_VEC4]], <16 x double> poison, <4 x i32> <i32 0, i32 4, i32 8, i32 12> | |
| ; CHECK-NEXT: [[WIDE_VEC6:%.*]] = load <16 x double>, ptr [[TMP14]], align 8 | |
| ; CHECK-NEXT: [[STRIDED_VEC7:%.*]] = shufflevector <16 x double> [[WIDE_VEC6]], <16 x double> poison, <4 x i32> <i32 0, i32 4, i32 8, i32 12> | |
| ; CHECK-NEXT: [[TMP15:%.*]] = fcmp oeq <4 x double> [[STRIDED_VEC]], zeroinitializer | |
| ; CHECK-NEXT: [[TMP16:%.*]] = fcmp oeq <4 x double> [[STRIDED_VEC3]], zeroinitializer | |
| ; CHECK-NEXT: [[TMP17:%.*]] = fcmp oeq <4 x double> [[STRIDED_VEC5]], zeroinitializer | |
| ; CHECK-NEXT: [[TMP18:%.*]] = fcmp oeq <4 x double> [[STRIDED_VEC7]], zeroinitializer | |
| ; CHECK-NEXT: [[TMP19:%.*]] = extractelement <4 x i1> [[TMP15]], i64 0 | |
| ; CHECK-NEXT: br i1 [[TMP19]], label [[PRED_STORE_IF:%.*]], label [[PRED_STORE_CONTINUE:%.*]] | |
| ; CHECK: pred.store.if: | |
| ; CHECK-NEXT: store double 0.000000e+00, ptr [[TMP11]], align 8 | |
| ; CHECK-NEXT: br label [[PRED_STORE_CONTINUE]] | |
| ; CHECK: pred.store.continue: | |
| ; CHECK-NEXT: [[TMP20:%.*]] = extractelement <4 x i1> [[TMP15]], i64 1 | |
| ; CHECK-NEXT: br i1 [[TMP20]], label [[PRED_STORE_IF8:%.*]], label [[PRED_STORE_CONTINUE9:%.*]] | |
| ; CHECK: pred.store.if8: | |
| ; CHECK-NEXT: [[TMP21:%.*]] = add i64 [[INDEX]], 1 | |
| ; CHECK-NEXT: [[TMP22:%.*]] = shl nsw i64 [[TMP21]], 2 | |
| ; CHECK-NEXT: [[TMP23:%.*]] = getelementptr double, ptr [[A]], i64 [[TMP22]] | |
| ; CHECK-NEXT: store double 0.000000e+00, ptr [[TMP23]], align 8 | |
| ; CHECK-NEXT: br label [[PRED_STORE_CONTINUE9]] | |
| ; CHECK: pred.store.continue9: | |
| ; CHECK-NEXT: [[TMP24:%.*]] = extractelement <4 x i1> [[TMP15]], i64 2 | |
| ; CHECK-NEXT: br i1 [[TMP24]], label [[PRED_STORE_IF10:%.*]], label [[PRED_STORE_CONTINUE11:%.*]] | |
| ; CHECK: pred.store.if10: | |
| ; CHECK-NEXT: [[TMP25:%.*]] = add i64 [[INDEX]], 2 | |
| ; CHECK-NEXT: [[TMP26:%.*]] = shl nsw i64 [[TMP25]], 2 | |
| ; CHECK-NEXT: [[TMP27:%.*]] = getelementptr double, ptr [[A]], i64 [[TMP26]] | |
| ; CHECK-NEXT: store double 0.000000e+00, ptr [[TMP27]], align 8 | |
| ; CHECK-NEXT: br label [[PRED_STORE_CONTINUE11]] | |
| ; CHECK: pred.store.continue11: | |
| ; CHECK-NEXT: [[TMP28:%.*]] = extractelement <4 x i1> [[TMP15]], i64 3 | |
| ; CHECK-NEXT: br i1 [[TMP28]], label [[PRED_STORE_IF12:%.*]], label [[PRED_STORE_CONTINUE13:%.*]] | |
| ; CHECK: pred.store.if12: | |
| ; CHECK-NEXT: [[TMP29:%.*]] = add i64 [[INDEX]], 3 | |
| ; CHECK-NEXT: [[TMP30:%.*]] = shl nsw i64 [[TMP29]], 2 | |
| ; CHECK-NEXT: [[TMP31:%.*]] = getelementptr double, ptr [[A]], i64 [[TMP30]] | |
| ; CHECK-NEXT: store double 0.000000e+00, ptr [[TMP31]], align 8 | |
| ; CHECK-NEXT: br label [[PRED_STORE_CONTINUE13]] | |
| ; CHECK: pred.store.continue13: | |
| ; CHECK-NEXT: [[TMP32:%.*]] = extractelement <4 x i1> [[TMP16]], i64 0 | |
| ; CHECK-NEXT: br i1 [[TMP32]], label [[PRED_STORE_IF14:%.*]], label [[PRED_STORE_CONTINUE15:%.*]] | |
| ; CHECK: pred.store.if14: | |
| ; CHECK-NEXT: store double 0.000000e+00, ptr [[TMP12]], align 8 | |
| ; CHECK-NEXT: br label [[PRED_STORE_CONTINUE15]] | |
| ; CHECK: pred.store.continue15: | |
| ; CHECK-NEXT: [[TMP33:%.*]] = extractelement <4 x i1> [[TMP16]], i64 1 | |
| ; CHECK-NEXT: br i1 [[TMP33]], label [[PRED_STORE_IF16:%.*]], label [[PRED_STORE_CONTINUE17:%.*]] | |
| ; CHECK: pred.store.if16: | |
| ; CHECK-NEXT: [[TMP34:%.*]] = add i64 [[INDEX]], 5 | |
| ; CHECK-NEXT: [[TMP35:%.*]] = shl nsw i64 [[TMP34]], 2 | |
| ; CHECK-NEXT: [[TMP36:%.*]] = getelementptr double, ptr [[A]], i64 [[TMP35]] | |
| ; CHECK-NEXT: store double 0.000000e+00, ptr [[TMP36]], align 8 | |
| ; CHECK-NEXT: br label [[PRED_STORE_CONTINUE17]] | |
| ; CHECK: pred.store.continue17: | |
| ; CHECK-NEXT: [[TMP37:%.*]] = extractelement <4 x i1> [[TMP16]], i64 2 | |
| ; CHECK-NEXT: br i1 [[TMP37]], label [[PRED_STORE_IF18:%.*]], label [[PRED_STORE_CONTINUE19:%.*]] | |
| ; CHECK: pred.store.if18: | |
| ; CHECK-NEXT: [[TMP38:%.*]] = add i64 [[INDEX]], 6 | |
| ; CHECK-NEXT: [[TMP39:%.*]] = shl nsw i64 [[TMP38]], 2 | |
| ; CHECK-NEXT: [[TMP40:%.*]] = getelementptr double, ptr [[A]], i64 [[TMP39]] | |
| ; CHECK-NEXT: store double 0.000000e+00, ptr [[TMP40]], align 8 | |
| ; CHECK-NEXT: br label [[PRED_STORE_CONTINUE19]] | |
| ; CHECK: pred.store.continue19: | |
| ; CHECK-NEXT: [[TMP41:%.*]] = extractelement <4 x i1> [[TMP16]], i64 3 | |
| ; CHECK-NEXT: br i1 [[TMP41]], label [[PRED_STORE_IF20:%.*]], label [[PRED_STORE_CONTINUE21:%.*]] | |
| ; CHECK: pred.store.if20: | |
| ; CHECK-NEXT: [[TMP42:%.*]] = add i64 [[INDEX]], 7 | |
| ; CHECK-NEXT: [[TMP43:%.*]] = shl nsw i64 [[TMP42]], 2 | |
| ; CHECK-NEXT: [[TMP44:%.*]] = getelementptr double, ptr [[A]], i64 [[TMP43]] | |
| ; CHECK-NEXT: store double 0.000000e+00, ptr [[TMP44]], align 8 | |
| ; CHECK-NEXT: br label [[PRED_STORE_CONTINUE21]] | |
| ; CHECK: pred.store.continue21: | |
| ; CHECK-NEXT: [[TMP45:%.*]] = extractelement <4 x i1> [[TMP17]], i64 0 | |
| ; CHECK-NEXT: br i1 [[TMP45]], label [[PRED_STORE_IF22:%.*]], label [[PRED_STORE_CONTINUE23:%.*]] | |
| ; CHECK: pred.store.if22: | |
| ; CHECK-NEXT: store double 0.000000e+00, ptr [[TMP13]], align 8 | |
| ; CHECK-NEXT: br label [[PRED_STORE_CONTINUE23]] | |
| ; CHECK: pred.store.continue23: | |
| ; CHECK-NEXT: [[TMP46:%.*]] = extractelement <4 x i1> [[TMP17]], i64 1 | |
| ; CHECK-NEXT: br i1 [[TMP46]], label [[PRED_STORE_IF24:%.*]], label [[PRED_STORE_CONTINUE25:%.*]] | |
| ; CHECK: pred.store.if24: | |
| ; CHECK-NEXT: [[TMP47:%.*]] = add i64 [[INDEX]], 9 | |
| ; CHECK-NEXT: [[TMP48:%.*]] = shl nsw i64 [[TMP47]], 2 | |
| ; CHECK-NEXT: [[TMP49:%.*]] = getelementptr double, ptr [[A]], i64 [[TMP48]] | |
| ; CHECK-NEXT: store double 0.000000e+00, ptr [[TMP49]], align 8 | |
| ; CHECK-NEXT: br label [[PRED_STORE_CONTINUE25]] | |
| ; CHECK: pred.store.continue25: | |
| ; CHECK-NEXT: [[TMP50:%.*]] = extractelement <4 x i1> [[TMP17]], i64 2 | |
| ; CHECK-NEXT: br i1 [[TMP50]], label [[PRED_STORE_IF26:%.*]], label [[PRED_STORE_CONTINUE27:%.*]] | |
| ; CHECK: pred.store.if26: | |
| ; CHECK-NEXT: [[TMP51:%.*]] = add i64 [[INDEX]], 10 | |
| ; CHECK-NEXT: [[TMP52:%.*]] = shl nsw i64 [[TMP51]], 2 | |
| ; CHECK-NEXT: [[TMP53:%.*]] = getelementptr double, ptr [[A]], i64 [[TMP52]] | |
| ; CHECK-NEXT: store double 0.000000e+00, ptr [[TMP53]], align 8 | |
| ; CHECK-NEXT: br label [[PRED_STORE_CONTINUE27]] | |
| ; CHECK: pred.store.continue27: | |
| ; CHECK-NEXT: [[TMP54:%.*]] = extractelement <4 x i1> [[TMP17]], i64 3 | |
| ; CHECK-NEXT: br i1 [[TMP54]], label [[PRED_STORE_IF28:%.*]], label [[PRED_STORE_CONTINUE29:%.*]] | |
| ; CHECK: pred.store.if28: | |
| ; CHECK-NEXT: [[TMP55:%.*]] = add i64 [[INDEX]], 11 | |
| ; CHECK-NEXT: [[TMP56:%.*]] = shl nsw i64 [[TMP55]], 2 | |
| ; CHECK-NEXT: [[TMP57:%.*]] = getelementptr double, ptr [[A]], i64 [[TMP56]] | |
| ; CHECK-NEXT: store double 0.000000e+00, ptr [[TMP57]], align 8 | |
| ; CHECK-NEXT: br label [[PRED_STORE_CONTINUE29]] | |
| ; CHECK: pred.store.continue29: | |
| ; CHECK-NEXT: [[TMP58:%.*]] = extractelement <4 x i1> [[TMP18]], i64 0 | |
| ; CHECK-NEXT: br i1 [[TMP58]], label [[PRED_STORE_IF30:%.*]], label [[PRED_STORE_CONTINUE31:%.*]] | |
| ; CHECK: pred.store.if30: | |
| ; CHECK-NEXT: store double 0.000000e+00, ptr [[TMP14]], align 8 | |
| ; CHECK-NEXT: br label [[PRED_STORE_CONTINUE31]] | |
| ; CHECK: pred.store.continue31: | |
| ; CHECK-NEXT: [[TMP59:%.*]] = extractelement <4 x i1> [[TMP18]], i64 1 | |
| ; CHECK-NEXT: br i1 [[TMP59]], label [[PRED_STORE_IF32:%.*]], label [[PRED_STORE_CONTINUE33:%.*]] | |
| ; CHECK: pred.store.if32: | |
| ; CHECK-NEXT: [[TMP60:%.*]] = add i64 [[INDEX]], 13 | |
| ; CHECK-NEXT: [[TMP61:%.*]] = shl nsw i64 [[TMP60]], 2 | |
| ; CHECK-NEXT: [[TMP62:%.*]] = getelementptr double, ptr [[A]], i64 [[TMP61]] | |
| ; CHECK-NEXT: store double 0.000000e+00, ptr [[TMP62]], align 8 | |
| ; CHECK-NEXT: br label [[PRED_STORE_CONTINUE33]] | |
| ; CHECK: pred.store.continue33: | |
| ; CHECK-NEXT: [[TMP63:%.*]] = extractelement <4 x i1> [[TMP18]], i64 2 | |
| ; CHECK-NEXT: br i1 [[TMP63]], label [[PRED_STORE_IF34:%.*]], label [[PRED_STORE_CONTINUE35:%.*]] | |
| ; CHECK: pred.store.if34: | |
| ; CHECK-NEXT: [[TMP64:%.*]] = add i64 [[INDEX]], 14 | |
| ; CHECK-NEXT: [[TMP65:%.*]] = shl nsw i64 [[TMP64]], 2 | |
| ; CHECK-NEXT: [[TMP66:%.*]] = getelementptr double, ptr [[A]], i64 [[TMP65]] | |
| ; CHECK-NEXT: store double 0.000000e+00, ptr [[TMP66]], align 8 | |
| ; CHECK-NEXT: br label [[PRED_STORE_CONTINUE35]] | |
| ; CHECK: pred.store.continue35: | |
| ; CHECK-NEXT: [[TMP67:%.*]] = extractelement <4 x i1> [[TMP18]], i64 3 | |
| ; CHECK-NEXT: br i1 [[TMP67]], label [[PRED_STORE_IF36:%.*]], label [[PRED_STORE_CONTINUE37]] | |
| ; CHECK: pred.store.if36: | |
| ; CHECK-NEXT: [[TMP68:%.*]] = add i64 [[INDEX]], 15 | |
| ; CHECK-NEXT: [[TMP69:%.*]] = shl nsw i64 [[TMP68]], 2 | |
| ; CHECK-NEXT: [[TMP70:%.*]] = getelementptr double, ptr [[A]], i64 [[TMP69]] | |
| ; CHECK-NEXT: store double 0.000000e+00, ptr [[TMP70]], align 8 | |
| ; CHECK-NEXT: br label [[PRED_STORE_CONTINUE37]] | |
| ; CHECK: pred.store.continue37: | |
| ; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 16 | |
| ; CHECK-NEXT: [[TMP71:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]] | |
| ; CHECK-NEXT: br i1 [[TMP71]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP6:![0-9]+]] | |
| ; CHECK: middle.block: | |
| ; CHECK-NEXT: br label [[VEC_EPILOG_ITER_CHECK:%.*]] | |
| ; CHECK: vec.epilog.iter.check: | |
| ; CHECK-NEXT: [[MIN_EPILOG_ITERS_CHECK:%.*]] = icmp ule i64 [[TMP3]], 4 | |
| ; CHECK-NEXT: br i1 [[MIN_EPILOG_ITERS_CHECK]], label [[VEC_EPILOG_SCALAR_PH]], label [[VEC_EPILOG_PH]], !prof [[PROF7:![0-9]+]] | |
| ; CHECK: vec.epilog.ph: | |
| ; CHECK-NEXT: [[VEC_EPILOG_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[VEC_EPILOG_ITER_CHECK]] ], [ 0, [[VECTOR_MAIN_LOOP_ITER_CHECK]] ] | |
| ; CHECK-NEXT: [[TMP72:%.*]] = and i64 [[TMP0]], 3 | |
| ; CHECK-NEXT: [[TMP73:%.*]] = icmp eq i64 [[TMP72]], 0 | |
| ; CHECK-NEXT: [[TMP74:%.*]] = select i1 [[TMP73]], i64 4, i64 [[TMP72]] | |
| ; CHECK-NEXT: [[N_VEC38:%.*]] = sub i64 [[TMP0]], [[TMP74]] | |
| ; CHECK-NEXT: br label [[VEC_EPILOG_VECTOR_BODY:%.*]] | |
| ; CHECK: vec.epilog.vector.body: | |
| ; CHECK-NEXT: [[INDEX39:%.*]] = phi i64 [ [[VEC_EPILOG_RESUME_VAL]], [[VEC_EPILOG_PH]] ], [ [[INDEX_NEXT50:%.*]], [[PRED_STORE_CONTINUE49:%.*]] ] | |
| ; CHECK-NEXT: [[TMP75:%.*]] = shl nsw i64 [[INDEX39]], 2 | |
| ; CHECK-NEXT: [[TMP76:%.*]] = getelementptr double, ptr [[A]], i64 [[TMP75]] | |
| ; CHECK-NEXT: [[WIDE_VEC40:%.*]] = load <16 x double>, ptr [[TMP76]], align 8 | |
| ; CHECK-NEXT: [[STRIDED_VEC41:%.*]] = shufflevector <16 x double> [[WIDE_VEC40]], <16 x double> poison, <4 x i32> <i32 0, i32 4, i32 8, i32 12> | |
| ; CHECK-NEXT: [[TMP77:%.*]] = fcmp oeq <4 x double> [[STRIDED_VEC41]], zeroinitializer | |
| ; CHECK-NEXT: [[TMP78:%.*]] = extractelement <4 x i1> [[TMP77]], i64 0 | |
| ; CHECK-NEXT: br i1 [[TMP78]], label [[PRED_STORE_IF42:%.*]], label [[PRED_STORE_CONTINUE43:%.*]] | |
| ; CHECK: pred.store.if42: | |
| ; CHECK-NEXT: store double 0.000000e+00, ptr [[TMP76]], align 8 | |
| ; CHECK-NEXT: br label [[PRED_STORE_CONTINUE43]] | |
| ; CHECK: pred.store.continue43: | |
| ; CHECK-NEXT: [[TMP79:%.*]] = extractelement <4 x i1> [[TMP77]], i64 1 | |
| ; CHECK-NEXT: br i1 [[TMP79]], label [[PRED_STORE_IF44:%.*]], label [[PRED_STORE_CONTINUE45:%.*]] | |
| ; CHECK: pred.store.if44: | |
| ; CHECK-NEXT: [[TMP80:%.*]] = add i64 [[INDEX39]], 1 | |
| ; CHECK-NEXT: [[TMP81:%.*]] = shl nsw i64 [[TMP80]], 2 | |
| ; CHECK-NEXT: [[TMP82:%.*]] = getelementptr double, ptr [[A]], i64 [[TMP81]] | |
| ; CHECK-NEXT: store double 0.000000e+00, ptr [[TMP82]], align 8 | |
| ; CHECK-NEXT: br label [[PRED_STORE_CONTINUE45]] | |
| ; CHECK: pred.store.continue45: | |
| ; CHECK-NEXT: [[TMP83:%.*]] = extractelement <4 x i1> [[TMP77]], i64 2 | |
| ; CHECK-NEXT: br i1 [[TMP83]], label [[PRED_STORE_IF46:%.*]], label [[PRED_STORE_CONTINUE47:%.*]] | |
| ; CHECK: pred.store.if46: | |
| ; CHECK-NEXT: [[TMP84:%.*]] = add i64 [[INDEX39]], 2 | |
| ; CHECK-NEXT: [[TMP85:%.*]] = shl nsw i64 [[TMP84]], 2 | |
| ; CHECK-NEXT: [[TMP86:%.*]] = getelementptr double, ptr [[A]], i64 [[TMP85]] | |
| ; CHECK-NEXT: store double 0.000000e+00, ptr [[TMP86]], align 8 | |
| ; CHECK-NEXT: br label [[PRED_STORE_CONTINUE47]] | |
| ; CHECK: pred.store.continue47: | |
| ; CHECK-NEXT: [[TMP87:%.*]] = extractelement <4 x i1> [[TMP77]], i64 3 | |
| ; CHECK-NEXT: br i1 [[TMP87]], label [[PRED_STORE_IF48:%.*]], label [[PRED_STORE_CONTINUE49]] | |
| ; CHECK: pred.store.if48: | |
| ; CHECK-NEXT: [[TMP88:%.*]] = add i64 [[INDEX39]], 3 | |
| ; CHECK-NEXT: [[TMP89:%.*]] = shl nsw i64 [[TMP88]], 2 | |
| ; CHECK-NEXT: [[TMP90:%.*]] = getelementptr double, ptr [[A]], i64 [[TMP89]] | |
| ; CHECK-NEXT: store double 0.000000e+00, ptr [[TMP90]], align 8 | |
| ; CHECK-NEXT: br label [[PRED_STORE_CONTINUE49]] | |
| ; CHECK: pred.store.continue49: | |
| ; CHECK-NEXT: [[INDEX_NEXT50]] = add nuw i64 [[INDEX39]], 4 | |
| ; CHECK-NEXT: [[TMP91:%.*]] = icmp eq i64 [[INDEX_NEXT50]], [[N_VEC38]] | |
| ; CHECK-NEXT: br i1 [[TMP91]], label [[VEC_EPILOG_MIDDLE_BLOCK:%.*]], label [[VEC_EPILOG_VECTOR_BODY]], !llvm.loop [[LOOP8:![0-9]+]] | |
| ; CHECK: vec.epilog.middle.block: | |
| ; CHECK-NEXT: br label [[VEC_EPILOG_SCALAR_PH]] | |
| ; CHECK: vec.epilog.scalar.ph: | |
| ; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC38]], [[VEC_EPILOG_MIDDLE_BLOCK]] ], [ [[N_VEC]], [[VEC_EPILOG_ITER_CHECK]] ], [ 0, [[ITER_CHECK:%.*]] ] | |
| ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] | |
| ; CHECK: loop.header: | |
| ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[VEC_EPILOG_SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] | |
| ; CHECK-NEXT: [[IV_SHL:%.*]] = shl nsw i64 [[IV]], 2 | |
| ; CHECK-NEXT: [[GEP_0:%.*]] = getelementptr nusw double, ptr [[A]], i64 [[IV_SHL]] | |
| ; CHECK-NEXT: [[L:%.*]] = load double, ptr [[GEP_0]], align 8 | |
| ; CHECK-NEXT: [[C:%.*]] = fcmp oeq double [[L]], 0.000000e+00 | |
| ; CHECK-NEXT: br i1 [[C]], label [[IF_THEN:%.*]], label [[LOOP_LATCH]] | |
| ; CHECK: if.then: | |
| ; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr double, ptr [[A]], i64 [[IV_SHL]] | |
| ; CHECK-NEXT: store double 0.000000e+00, ptr [[GEP_1]], align 8 | |
| ; CHECK-NEXT: br label [[LOOP_LATCH]] | |
| ; CHECK: loop.latch: | |
| ; CHECK-NEXT: [[IV_NEXT]] = add nsw i64 [[IV]], 1 | |
| ; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV]], [[N]] | |
| ; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP_HEADER]], !llvm.loop [[LOOP9:![0-9]+]] | |
| ; CHECK: exit: | |
| ; CHECK-NEXT: ret void | |
| ; | |
| entry: | |
| br label %loop.header | |
| loop.header: | |
| %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ] | |
| %iv.shl = shl nsw i64 %iv, 2 | |
| %gep.0 = getelementptr nusw double, ptr %A, i64 %iv.shl | |
| %l = load double, ptr %gep.0, align 8 | |
| %c = fcmp oeq double %l, 0.000000e+00 | |
| br i1 %c, label %if.then, label %loop.latch | |
| if.then: | |
| %gep.1 = getelementptr double, ptr %A, i64 %iv.shl | |
| store double 0.000000e+00, ptr %gep.1, align 8 | |
| br label %loop.latch | |
| loop.latch: | |
| %iv.next = add nsw i64 %iv, 1 | |
| %ec = icmp eq i64 %iv, %N | |
| br i1 %ec, label %exit, label %loop.header | |
| exit: | |
| ret void | |
| } | |
| ; Test for https://github.com/llvm/llvm-project/issues/129236. | |
| define i32 @cost_ashr_with_op_known_invariant_via_scev(i8 %a) { | |
| ; CHECK-LABEL: @cost_ashr_with_op_known_invariant_via_scev( | |
| ; CHECK-NEXT: entry: | |
| ; CHECK-NEXT: [[CMP_I:%.*]] = icmp eq i16 0, 0 | |
| ; CHECK-NEXT: [[CONV_I:%.*]] = sext i16 0 to i32 | |
| ; CHECK-NEXT: [[CONV5_I:%.*]] = sext i8 [[A:%.*]] to i32 | |
| ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] | |
| ; CHECK: loop.header: | |
| ; CHECK-NEXT: [[IV:%.*]] = phi i8 [ 100, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] | |
| ; CHECK-NEXT: br i1 [[CMP_I]], label [[THEN:%.*]], label [[ELSE:%.*]] | |
| ; CHECK: then: | |
| ; CHECK-NEXT: [[P_1:%.*]] = phi i32 [ [[REM_I:%.*]], [[ELSE]] ], [ 0, [[LOOP_HEADER]] ] | |
| ; CHECK-NEXT: [[SHR_I:%.*]] = ashr i32 [[CONV5_I]], [[P_1]] | |
| ; CHECK-NEXT: [[TOBOOL6_NOT_I:%.*]] = icmp eq i32 [[SHR_I]], 0 | |
| ; CHECK-NEXT: [[SEXT_I:%.*]] = shl i32 [[P_1]], 24 | |
| ; CHECK-NEXT: [[TMP0:%.*]] = ashr exact i32 [[SEXT_I]], 24 | |
| ; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[TOBOOL6_NOT_I]], i32 [[TMP0]], i32 0 | |
| ; CHECK-NEXT: br label [[LOOP_LATCH]] | |
| ; CHECK: else: | |
| ; CHECK-NEXT: [[REM_I]] = urem i32 -1, [[CONV_I]] | |
| ; CHECK-NEXT: [[CMP3_I:%.*]] = icmp sgt i32 [[REM_I]], 1 | |
| ; CHECK-NEXT: br i1 [[CMP3_I]], label [[LOOP_LATCH]], label [[THEN]] | |
| ; CHECK: loop.latch: | |
| ; CHECK-NEXT: [[P_2:%.*]] = phi i32 [ 0, [[ELSE]] ], [ [[TMP1]], [[THEN]] ] | |
| ; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], -1 | |
| ; CHECK-NEXT: [[EC:%.*]] = icmp eq i8 [[IV_NEXT]], 0 | |
| ; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP_HEADER]] | |
| ; CHECK: exit: | |
| ; CHECK-NEXT: [[P_2_LCSSA:%.*]] = phi i32 [ [[P_2]], [[LOOP_LATCH]] ] | |
| ; CHECK-NEXT: ret i32 [[P_2_LCSSA]] | |
| ; | |
| entry: | |
| %cmp.i = icmp eq i16 0, 0 | |
| %conv.i = sext i16 0 to i32 | |
| %conv5.i = sext i8 %a to i32 | |
| br label %loop.header | |
| loop.header: | |
| %iv = phi i8 [ 100, %entry ], [ %iv.next, %loop.latch ] | |
| br i1 %cmp.i, label %then, label %else | |
| then: | |
| %p.1 = phi i32 [ %rem.i, %else ], [ 0, %loop.header ] | |
| %shr.i = ashr i32 %conv5.i, %p.1 | |
| %tobool6.not.i = icmp eq i32 %shr.i, 0 | |
| %sext.i = shl i32 %p.1, 24 | |
| %2 = ashr exact i32 %sext.i, 24 | |
| %3 = select i1 %tobool6.not.i, i32 %2, i32 0 | |
| br label %loop.latch | |
| else: | |
| %rem.i = urem i32 -1, %conv.i | |
| %cmp3.i = icmp sgt i32 %rem.i, 1 | |
| br i1 %cmp3.i, label %loop.latch, label %then | |
| loop.latch: | |
| %p.2 = phi i32 [ 0, %else ], [ %3, %then ] | |
| %iv.next = add i8 %iv, -1 | |
| %ec = icmp eq i8 %iv.next, 0 | |
| br i1 %ec, label %exit, label %loop.header | |
| exit: | |
| ret i32 %p.2 | |
| } | |
| ; Test case for https://github.com/llvm/llvm-project/issues/156066. | |
| define void @sdiv_by_zero(ptr noalias %src, ptr noalias %dst, i32 %d) #2 { | |
| ; CHECK-LABEL: @sdiv_by_zero( | |
| ; CHECK-NEXT: bb: | |
| ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] | |
| ; CHECK: loop.header: | |
| ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ], [ 0, [[BB:%.*]] ] | |
| ; CHECK-NEXT: [[GEP_SRC:%.*]] = getelementptr inbounds i32, ptr [[SRC:%.*]], i64 [[IV]] | |
| ; CHECK-NEXT: [[L:%.*]] = load i32, ptr [[GEP_SRC]], align 4 | |
| ; CHECK-NEXT: [[ICMP:%.*]] = icmp eq i32 [[L]], 0 | |
| ; CHECK-NEXT: br i1 [[ICMP]], label [[LOOP_LATCH]], label [[THEN:%.*]] | |
| ; CHECK: then: | |
| ; CHECK-NEXT: [[SDIV:%.*]] = sdiv i32 [[L]], 0 | |
| ; CHECK-NEXT: br label [[LOOP_LATCH]] | |
| ; CHECK: loop.latch: | |
| ; CHECK-NEXT: [[MERGE:%.*]] = phi i32 [ [[SDIV]], [[THEN]] ], [ 0, [[LOOP_HEADER]] ] | |
| ; CHECK-NEXT: [[GEP_DST:%.*]] = getelementptr inbounds i32, ptr [[DST:%.*]], i64 [[IV]] | |
| ; CHECK-NEXT: store i32 [[MERGE]], ptr [[GEP_DST]], align 4 | |
| ; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1 | |
| ; CHECK-NEXT: [[EC:%.*]] = icmp ult i64 [[IV]], 16 | |
| ; CHECK-NEXT: br i1 [[EC]], label [[LOOP_HEADER]], label [[EXIT:%.*]] | |
| ; CHECK: exit: | |
| ; CHECK-NEXT: ret void | |
| ; | |
| bb: | |
| br label %loop.header | |
| loop.header: | |
| %iv = phi i64 [ %iv.next, %loop.latch ], [ 0, %bb ] | |
| %gep.src = getelementptr inbounds i32, ptr %src, i64 %iv | |
| %l = load i32, ptr %gep.src, align 4 | |
| %icmp = icmp eq i32 %l, 0 | |
| br i1 %icmp, label %loop.latch, label %then | |
| then: | |
| %sdiv = sdiv i32 %l, 0 | |
| br label %loop.latch | |
| loop.latch: | |
| %merge = phi i32 [ %sdiv, %then ], [ 0, %loop.header ] | |
| %gep.dst = getelementptr inbounds i32, ptr %dst, i64 %iv | |
| store i32 %merge, ptr %gep.dst, align 4 | |
| %iv.next = add i64 %iv, 1 | |
| %ec = icmp ult i64 %iv, 16 | |
| br i1 %ec, label %loop.header, label %exit | |
| exit: | |
| ret void | |
| } | |
| ; Test case for https://github.com/llvm/llvm-project/issues/158660. | |
| define i64 @test_predicated_udiv(i32 %d, i1 %c) #2 { | |
| ; CHECK-LABEL: @test_predicated_udiv( | |
| ; CHECK-NEXT: iter.check: | |
| ; CHECK-NEXT: br i1 false, label [[VEC_EPILOG_SCALAR_PH:%.*]], label [[VECTOR_MAIN_LOOP_ITER_CHECK:%.*]] | |
| ; CHECK: vector.main.loop.iter.check: | |
| ; CHECK-NEXT: br i1 false, label [[VEC_EPILOG_PH:%.*]], label [[VECTOR_PH:%.*]] | |
| ; CHECK: vector.ph: | |
| ; CHECK-NEXT: [[BROADCAST_SPLATINSERT2:%.*]] = insertelement <32 x i1> poison, i1 [[C:%.*]], i64 0 | |
| ; CHECK-NEXT: [[BROADCAST_SPLAT1:%.*]] = shufflevector <32 x i1> [[BROADCAST_SPLATINSERT2]], <32 x i1> poison, <32 x i32> zeroinitializer | |
| ; CHECK-NEXT: [[TMP0:%.*]] = xor <32 x i1> [[BROADCAST_SPLAT1]], splat (i1 true) | |
| ; CHECK-NEXT: [[BROADCAST_SPLATINSERT1:%.*]] = insertelement <32 x i32> poison, i32 [[D:%.*]], i64 0 | |
| ; CHECK-NEXT: [[BROADCAST_SPLAT2:%.*]] = shufflevector <32 x i32> [[BROADCAST_SPLATINSERT1]], <32 x i32> poison, <32 x i32> zeroinitializer | |
| ; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] | |
| ; CHECK: vector.body: | |
| ; CHECK-NEXT: [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ] | |
| ; CHECK-NEXT: [[VEC_IND:%.*]] = phi <32 x i32> [ <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30, i32 31>, [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[VECTOR_BODY]] ] | |
| ; CHECK-NEXT: [[STEP_ADD:%.*]] = add nuw <32 x i32> [[VEC_IND]], splat (i32 32) | |
| ; CHECK-NEXT: [[STEP_ADD_2:%.*]] = add nuw <32 x i32> [[STEP_ADD]], splat (i32 32) | |
| ; CHECK-NEXT: [[STEP_ADD_3:%.*]] = add nuw <32 x i32> [[STEP_ADD_2]], splat (i32 32) | |
| ; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 128 | |
| ; CHECK-NEXT: [[VEC_IND_NEXT]] = add <32 x i32> [[STEP_ADD_3]], splat (i32 32) | |
| ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[INDEX_NEXT]], 896 | |
| ; CHECK-NEXT: br i1 [[TMP1]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP10:![0-9]+]] | |
| ; CHECK: middle.block: | |
| ; CHECK-NEXT: [[TMP2:%.*]] = call <32 x i32> @llvm.usub.sat.v32i32(<32 x i32> [[STEP_ADD_3]], <32 x i32> splat (i32 1)) | |
| ; CHECK-NEXT: [[TMP3:%.*]] = call <32 x i32> @llvm.masked.udiv.v32i32(<32 x i32> [[TMP2]], <32 x i32> [[BROADCAST_SPLAT2]], <32 x i1> [[TMP0]]) | |
| ; CHECK-NEXT: [[TMP4:%.*]] = zext <32 x i32> [[TMP3]] to <32 x i64> | |
| ; CHECK-NEXT: [[PREDPHI:%.*]] = select i1 [[C]], <32 x i64> zeroinitializer, <32 x i64> [[TMP4]] | |
| ; CHECK-NEXT: [[TMP132:%.*]] = extractelement <32 x i64> [[PREDPHI]], i64 31 | |
| ; CHECK-NEXT: br i1 false, label [[EXIT:%.*]], label [[VEC_EPILOG_ITER_CHECK:%.*]] | |
| ; CHECK: vec.epilog.iter.check: | |
| ; CHECK-NEXT: br i1 false, label [[VEC_EPILOG_SCALAR_PH]], label [[VEC_EPILOG_PH]], !prof [[PROF11:![0-9]+]] | |
| ; CHECK: vec.epilog.ph: | |
| ; CHECK-NEXT: [[VEC_EPILOG_RESUME_VAL:%.*]] = phi i32 [ 896, [[VEC_EPILOG_ITER_CHECK]] ], [ 0, [[VECTOR_MAIN_LOOP_ITER_CHECK]] ] | |
| ; CHECK-NEXT: [[BROADCAST_SPLATINSERT3:%.*]] = insertelement <8 x i1> poison, i1 [[C]], i64 0 | |
| ; CHECK-NEXT: [[BROADCAST_SPLAT4:%.*]] = shufflevector <8 x i1> [[BROADCAST_SPLATINSERT3]], <8 x i1> poison, <8 x i32> zeroinitializer | |
| ; CHECK-NEXT: [[TMP6:%.*]] = xor <8 x i1> [[BROADCAST_SPLAT4]], splat (i1 true) | |
| ; CHECK-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement <8 x i32> poison, i32 [[D]], i64 0 | |
| ; CHECK-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector <8 x i32> [[BROADCAST_SPLATINSERT]], <8 x i32> poison, <8 x i32> zeroinitializer | |
| ; CHECK-NEXT: [[BROADCAST_SPLATINSERT7:%.*]] = insertelement <8 x i32> poison, i32 [[VEC_EPILOG_RESUME_VAL]], i64 0 | |
| ; CHECK-NEXT: [[BROADCAST_SPLAT8:%.*]] = shufflevector <8 x i32> [[BROADCAST_SPLATINSERT7]], <8 x i32> poison, <8 x i32> zeroinitializer | |
| ; CHECK-NEXT: [[INDUCTION:%.*]] = add <8 x i32> [[BROADCAST_SPLAT8]], <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> | |
| ; CHECK-NEXT: br label [[VEC_EPILOG_VECTOR_BODY:%.*]] | |
| ; CHECK: vec.epilog.vector.body: | |
| ; CHECK-NEXT: [[INDEX63:%.*]] = phi i32 [ [[VEC_EPILOG_RESUME_VAL]], [[VEC_EPILOG_PH]] ], [ [[INDEX_NEXT81:%.*]], [[VEC_EPILOG_VECTOR_BODY]] ] | |
| ; CHECK-NEXT: [[VEC_IND64:%.*]] = phi <8 x i32> [ [[INDUCTION]], [[VEC_EPILOG_PH]] ], [ [[VEC_IND_NEXT82:%.*]], [[VEC_EPILOG_VECTOR_BODY]] ] | |
| ; CHECK-NEXT: [[INDEX_NEXT81]] = add nuw i32 [[INDEX63]], 8 | |
| ; CHECK-NEXT: [[VEC_IND_NEXT82]] = add <8 x i32> [[VEC_IND64]], splat (i32 8) | |
| ; CHECK-NEXT: [[TMP167:%.*]] = icmp eq i32 [[INDEX_NEXT81]], 1000 | |
| ; CHECK-NEXT: br i1 [[TMP167]], label [[VEC_EPILOG_MIDDLE_BLOCK:%.*]], label [[VEC_EPILOG_VECTOR_BODY]], !llvm.loop [[LOOP12:![0-9]+]] | |
| ; CHECK: vec.epilog.middle.block: | |
| ; CHECK-NEXT: [[TMP8:%.*]] = call <8 x i32> @llvm.usub.sat.v8i32(<8 x i32> [[VEC_IND64]], <8 x i32> splat (i32 1)) | |
| ; CHECK-NEXT: [[TMP166:%.*]] = call <8 x i32> @llvm.masked.udiv.v8i32(<8 x i32> [[TMP8]], <8 x i32> [[BROADCAST_SPLAT]], <8 x i1> [[TMP6]]) | |
| ; CHECK-NEXT: [[TMP168:%.*]] = zext <8 x i32> [[TMP166]] to <8 x i64> | |
| ; CHECK-NEXT: [[PREDPHI83:%.*]] = select i1 [[C]], <8 x i64> zeroinitializer, <8 x i64> [[TMP168]] | |
| ; CHECK-NEXT: [[TMP169:%.*]] = extractelement <8 x i64> [[PREDPHI83]], i64 7 | |
| ; CHECK-NEXT: br i1 false, label [[EXIT]], label [[VEC_EPILOG_SCALAR_PH]] | |
| ; CHECK: vec.epilog.scalar.ph: | |
| ; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i32 [ 1000, [[VEC_EPILOG_MIDDLE_BLOCK]] ], [ 896, [[VEC_EPILOG_ITER_CHECK]] ], [ 0, [[ITER_CHECK:%.*]] ] | |
| ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] | |
| ; CHECK: loop.header: | |
| ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[BC_RESUME_VAL]], [[VEC_EPILOG_SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] | |
| ; CHECK-NEXT: br i1 [[C]], label [[LOOP_LATCH]], label [[THEN:%.*]] | |
| ; CHECK: then: | |
| ; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @llvm.usub.sat.i32(i32 [[IV]], i32 1) | |
| ; CHECK-NEXT: [[UDIV:%.*]] = udiv i32 [[CALL]], [[D]] | |
| ; CHECK-NEXT: [[ZEXT:%.*]] = zext i32 [[UDIV]] to i64 | |
| ; CHECK-NEXT: br label [[LOOP_LATCH]] | |
| ; CHECK: loop.latch: | |
| ; CHECK-NEXT: [[MERGE:%.*]] = phi i64 [ [[ZEXT]], [[THEN]] ], [ 0, [[LOOP_HEADER]] ] | |
| ; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1 | |
| ; CHECK-NEXT: [[EC:%.*]] = icmp eq i32 [[IV]], 1000 | |
| ; CHECK-NEXT: br i1 [[EC]], label [[EXIT]], label [[LOOP_HEADER]], !llvm.loop [[LOOP13:![0-9]+]] | |
| ; CHECK: exit: | |
| ; CHECK-NEXT: [[MERGE_LCSSA:%.*]] = phi i64 [ [[MERGE]], [[LOOP_LATCH]] ], [ [[TMP132]], [[MIDDLE_BLOCK]] ], [ [[TMP169]], [[VEC_EPILOG_MIDDLE_BLOCK]] ] | |
| ; CHECK-NEXT: ret i64 [[MERGE_LCSSA]] | |
| ; | |
| entry: | |
| br label %loop.header | |
| loop.header: | |
| %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] | |
| br i1 %c, label %loop.latch, label %then | |
| then: | |
| %call = tail call i32 @llvm.usub.sat.i32(i32 %iv, i32 1) | |
| %udiv = udiv i32 %call, %d | |
| %zext = zext i32 %udiv to i64 | |
| br label %loop.latch | |
| loop.latch: | |
| %merge = phi i64 [ %zext, %then ], [ 0, %loop.header ] | |
| %iv.next = add i32 %iv, 1 | |
| %ec = icmp eq i32 %iv, 1000 | |
| br i1 %ec, label %exit, label %loop.header | |
| exit: | |
| ret i64 %merge | |
| } | |
| attributes #0 = { "target-cpu"="znver4" } | |
| attributes #1 = { "target-features"="+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512vl" } | |
| attributes #2 = { "target-cpu"="znver3" } |