diff options
author | Krzysztof Parzyszek <kparzysz@codeaurora.org> | 2016-07-26 20:30:30 +0000 |
---|---|---|
committer | Krzysztof Parzyszek <kparzysz@codeaurora.org> | 2016-07-26 20:30:30 +0000 |
commit | 2a480599bb688dc9bb4fc24b60958c15968a3b85 (patch) | |
tree | 9099ea96dd42db51342491762624af2a9b5d1aad | |
parent | ad2b717f2c8fcc279cf13aa51349012c3710c987 (diff) | |
download | bcm5719-llvm-2a480599bb688dc9bb4fc24b60958c15968a3b85.tar.gz bcm5719-llvm-2a480599bb688dc9bb4fc24b60958c15968a3b85.zip |
[Hexagon] Post-increment loads/stores enhancements
- Generate vector post-increment stores more aggressively.
- Predicate post-increment and vector stores in early if-conversion.
llvm-svn: 276800
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonEarlyIfConv.cpp | 138 | ||||
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonISelLowering.cpp | 17 | ||||
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonInstrInfoV60.td | 44 | ||||
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp | 10 | ||||
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.h | 2 | ||||
-rw-r--r-- | llvm/test/CodeGen/Hexagon/early-if-vecpi.ll | 69 |
6 files changed, 168 insertions, 112 deletions
diff --git a/llvm/lib/Target/Hexagon/HexagonEarlyIfConv.cpp b/llvm/lib/Target/Hexagon/HexagonEarlyIfConv.cpp index 2665acd19fb..2f19120f186 100644 --- a/llvm/lib/Target/Hexagon/HexagonEarlyIfConv.cpp +++ b/llvm/lib/Target/Hexagon/HexagonEarlyIfConv.cpp @@ -134,7 +134,7 @@ namespace { public: static char ID; HexagonEarlyIfConversion() : MachineFunctionPass(ID), - TII(0), TRI(0), MFN(0), MRI(0), MDT(0), MLI(0) { + HII(0), TRI(0), MFN(0), MRI(0), MDT(0), MLI(0) { initializeHexagonEarlyIfConversionPass(*PassRegistry::getPassRegistry()); } const char *getPassName() const override { @@ -185,7 +185,7 @@ namespace { void mergeBlocks(MachineBasicBlock *PredB, MachineBasicBlock *SuccB); void simplifyFlowGraph(const FlowPattern &FP); - const TargetInstrInfo *TII; + const HexagonInstrInfo *HII; const TargetRegisterInfo *TRI; MachineFunction *MFN; MachineRegisterInfo *MRI; @@ -443,7 +443,7 @@ unsigned HexagonEarlyIfConversion::computePhiCost(MachineBasicBlock *B) const { } MachineInstr *Def1 = MRI->getVRegDef(RO1.getReg()); MachineInstr *Def3 = MRI->getVRegDef(RO3.getReg()); - if (!TII->isPredicable(*Def1) || !TII->isPredicable(*Def3)) + if (!HII->isPredicable(*Def1) || !HII->isPredicable(*Def3)) Cost++; } return Cost; @@ -612,29 +612,26 @@ bool HexagonEarlyIfConversion::visitLoop(MachineLoop *L) { bool HexagonEarlyIfConversion::isPredicableStore(const MachineInstr *MI) const { - // Exclude post-increment stores. Those return a value, so we cannot - // predicate them. + // HexagonInstrInfo::isPredicable will consider these stores are non- + // -predicable if the offset would become constant-extended after + // predication. unsigned Opc = MI->getOpcode(); - using namespace Hexagon; switch (Opc) { - // Store byte: - case S2_storerb_io: case S4_storerb_rr: - case S2_storerbabs: case S4_storeirb_io: case S2_storerbgp: - // Store halfword: - case S2_storerh_io: case S4_storerh_rr: - case S2_storerhabs: case S4_storeirh_io: case S2_storerhgp: - // Store upper halfword: - case S2_storerf_io: case S4_storerf_rr: - case S2_storerfabs: case S2_storerfgp: - // Store word: - case S2_storeri_io: case S4_storeri_rr: - case S2_storeriabs: case S4_storeiri_io: case S2_storerigp: - // Store doubleword: - case S2_storerd_io: case S4_storerd_rr: - case S2_storerdabs: case S2_storerdgp: + case Hexagon::S2_storerb_io: + case Hexagon::S2_storerbnew_io: + case Hexagon::S2_storerh_io: + case Hexagon::S2_storerhnew_io: + case Hexagon::S2_storeri_io: + case Hexagon::S2_storerinew_io: + case Hexagon::S2_storerd_io: + case Hexagon::S4_storeirb_io: + case Hexagon::S4_storeirh_io: + case Hexagon::S4_storeiri_io: return true; } - return false; + + // TargetInstrInfo::isPredicable takes a non-const pointer. + return MI->mayStore() && HII->isPredicable(const_cast<MachineInstr&>(*MI)); } @@ -653,53 +650,7 @@ bool HexagonEarlyIfConversion::isSafeToSpeculate(const MachineInstr *MI) unsigned HexagonEarlyIfConversion::getCondStoreOpcode(unsigned Opc, bool IfTrue) const { - // Exclude post-increment stores. - using namespace Hexagon; - switch (Opc) { - case S2_storerb_io: - return IfTrue ? S2_pstorerbt_io : S2_pstorerbf_io; - case S4_storerb_rr: - return IfTrue ? S4_pstorerbt_rr : S4_pstorerbf_rr; - case S2_storerbabs: - case S2_storerbgp: - return IfTrue ? S4_pstorerbt_abs : S4_pstorerbf_abs; - case S4_storeirb_io: - return IfTrue ? S4_storeirbt_io : S4_storeirbf_io; - case S2_storerh_io: - return IfTrue ? S2_pstorerht_io : S2_pstorerhf_io; - case S4_storerh_rr: - return IfTrue ? S4_pstorerht_rr : S4_pstorerhf_rr; - case S2_storerhabs: - case S2_storerhgp: - return IfTrue ? S4_pstorerht_abs : S4_pstorerhf_abs; - case S2_storerf_io: - return IfTrue ? S2_pstorerft_io : S2_pstorerff_io; - case S4_storerf_rr: - return IfTrue ? S4_pstorerft_rr : S4_pstorerff_rr; - case S2_storerfabs: - case S2_storerfgp: - return IfTrue ? S4_pstorerft_abs : S4_pstorerff_abs; - case S4_storeirh_io: - return IfTrue ? S4_storeirht_io : S4_storeirhf_io; - case S2_storeri_io: - return IfTrue ? S2_pstorerit_io : S2_pstorerif_io; - case S4_storeri_rr: - return IfTrue ? S4_pstorerit_rr : S4_pstorerif_rr; - case S2_storeriabs: - case S2_storerigp: - return IfTrue ? S4_pstorerit_abs : S4_pstorerif_abs; - case S4_storeiri_io: - return IfTrue ? S4_storeirit_io : S4_storeirif_io; - case S2_storerd_io: - return IfTrue ? S2_pstorerdt_io : S2_pstorerdf_io; - case S4_storerd_rr: - return IfTrue ? S4_pstorerdt_rr : S4_pstorerdf_rr; - case S2_storerdabs: - case S2_storerdgp: - return IfTrue ? S4_pstorerdt_abs : S4_pstorerdf_abs; - } - llvm_unreachable("Unexpected opcode"); - return 0; + return HII->getCondOpcode(Opc, !IfTrue); } @@ -717,9 +668,14 @@ void HexagonEarlyIfConversion::predicateInstr(MachineBasicBlock *ToB, if (isPredicableStore(MI)) { unsigned COpc = getCondStoreOpcode(Opc, IfTrue); assert(COpc); - MachineInstrBuilder MIB = BuildMI(*ToB, At, DL, TII->get(COpc)) - .addReg(PredR); - for (MIOperands MO(*MI); MO.isValid(); ++MO) + MachineInstrBuilder MIB = BuildMI(*ToB, At, DL, HII->get(COpc)); + MIOperands MO(*MI); + if (HII->isPostIncrement(MI)) { + MIB.addOperand(*MO); + ++MO; + } + MIB.addReg(PredR); + for (; MO.isValid(); ++MO) MIB.addOperand(*MO); // Set memory references. @@ -733,7 +689,7 @@ void HexagonEarlyIfConversion::predicateInstr(MachineBasicBlock *ToB, if (Opc == Hexagon::J2_jump) { MachineBasicBlock *TB = MI->getOperand(0).getMBB(); - const MCInstrDesc &D = TII->get(IfTrue ? Hexagon::J2_jumpt + const MCInstrDesc &D = HII->get(IfTrue ? Hexagon::J2_jumpt : Hexagon::J2_jumpf); BuildMI(*ToB, At, DL, D) .addReg(PredR) @@ -801,8 +757,22 @@ void HexagonEarlyIfConversion::updatePhiNodes(MachineBasicBlock *WhereB, using namespace Hexagon; unsigned DR = PN->getOperand(0).getReg(); const TargetRegisterClass *RC = MRI->getRegClass(DR); - const MCInstrDesc &D = RC == &IntRegsRegClass ? TII->get(C2_mux) - : TII->get(MUX64_rr); + unsigned Opc = 0; + if (RC == &IntRegsRegClass) + Opc = C2_mux; + else if (RC == &DoubleRegsRegClass) + Opc = MUX64_rr; + else if (RC == &VectorRegsRegClass) + Opc = VSelectPseudo_V6; + else if (RC == &VecDblRegsRegClass) + Opc = VSelectDblPseudo_V6; + else if (RC == &VectorRegs128BRegClass) + Opc = VSelectPseudo_V6_128B; + else if (RC == &VecDblRegs128BRegClass) + Opc = VSelectDblPseudo_V6_128B; + else + llvm_unreachable("unexpected register type"); + const MCInstrDesc &D = HII->get(Opc); MachineBasicBlock::iterator MuxAt = FP.SplitB->getFirstTerminator(); DebugLoc DL; @@ -870,21 +840,21 @@ void HexagonEarlyIfConversion::convert(const FlowPattern &FP) { // generated. if (FP.JoinB) { assert(!SSB || SSB == FP.JoinB); - BuildMI(*FP.SplitB, FP.SplitB->end(), DL, TII->get(Hexagon::J2_jump)) + BuildMI(*FP.SplitB, FP.SplitB->end(), DL, HII->get(Hexagon::J2_jump)) .addMBB(FP.JoinB); FP.SplitB->addSuccessor(FP.JoinB); } else { bool HasBranch = false; if (TSB) { - BuildMI(*FP.SplitB, FP.SplitB->end(), DL, TII->get(Hexagon::J2_jumpt)) + BuildMI(*FP.SplitB, FP.SplitB->end(), DL, HII->get(Hexagon::J2_jumpt)) .addReg(FP.PredR) .addMBB(TSB); FP.SplitB->addSuccessor(TSB); HasBranch = true; } if (FSB) { - const MCInstrDesc &D = HasBranch ? TII->get(Hexagon::J2_jump) - : TII->get(Hexagon::J2_jumpf); + const MCInstrDesc &D = HasBranch ? HII->get(Hexagon::J2_jump) + : HII->get(Hexagon::J2_jumpf); MachineInstrBuilder MIB = BuildMI(*FP.SplitB, FP.SplitB->end(), DL, D); if (!HasBranch) MIB.addReg(FP.PredR); @@ -896,7 +866,7 @@ void HexagonEarlyIfConversion::convert(const FlowPattern &FP) { // successor blocks of the TrueB and FalseB (or null of the TrueB // or FalseB block is null). SSB is the potential successor block // of the SplitB that is neither TrueB nor FalseB. - BuildMI(*FP.SplitB, FP.SplitB->end(), DL, TII->get(Hexagon::J2_jump)) + BuildMI(*FP.SplitB, FP.SplitB->end(), DL, HII->get(Hexagon::J2_jump)) .addMBB(SSB); FP.SplitB->addSuccessor(SSB); } @@ -963,7 +933,7 @@ void HexagonEarlyIfConversion::eliminatePhis(MachineBasicBlock *B) { const DebugLoc &DL = PN->getDebugLoc(); const TargetRegisterClass *RC = MRI->getRegClass(DefR); NewR = MRI->createVirtualRegister(RC); - NonPHI = BuildMI(*B, NonPHI, DL, TII->get(TargetOpcode::COPY), NewR) + NonPHI = BuildMI(*B, NonPHI, DL, HII->get(TargetOpcode::COPY), NewR) .addReg(UseR, 0, UseSR); } MRI->replaceRegWith(DefR, NewR); @@ -993,7 +963,7 @@ void HexagonEarlyIfConversion::mergeBlocks(MachineBasicBlock *PredB, << PrintMB(SuccB) << "\n"); bool TermOk = hasUncondBranch(SuccB); eliminatePhis(SuccB); - TII->RemoveBranch(*PredB); + HII->RemoveBranch(*PredB); PredB->removeSuccessor(SuccB); PredB->splice(PredB->end(), SuccB, SuccB->begin(), SuccB->end()); MachineBasicBlock::succ_iterator I, E = SuccB->succ_end(); @@ -1035,8 +1005,8 @@ bool HexagonEarlyIfConversion::runOnMachineFunction(MachineFunction &MF) { if (skipFunction(*MF.getFunction())) return false; - auto &ST = MF.getSubtarget(); - TII = ST.getInstrInfo(); + auto &ST = MF.getSubtarget<HexagonSubtarget>(); + HII = ST.getInstrInfo(); TRI = ST.getRegisterInfo(); MFN = &MF; MRI = &MF.getRegInfo(); diff --git a/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp b/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp index 2362ef8048f..f17616f4185 100644 --- a/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp +++ b/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp @@ -2055,13 +2055,20 @@ HexagonTargetLowering::HexagonTargetLowering(const TargetMachine &TM, // Handling of indexed loads/stores: default is "expand". // - for (MVT LSXTy : {MVT::i8, MVT::i16, MVT::i32, MVT::i64}) { - setIndexedLoadAction(ISD::POST_INC, LSXTy, Legal); - setIndexedStoreAction(ISD::POST_INC, LSXTy, Legal); + for (MVT VT : {MVT::i8, MVT::i16, MVT::i32, MVT::i64}) { + setIndexedLoadAction(ISD::POST_INC, VT, Legal); + setIndexedStoreAction(ISD::POST_INC, VT, Legal); } - if (UseHVXDbl) { - for (MVT VT : {MVT::v128i8, MVT::v64i16, MVT::v32i32, MVT::v16i64}) { + if (UseHVXSgl) { + for (MVT VT : {MVT::v64i8, MVT::v32i16, MVT::v16i32, MVT::v8i64, + MVT::v128i8, MVT::v64i16, MVT::v32i32, MVT::v16i64}) { + setIndexedLoadAction(ISD::POST_INC, VT, Legal); + setIndexedStoreAction(ISD::POST_INC, VT, Legal); + } + } else if (UseHVXDbl) { + for (MVT VT : {MVT::v128i8, MVT::v64i16, MVT::v32i32, MVT::v16i64, + MVT::v256i8, MVT::v128i16, MVT::v64i32, MVT::v32i64}) { setIndexedLoadAction(ISD::POST_INC, VT, Legal); setIndexedStoreAction(ISD::POST_INC, VT, Legal); } diff --git a/llvm/lib/Target/Hexagon/HexagonInstrInfoV60.td b/llvm/lib/Target/Hexagon/HexagonInstrInfoV60.td index c3f09b69ce8..3b6ca04cbc1 100644 --- a/llvm/lib/Target/Hexagon/HexagonInstrInfoV60.td +++ b/llvm/lib/Target/Hexagon/HexagonInstrInfoV60.td @@ -219,6 +219,8 @@ let isNVStorable = 1 in { def V6_vS32b_npred_ai_128B : T_vstore_pred_ai_128B <"vmem", "vS32b_ai", 1>, V6_vS32b_npred_ai_128B_enc; } + + let isNVStorable = 1, isNonTemporal = 1 in { def V6_vS32b_nt_pred_ai : T_vstore_pred_ai_64B <"vmem", "vS32b_ai", 0, 1>, V6_vS32b_nt_pred_ai_enc; @@ -1031,27 +1033,29 @@ class VSELInst<dag outs, dag ins, string asmstr, list<dag> pattern = [], IType type = TypeCVI_VA_DV> : InstHexagon<outs, ins, asmstr, pattern, cstr, itin, type>; -let isCodeGenOnly = 1, isPseudo = 1, hasSideEffects = 0 in { -def VSelectPseudo_V6 : VSELInst<(outs VectorRegs:$dst), - (ins PredRegs:$src1, VectorRegs:$src2, VectorRegs:$src3), - ".error \"should not emit\" ", - []>, - Requires<[HasV60T,UseHVXSgl]>; -def VSelectDblPseudo_V6 : VSELInst<(outs VecDblRegs:$dst), - (ins PredRegs:$src1, VecDblRegs:$src2, VecDblRegs:$src3), - ".error \"should not emit\" ", - []>, - Requires<[HasV60T,UseHVXSgl]>; -} - -def : Pat <(v16i32 (selectcc (i32 IntRegs:$lhs), (i32 IntRegs:$rhs), - (v16i32 VectorRegs:$tval), - (v16i32 VectorRegs:$fval), SETEQ)), - (v16i32 (VSelectPseudo_V6 (i32 (C2_cmpeq (i32 IntRegs:$lhs), - (i32 IntRegs:$rhs))), - (v16i32 VectorRegs:$tval), - (v16i32 VectorRegs:$fval)))>; +multiclass VSelect<RegisterClass RC, ValueType V> { + let isCodeGenOnly = 1, isPseudo = 1, hasSideEffects = 0 in { + def NAME : VSELInst<(outs RC:$dst), + (ins PredRegs:$src1, RC:$src2, RC:$src3), + ".error \"should not emit\" ", + []>; + } + def : Pat <(V (selectcc (i32 IntRegs:$lhs), (i32 IntRegs:$rhs), (V RC:$tval), + (V RC:$fval), SETEQ)), + (V (!cast<Instruction>(NAME) (i32 (C2_cmpeq (i32 IntRegs:$lhs), + (i32 IntRegs:$rhs))), + (V RC:$tval), (V RC:$fval)))>; +} + +defm VSelectPseudo_V6 : VSelect<VectorRegs, v16i32>, + Requires<[HasV60T,UseHVXSgl]>; +defm VSelectDblPseudo_V6 : VSelect<VecDblRegs, v32i32>, + Requires<[HasV60T,UseHVXSgl]>; +defm VSelectPseudo_V6_128B : VSelect<VectorRegs128B, v32i32>, + Requires<[HasV60T,UseHVXDbl]>; +defm VSelectDblPseudo_V6_128B : VSelect<VecDblRegs128B, v64i32>, + Requires<[HasV60T,UseHVXDbl]>; let hasNewValue = 1 in class T_vmpy <string asmString, RegisterClass RCout, RegisterClass RCin> diff --git a/llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp b/llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp index ba98b27561c..ef879591b19 100644 --- a/llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp +++ b/llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp @@ -326,7 +326,13 @@ static bool doesModifyCalleeSavedReg(const MachineInstr *MI, // TODO: MI->isIndirectBranch() and IsRegisterJump(MI) // Returns true if an instruction can be promoted to .new predicate or // new-value store. -bool HexagonPacketizerList::isNewifiable(const MachineInstr* MI) { +bool HexagonPacketizerList::isNewifiable(const MachineInstr* MI, + const TargetRegisterClass *NewRC) { + // Vector stores can be predicated, and can be new-value stores, but + // they cannot be predicated on a .new predicate value. + if (NewRC == &Hexagon::PredRegsRegClass) + if (HII->isV60VectorInstruction(MI) && MI->mayStore()) + return false; return HII->isCondInst(MI) || MI->isReturn() || HII->mayBeNewStore(MI); } @@ -767,7 +773,7 @@ bool HexagonPacketizerList::canPromoteToDotNew(const MachineInstr *MI, if (HII->isDotNewInst(MI) && !HII->mayBeNewStore(MI)) return false; - if (!isNewifiable(MI)) + if (!isNewifiable(MI, RC)) return false; const MachineInstr *PI = PacketSU->getInstr(); diff --git a/llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.h b/llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.h index bd5546d9bdb..89aab35dbde 100644 --- a/llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.h +++ b/llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.h @@ -98,7 +98,7 @@ protected: void useCalleesSP(MachineInstr *MI); bool arePredicatesComplements(MachineInstr &MI1, MachineInstr &MI2); bool restrictingDepExistInPacket(MachineInstr*, unsigned); - bool isNewifiable(const MachineInstr *MI); + bool isNewifiable(const MachineInstr *MI, const TargetRegisterClass *NewRC); bool isCurifiable(MachineInstr* MI); bool cannotCoexist(const MachineInstr *MI, const MachineInstr *MJ); inline bool isPromotedToDotNew() const { diff --git a/llvm/test/CodeGen/Hexagon/early-if-vecpi.ll b/llvm/test/CodeGen/Hexagon/early-if-vecpi.ll new file mode 100644 index 00000000000..6f3ec2d5a51 --- /dev/null +++ b/llvm/test/CodeGen/Hexagon/early-if-vecpi.ll @@ -0,0 +1,69 @@ +; RUN: llc -march=hexagon < %s | FileCheck %s + +target triple = "hexagon-unknown--elf" + +; Check that we can predicate base+offset vector stores. +; CHECK-LABEL: sammy +; CHECK: if{{.*}}vmem(r{{[0-9]+}}+#0) = +define void @sammy(<16 x i32>* nocapture %p, <16 x i32>* nocapture readonly %q, i32 %n) #0 { +entry: + %0 = load <16 x i32>, <16 x i32>* %q, align 64 + %sub = add nsw i32 %n, -1 + br label %for.body + +for.body: ; preds = %if.end, %entry + %p.addr.011 = phi <16 x i32>* [ %p, %entry ], [ %incdec.ptr, %if.end ] + %i.010 = phi i32 [ 0, %entry ], [ %add, %if.end ] + %mul = mul nsw i32 %i.010, %sub + %add = add nuw nsw i32 %i.010, 1 + %mul1 = mul nsw i32 %add, %n + %cmp2 = icmp slt i32 %mul, %mul1 + br i1 %cmp2, label %if.then, label %if.end + +if.then: ; preds = %for.body + store <16 x i32> %0, <16 x i32>* %p.addr.011, align 64 + br label %if.end + +if.end: ; preds = %if.then, %for.body + %incdec.ptr = getelementptr inbounds <16 x i32>, <16 x i32>* %p.addr.011, i32 1 + %exitcond = icmp eq i32 %add, 100 + br i1 %exitcond, label %for.end, label %for.body + +for.end: ; preds = %if.end + ret void +} + +; Check that we can predicate post-increment vector stores. +; CHECK-LABEL: danny +; CHECK: if{{.*}}vmem(r{{[0-9]+}}++#1) = +define void @danny(<16 x i32>* nocapture %p, <16 x i32>* nocapture readonly %q, i32 %n) #0 { +entry: + %0 = load <16 x i32>, <16 x i32>* %q, align 64 + %sub = add nsw i32 %n, -1 + br label %for.body + +for.body: ; preds = %if.end, %entry + %p.addr.012 = phi <16 x i32>* [ %p, %entry ], [ %incdec.ptr3, %if.end ] + %i.011 = phi i32 [ 0, %entry ], [ %add, %if.end ] + %mul = mul nsw i32 %i.011, %sub + %add = add nuw nsw i32 %i.011, 1 + %mul1 = mul nsw i32 %add, %n + %cmp2 = icmp slt i32 %mul, %mul1 + br i1 %cmp2, label %if.then, label %if.end + +if.then: ; preds = %for.body + %incdec.ptr = getelementptr inbounds <16 x i32>, <16 x i32>* %p.addr.012, i32 1 + store <16 x i32> %0, <16 x i32>* %p.addr.012, align 64 + br label %if.end + +if.end: ; preds = %if.then, %for.body + %p.addr.1 = phi <16 x i32>* [ %incdec.ptr, %if.then ], [ %p.addr.012, %for.body ] + %incdec.ptr3 = getelementptr inbounds <16 x i32>, <16 x i32>* %p.addr.1, i32 1 + %exitcond = icmp eq i32 %add, 100 + br i1 %exitcond, label %for.end, label %for.body + +for.end: ; preds = %if.end + ret void +} + +attributes #0 = { norecurse nounwind "target-cpu"="hexagonv60" "target-features"="+hvx,-hvx-double" } |