Skip to content

Commit e571aff

Browse files
committed
[LV] Bundle (partial) reductions with a mul of a constant
A reduction (including partial reductions) with a multiply of a constant value can be bundled by first converting it from `reduce.add(mul(ext, const))` to `reduce.add(mul(ext, ext(const)))` as long as it is safe to extend the constant. This PR adds such bundling by first truncating the constant to the source type of the other extend, then extending it to the destination type of the extend. The first truncate is necessary so that the types of each extend's operand are then the same, and the call to canConstantBeExtended proves that the extend following a truncate is safe to do. The truncate is removed by optimisations.
1 parent 911e5aa commit e571aff

File tree

2 files changed

+292
-0
lines changed

2 files changed

+292
-0
lines changed

llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3650,6 +3650,32 @@ tryToMatchAndCreateMulAccumulateReduction(VPReductionRecipe *Red,
36503650
dyn_cast_if_present<VPWidenCastRecipe>(B->getDefiningRecipe());
36513651
auto *Mul = cast<VPWidenRecipe>(VecOp->getDefiningRecipe());
36523652

3653+
// Match reduce.add(mul(ext, const)) and convert it to
3654+
// reduce.add(mul(ext, ext(const)))
3655+
if (RecipeA && !RecipeB && B->isLiveIn()) {
3656+
Type *NarrowTy = Ctx.Types.inferScalarType(RecipeA->getOperand(0));
3657+
Instruction::CastOps ExtOpc = RecipeA->getOpcode();
3658+
auto *Const = dyn_cast<ConstantInt>(B->getLiveInIRValue());
3659+
if (Const &&
3660+
llvm::canConstantBeExtended(
3661+
Const, NarrowTy, TTI::getPartialReductionExtendKind(ExtOpc))) {
3662+
// The truncate ensures that the type of each extended operand is the
3663+
// same, and it's been proven that the constant can be extended from
3664+
// NarrowTy safely. Necessary since RecipeA's extended operand would be
3665+
// e.g. an i8, while the const will likely be an i32. This will be
3666+
// elided by later optimisations.
3667+
auto *Trunc =
3668+
new VPWidenCastRecipe(Instruction::CastOps::Trunc, B, NarrowTy);
3669+
Trunc->insertBefore(*RecipeA->getParent(),
3670+
std::next(RecipeA->getIterator()));
3671+
3672+
Type *WideTy = Ctx.Types.inferScalarType(RecipeA);
3673+
RecipeB = new VPWidenCastRecipe(ExtOpc, Trunc, WideTy);
3674+
RecipeB->insertAfter(Trunc);
3675+
Mul->setOperand(1, RecipeB);
3676+
}
3677+
}
3678+
36533679
// Match reduce.add/sub(mul(ext, ext)).
36543680
if (RecipeA && RecipeB && match(RecipeA, m_ZExtOrSExt(m_VPValue())) &&
36553681
match(RecipeB, m_ZExtOrSExt(m_VPValue())) &&

llvm/test/Transforms/LoopVectorize/vplan-printing-reductions.ll

Lines changed: 266 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -800,3 +800,269 @@ exit:
800800
%r.0.lcssa = phi i64 [ %rdx.next, %loop ]
801801
ret i64 %r.0.lcssa
802802
}
803+
804+
define i32 @print_mulacc_extended_const(ptr %start, ptr %end) {
805+
; CHECK-LABEL: 'print_mulacc_extended_const'
806+
; CHECK: VPlan 'Initial VPlan for VF={4},UF>=1' {
807+
; CHECK-NEXT: Live-in vp<%0> = VF
808+
; CHECK-NEXT: Live-in vp<%1> = VF * UF
809+
; CHECK-NEXT: Live-in vp<%2> = vector-trip-count
810+
; CHECK-NEXT: vp<%3> = original trip-count
811+
; CHECK-EMPTY:
812+
; CHECK-NEXT: ir-bb<entry>:
813+
; CHECK-NEXT: EMIT vp<%3> = EXPAND SCEV (1 + (-1 * (ptrtoint ptr %start to i64)) + (ptrtoint ptr %end to i64))
814+
; CHECK-NEXT: Successor(s): scalar.ph, vector.ph
815+
; CHECK-EMPTY:
816+
; CHECK-NEXT: vector.ph:
817+
; CHECK-NEXT: vp<%4> = DERIVED-IV ir<%start> + vp<%2> * ir<1>
818+
; CHECK-NEXT: EMIT vp<%5> = reduction-start-vector ir<0>, ir<0>, ir<1>
819+
; CHECK-NEXT: Successor(s): vector loop
820+
; CHECK-EMPTY:
821+
; CHECK-NEXT: <x1> vector loop: {
822+
; CHECK-NEXT: vector.body:
823+
; CHECK-NEXT: EMIT vp<%6> = CANONICAL-INDUCTION ir<0>, vp<%index.next>
824+
; CHECK-NEXT: WIDEN-REDUCTION-PHI ir<%red> = phi vp<%5>, vp<%9>
825+
; CHECK-NEXT: vp<%7> = SCALAR-STEPS vp<%6>, ir<1>, vp<%0>
826+
; CHECK-NEXT: EMIT vp<%next.gep> = ptradd ir<%start>, vp<%7>
827+
; CHECK-NEXT: vp<%8> = vector-pointer vp<%next.gep>
828+
; CHECK-NEXT: WIDEN ir<%l> = load vp<%8>
829+
; CHECK-NEXT: EXPRESSION vp<%9> = ir<%red> + reduce.add (mul (ir<%l> zext to i32), (ir<63> zext to i32))
830+
; CHECK-NEXT: EMIT vp<%index.next> = add nuw vp<%6>, vp<%1>
831+
; CHECK-NEXT: EMIT branch-on-count vp<%index.next>, vp<%2>
832+
; CHECK-NEXT: No successors
833+
; CHECK-NEXT: }
834+
; CHECK-NEXT: Successor(s): middle.block
835+
; CHECK-EMPTY:
836+
; CHECK-NEXT: middle.block:
837+
; CHECK-NEXT: EMIT vp<%11> = compute-reduction-result ir<%red>, vp<%9>
838+
; CHECK-NEXT: EMIT vp<%cmp.n> = icmp eq vp<%3>, vp<%2>
839+
; CHECK-NEXT: EMIT branch-on-cond vp<%cmp.n>
840+
; CHECK-NEXT: Successor(s): ir-bb<exit>, scalar.ph
841+
; CHECK-EMPTY:
842+
; CHECK-NEXT: ir-bb<exit>:
843+
; CHECK-NEXT: IR %red.next.lcssa = phi i32 [ %red.next, %loop ] (extra operand: vp<%11> from middle.block)
844+
; CHECK-NEXT: No successors
845+
; CHECK-EMPTY:
846+
; CHECK-NEXT: scalar.ph:
847+
; CHECK-NEXT: EMIT-SCALAR vp<%bc.resume.val> = phi [ vp<%4>, middle.block ], [ ir<%start>, ir-bb<entry> ]
848+
; CHECK-NEXT: EMIT-SCALAR vp<%bc.merge.rdx> = phi [ vp<%11>, middle.block ], [ ir<0>, ir-bb<entry> ]
849+
; CHECK-NEXT: Successor(s): ir-bb<loop>
850+
; CHECK-EMPTY:
851+
; CHECK-NEXT: ir-bb<loop>:
852+
; CHECK-NEXT: IR %ptr.iv = phi ptr [ %start, %entry ], [ %gep.iv.next, %loop ] (extra operand: vp<%bc.resume.val> from scalar.ph)
853+
; CHECK-NEXT: IR %red = phi i32 [ 0, %entry ], [ %red.next, %loop ] (extra operand: vp<%bc.merge.rdx> from scalar.ph)
854+
; CHECK-NEXT: IR %l = load i8, ptr %ptr.iv, align 1
855+
; CHECK-NEXT: IR %l.ext = zext i8 %l to i32
856+
; CHECK-NEXT: IR %mul = mul i32 %l.ext, 63
857+
; CHECK-NEXT: IR %red.next = add i32 %red, %mul
858+
; CHECK-NEXT: IR %gep.iv.next = getelementptr i8, ptr %ptr.iv, i64 1
859+
; CHECK-NEXT: IR %ec = icmp eq ptr %ptr.iv, %end
860+
; CHECK-NEXT: No successors
861+
; CHECK-NEXT: }
862+
; CHECK: VPlan 'Final VPlan for VF={4},UF={1}' {
863+
; CHECK-NEXT: Live-in ir<%1> = original trip-count
864+
; CHECK-EMPTY:
865+
; CHECK-NEXT: ir-bb<entry>:
866+
; CHECK-NEXT: IR %start2 = ptrtoint ptr %start to i64
867+
; CHECK-NEXT: IR %end1 = ptrtoint ptr %end to i64
868+
; CHECK-NEXT: IR %0 = add i64 %end1, 1
869+
; CHECK-NEXT: IR %1 = sub i64 %0, %start2
870+
; CHECK-NEXT: EMIT vp<%min.iters.check> = icmp ult ir<%1>, ir<4>
871+
; CHECK-NEXT: EMIT branch-on-cond vp<%min.iters.check>
872+
; CHECK-NEXT: Successor(s): ir-bb<scalar.ph>, vector.ph
873+
; CHECK-EMPTY:
874+
; CHECK-NEXT: vector.ph:
875+
; CHECK-NEXT: EMIT vp<%n.mod.vf> = urem ir<%1>, ir<4>
876+
; CHECK-NEXT: EMIT vp<%n.vec> = sub ir<%1>, vp<%n.mod.vf>
877+
; CHECK-NEXT: vp<%3> = DERIVED-IV ir<%start> + vp<%n.vec> * ir<1>
878+
; CHECK-NEXT: Successor(s): vector.body
879+
; CHECK-EMPTY:
880+
; CHECK-NEXT: vector.body:
881+
; CHECK-NEXT: EMIT-SCALAR vp<%index> = phi [ ir<0>, vector.ph ], [ vp<%index.next>, vector.body ]
882+
; CHECK-NEXT: WIDEN-REDUCTION-PHI ir<%red> = phi ir<0>, ir<%red.next>
883+
; CHECK-NEXT: EMIT vp<%next.gep> = ptradd ir<%start>, vp<%index>
884+
; CHECK-NEXT: WIDEN ir<%l> = load vp<%next.gep>
885+
; CHECK-NEXT: WIDEN-CAST ir<%l.ext> = zext ir<%l> to i32
886+
; CHECK-NEXT: WIDEN ir<%mul> = mul ir<%l.ext>, ir<63>
887+
; CHECK-NEXT: REDUCE ir<%red.next> = ir<%red> + reduce.add (ir<%mul>)
888+
; CHECK-NEXT: EMIT vp<%index.next> = add nuw vp<%index>, ir<4>
889+
; CHECK-NEXT: EMIT branch-on-count vp<%index.next>, vp<%n.vec>
890+
; CHECK-NEXT: Successor(s): middle.block, vector.body
891+
; CHECK-EMPTY:
892+
; CHECK-NEXT: middle.block:
893+
; CHECK-NEXT: EMIT vp<%5> = compute-reduction-result ir<%red>, ir<%red.next>
894+
; CHECK-NEXT: EMIT vp<%cmp.n> = icmp eq ir<%1>, vp<%n.vec>
895+
; CHECK-NEXT: EMIT branch-on-cond vp<%cmp.n>
896+
; CHECK-NEXT: Successor(s): ir-bb<exit>, ir-bb<scalar.ph>
897+
; CHECK-EMPTY:
898+
; CHECK-NEXT: ir-bb<exit>:
899+
; CHECK-NEXT: IR %red.next.lcssa = phi i32 [ %red.next, %loop ] (extra operand: vp<%5> from middle.block)
900+
; CHECK-NEXT: No successors
901+
; CHECK-EMPTY:
902+
; CHECK-NEXT: ir-bb<scalar.ph>:
903+
; CHECK-NEXT: EMIT-SCALAR vp<%bc.resume.val> = phi [ vp<%3>, middle.block ], [ ir<%start>, ir-bb<entry> ]
904+
; CHECK-NEXT: EMIT-SCALAR vp<%bc.merge.rdx> = phi [ vp<%5>, middle.block ], [ ir<0>, ir-bb<entry> ]
905+
; CHECK-NEXT: Successor(s): ir-bb<loop>
906+
; CHECK-EMPTY:
907+
; CHECK-NEXT: ir-bb<loop>:
908+
; CHECK-NEXT: IR %ptr.iv = phi ptr [ %start, %scalar.ph ], [ %gep.iv.next, %loop ] (extra operand: vp<%bc.resume.val> from ir-bb<scalar.ph>)
909+
; CHECK-NEXT: IR %red = phi i32 [ 0, %scalar.ph ], [ %red.next, %loop ] (extra operand: vp<%bc.merge.rdx> from ir-bb<scalar.ph>)
910+
; CHECK-NEXT: IR %l = load i8, ptr %ptr.iv, align 1
911+
; CHECK-NEXT: IR %l.ext = zext i8 %l to i32
912+
; CHECK-NEXT: IR %mul = mul i32 %l.ext, 63
913+
; CHECK-NEXT: IR %red.next = add i32 %red, %mul
914+
; CHECK-NEXT: IR %gep.iv.next = getelementptr i8, ptr %ptr.iv, i64 1
915+
; CHECK-NEXT: IR %ec = icmp eq ptr %ptr.iv, %end
916+
; CHECK-NEXT: No successors
917+
; CHECK-NEXT: }
918+
entry:
919+
br label %loop
920+
921+
loop:
922+
%ptr.iv = phi ptr [ %start, %entry ], [ %gep.iv.next, %loop ]
923+
%red = phi i32 [ 0, %entry ], [ %red.next, %loop ]
924+
%l = load i8, ptr %ptr.iv, align 1
925+
%l.ext = zext i8 %l to i32
926+
%mul = mul i32 %l.ext, 63
927+
%red.next = add i32 %red, %mul
928+
%gep.iv.next = getelementptr i8, ptr %ptr.iv, i64 1
929+
%ec = icmp eq ptr %ptr.iv, %end
930+
br i1 %ec, label %exit, label %loop
931+
932+
exit:
933+
ret i32 %red.next
934+
}
935+
936+
; Constants >= 128 cannot be treated as sign-extended, so the expression shouldn't extend 128
937+
define i32 @print_mulacc_not_extended_const(ptr %start, ptr %end) {
938+
; CHECK: VPlan 'Initial VPlan for VF={4},UF>=1' {
939+
; CHECK-NEXT: Live-in vp<%0> = VF
940+
; CHECK-NEXT: Live-in vp<%1> = VF * UF
941+
; CHECK-NEXT: Live-in vp<%2> = vector-trip-count
942+
; CHECK-NEXT: vp<%3> = original trip-count
943+
; CHECK-EMPTY:
944+
; CHECK-NEXT: ir-bb<entry>:
945+
; CHECK-NEXT: EMIT vp<%3> = EXPAND SCEV (1 + (-1 * (ptrtoint ptr %start to i64)) + (ptrtoint ptr %end to i64))
946+
; CHECK-NEXT: Successor(s): scalar.ph, vector.ph
947+
; CHECK-EMPTY:
948+
; CHECK-NEXT: vector.ph:
949+
; CHECK-NEXT: vp<%4> = DERIVED-IV ir<%start> + vp<%2> * ir<1>
950+
; CHECK-NEXT: EMIT vp<%5> = reduction-start-vector ir<0>, ir<0>, ir<1>
951+
; CHECK-NEXT: Successor(s): vector loop
952+
; CHECK-EMPTY:
953+
; CHECK-NEXT: <x1> vector loop: {
954+
; CHECK-NEXT: vector.body:
955+
; CHECK-NEXT: EMIT vp<%6> = CANONICAL-INDUCTION ir<0>, vp<%index.next>
956+
; CHECK-NEXT: WIDEN-REDUCTION-PHI ir<%red> = phi vp<%5>, vp<%9>
957+
; CHECK-NEXT: vp<%7> = SCALAR-STEPS vp<%6>, ir<1>, vp<%0>
958+
; CHECK-NEXT: EMIT vp<%next.gep> = ptradd ir<%start>, vp<%7>
959+
; CHECK-NEXT: vp<%8> = vector-pointer vp<%next.gep>
960+
; CHECK-NEXT: WIDEN ir<%l> = load vp<%8>
961+
; CHECK-NEXT: WIDEN-CAST ir<%l.ext> = sext ir<%l> to i32
962+
; CHECK-NEXT: EXPRESSION vp<%9> = ir<%red> + reduce.add (mul ir<%l.ext>, ir<128>)
963+
; CHECK-NEXT: EMIT vp<%index.next> = add nuw vp<%6>, vp<%1>
964+
; CHECK-NEXT: EMIT branch-on-count vp<%index.next>, vp<%2>
965+
; CHECK-NEXT: No successors
966+
; CHECK-NEXT: }
967+
; CHECK-NEXT: Successor(s): middle.block
968+
; CHECK-EMPTY:
969+
; CHECK-NEXT: middle.block:
970+
; CHECK-NEXT: EMIT vp<%11> = compute-reduction-result ir<%red>, vp<%9>
971+
; CHECK-NEXT: EMIT vp<%cmp.n> = icmp eq vp<%3>, vp<%2>
972+
; CHECK-NEXT: EMIT branch-on-cond vp<%cmp.n>
973+
; CHECK-NEXT: Successor(s): ir-bb<exit>, scalar.ph
974+
; CHECK-EMPTY:
975+
; CHECK-NEXT: ir-bb<exit>:
976+
; CHECK-NEXT: IR %red.next.lcssa = phi i32 [ %red.next, %loop ] (extra operand: vp<%11> from middle.block)
977+
; CHECK-NEXT: No successors
978+
; CHECK-EMPTY:
979+
; CHECK-NEXT: scalar.ph:
980+
; CHECK-NEXT: EMIT-SCALAR vp<%bc.resume.val> = phi [ vp<%4>, middle.block ], [ ir<%start>, ir-bb<entry> ]
981+
; CHECK-NEXT: EMIT-SCALAR vp<%bc.merge.rdx> = phi [ vp<%11>, middle.block ], [ ir<0>, ir-bb<entry> ]
982+
; CHECK-NEXT: Successor(s): ir-bb<loop>
983+
; CHECK-EMPTY:
984+
; CHECK-NEXT: ir-bb<loop>:
985+
; CHECK-NEXT: IR %ptr.iv = phi ptr [ %start, %entry ], [ %gep.iv.next, %loop ] (extra operand: vp<%bc.resume.val> from scalar.ph)
986+
; CHECK-NEXT: IR %red = phi i32 [ 0, %entry ], [ %red.next, %loop ] (extra operand: vp<%bc.merge.rdx> from scalar.ph)
987+
; CHECK-NEXT: IR %l = load i8, ptr %ptr.iv, align 1
988+
; CHECK-NEXT: IR %l.ext = sext i8 %l to i32
989+
; CHECK-NEXT: IR %mul = mul i32 %l.ext, 128
990+
; CHECK-NEXT: IR %red.next = add i32 %red, %mul
991+
; CHECK-NEXT: IR %gep.iv.next = getelementptr i8, ptr %ptr.iv, i64 1
992+
; CHECK-NEXT: IR %ec = icmp eq ptr %ptr.iv, %end
993+
; CHECK-NEXT: No successors
994+
; CHECK-NEXT: }
995+
; CHECK: VPlan 'Final VPlan for VF={4},UF={1}' {
996+
; CHECK-NEXT: Live-in ir<%1> = original trip-count
997+
; CHECK-EMPTY:
998+
; CHECK-NEXT: ir-bb<entry>:
999+
; CHECK-NEXT: IR %start2 = ptrtoint ptr %start to i64
1000+
; CHECK-NEXT: IR %end1 = ptrtoint ptr %end to i64
1001+
; CHECK-NEXT: IR %0 = add i64 %end1, 1
1002+
; CHECK-NEXT: IR %1 = sub i64 %0, %start2
1003+
; CHECK-NEXT: EMIT vp<%min.iters.check> = icmp ult ir<%1>, ir<4>
1004+
; CHECK-NEXT: EMIT branch-on-cond vp<%min.iters.check>
1005+
; CHECK-NEXT: Successor(s): ir-bb<scalar.ph>, vector.ph
1006+
; CHECK-EMPTY:
1007+
; CHECK-NEXT: vector.ph:
1008+
; CHECK-NEXT: EMIT vp<%n.mod.vf> = urem ir<%1>, ir<4>
1009+
; CHECK-NEXT: EMIT vp<%n.vec> = sub ir<%1>, vp<%n.mod.vf>
1010+
; CHECK-NEXT: vp<%3> = DERIVED-IV ir<%start> + vp<%n.vec> * ir<1>
1011+
; CHECK-NEXT: Successor(s): vector.body
1012+
; CHECK-EMPTY:
1013+
; CHECK-NEXT: vector.body:
1014+
; CHECK-NEXT: EMIT-SCALAR vp<%index> = phi [ ir<0>, vector.ph ], [ vp<%index.next>, vector.body ]
1015+
; CHECK-NEXT: WIDEN-REDUCTION-PHI ir<%red> = phi ir<0>, ir<%red.next>
1016+
; CHECK-NEXT: EMIT vp<%next.gep> = ptradd ir<%start>, vp<%index>
1017+
; CHECK-NEXT: WIDEN ir<%l> = load vp<%next.gep>
1018+
; CHECK-NEXT: WIDEN-CAST ir<%l.ext> = sext ir<%l> to i32
1019+
; CHECK-NEXT: WIDEN ir<%mul> = mul ir<%l.ext>, ir<128>
1020+
; CHECK-NEXT: REDUCE ir<%red.next> = ir<%red> + reduce.add (ir<%mul>)
1021+
; CHECK-NEXT: EMIT vp<%index.next> = add nuw vp<%index>, ir<4>
1022+
; CHECK-NEXT: EMIT branch-on-count vp<%index.next>, vp<%n.vec>
1023+
; CHECK-NEXT: Successor(s): middle.block, vector.body
1024+
; CHECK-EMPTY:
1025+
; CHECK-NEXT: middle.block:
1026+
; CHECK-NEXT: EMIT vp<%5> = compute-reduction-result ir<%red>, ir<%red.next>
1027+
; CHECK-NEXT: EMIT vp<%cmp.n> = icmp eq ir<%1>, vp<%n.vec>
1028+
; CHECK-NEXT: EMIT branch-on-cond vp<%cmp.n>
1029+
; CHECK-NEXT: Successor(s): ir-bb<exit>, ir-bb<scalar.ph>
1030+
; CHECK-EMPTY:
1031+
; CHECK-NEXT: ir-bb<exit>:
1032+
; CHECK-NEXT: IR %red.next.lcssa = phi i32 [ %red.next, %loop ] (extra operand: vp<%5> from middle.block)
1033+
; CHECK-NEXT: No successors
1034+
; CHECK-EMPTY:
1035+
; CHECK-NEXT: ir-bb<scalar.ph>:
1036+
; CHECK-NEXT: EMIT-SCALAR vp<%bc.resume.val> = phi [ vp<%3>, middle.block ], [ ir<%start>, ir-bb<entry> ]
1037+
; CHECK-NEXT: EMIT-SCALAR vp<%bc.merge.rdx> = phi [ vp<%5>, middle.block ], [ ir<0>, ir-bb<entry> ]
1038+
; CHECK-NEXT: Successor(s): ir-bb<loop>
1039+
; CHECK-EMPTY:
1040+
; CHECK-NEXT: ir-bb<loop>:
1041+
; CHECK-NEXT: IR %ptr.iv = phi ptr [ %start, %scalar.ph ], [ %gep.iv.next, %loop ] (extra operand: vp<%bc.resume.val> from ir-bb<scalar.ph>)
1042+
; CHECK-NEXT: IR %red = phi i32 [ 0, %scalar.ph ], [ %red.next, %loop ] (extra operand: vp<%bc.merge.rdx> from ir-bb<scalar.ph>)
1043+
; CHECK-NEXT: IR %l = load i8, ptr %ptr.iv, align 1
1044+
; CHECK-NEXT: IR %l.ext = sext i8 %l to i32
1045+
; CHECK-NEXT: IR %mul = mul i32 %l.ext, 128
1046+
; CHECK-NEXT: IR %red.next = add i32 %red, %mul
1047+
; CHECK-NEXT: IR %gep.iv.next = getelementptr i8, ptr %ptr.iv, i64 1
1048+
; CHECK-NEXT: IR %ec = icmp eq ptr %ptr.iv, %end
1049+
; CHECK-NEXT: No successors
1050+
; CHECK-NEXT: }
1051+
entry:
1052+
br label %loop
1053+
1054+
loop:
1055+
%ptr.iv = phi ptr [ %start, %entry ], [ %gep.iv.next, %loop ]
1056+
%red = phi i32 [ 0, %entry ], [ %red.next, %loop ]
1057+
%l = load i8, ptr %ptr.iv, align 1
1058+
%l.ext = sext i8 %l to i32
1059+
%mul = mul i32 %l.ext, 128
1060+
%red.next = add i32 %red, %mul
1061+
%gep.iv.next = getelementptr i8, ptr %ptr.iv, i64 1
1062+
%ec = icmp eq ptr %ptr.iv, %end
1063+
br i1 %ec, label %exit, label %loop
1064+
1065+
exit:
1066+
%red.next.lcssa = phi i32 [ %red.next, %loop ]
1067+
ret i32 %red.next.lcssa
1068+
}

0 commit comments

Comments
 (0)