[llvm] r328724 - [Hexagon] Add support for "new" circular buffer intrinsics

Krzysztof Parzyszek via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 6 06:59:19 PDT 2018


This one is fixed in r329394. Hope that's all of them.
-Krzysztof

On 4/6/2018 4:26 AM, Mikael Holmén wrote:
> 
> 
> On 04/05/2018 04:29 PM, Krzysztof Parzyszek wrote:
>> Fixed in r329286.
>>
> 
> Thanks.
> 
> Similar thing in tools/clang/lib/CodeGen/CGBuiltin.cpp introduced in 
> r328725:
> 
> ../tools/clang/lib/CodeGen/CGBuiltin.cpp: In member function 
> 'llvm::Value* 
> clang::CodeGen::CodeGenFunction::EmitHexagonBuiltinExpr(unsigned int, 
> const clang::CallExpr*)':
> ../tools/clang/lib/CodeGen/CGBuiltin.cpp:10777:55: error: default 
> argument specified for lambda parameter [-Werror=pedantic]
>     auto MakeCircLd = [&](unsigned IntID, bool HasImm = true) {
>                                                         ^
> ../tools/clang/lib/CodeGen/CGBuiltin.cpp:10802:55: error: default 
> argument specified for lambda parameter [-Werror=pedantic]
>     auto MakeCircSt = [&](unsigned IntID, bool HasImm = true) {
> 
> Regards,
> Mikael
> 
>> -Krzysztof
>>
>> On 4/5/2018 8:04 AM, Mikael Holmén wrote:
>>> Hi Krzysztof,
>>>
>>> Gcc (5.4.0) warns on code added in this patch:
>>>
>>> ../lib/Target/Hexagon/HexagonInstrInfo.cpp: In member function 
>>> 'virtual bool 
>>> llvm::HexagonInstrInfo::expandPostRAPseudo(llvm::MachineInstr&) const':
>>> ../lib/Target/Hexagon/HexagonInstrInfo.cpp:1019:51: error: default 
>>> argument specified for lambda parameter [-Werror=pedantic]
>>>     auto RealCirc = [&](unsigned Opc, bool HasImm = true, unsigned 
>>> MxOp = 4) {
>>>                                                     ^
>>> ../lib/Target/Hexagon/HexagonInstrInfo.cpp:1019:73: error: default 
>>> argument specified for lambda parameter [-Werror=pedantic]
>>>     auto RealCirc = [&](unsigned Opc, bool HasImm = true, unsigned 
>>> MxOp = 4) {
>>> ^
>>>
>>> Regards,
>>> Mikael
>>>
>>> On 03/28/2018 09:38 PM, Krzysztof Parzyszek via llvm-commits wrote:
>>>> Author: kparzysz
>>>> Date: Wed Mar 28 12:38:29 2018
>>>> New Revision: 328724
>>>>
>>>> URL: http://llvm.org/viewvc/llvm-project?rev=328724&view=rev
>>>> Log:
>>>> [Hexagon] Add support for "new" circular buffer intrinsics
>>>>
>>>> These instructions have been around for a long time, but we
>>>> haven't supported intrinsics for them. The "new" versions use
>>>> the CSx register for the start of the buffer instead of the K
>>>> field in the Mx register.
>>>>
>>>> We need to use pseudo instructions for these instructions until
>>>> after register allocation. The problem is that these instructions
>>>> allocate a M0/CS0 or M1/CS1 pair. But, we can't generate code for
>>>> the CSx set-up until after register allocation when the Mx
>>>> register has been fixed for the instruction.
>>>>
>>>> There is a related clang patch.
>>>>
>>>> Patch by Brendon Cahoon.
>>>>
>>>> Added:
>>>>      llvm/trunk/test/CodeGen/Hexagon/circ_new.ll
>>>> Modified:
>>>>      llvm/trunk/include/llvm/IR/IntrinsicsHexagon.td
>>>>      llvm/trunk/lib/Target/Hexagon/HexagonFrameLowering.cpp
>>>>      llvm/trunk/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp
>>>>      llvm/trunk/lib/Target/Hexagon/HexagonISelDAGToDAG.h
>>>>      llvm/trunk/lib/Target/Hexagon/HexagonInstrInfo.cpp
>>>>      llvm/trunk/lib/Target/Hexagon/HexagonPseudo.td
>>>>
>>>> Modified: llvm/trunk/include/llvm/IR/IntrinsicsHexagon.td
>>>> URL: 
>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/IntrinsicsHexagon.td?rev=328724&r1=328723&r2=328724&view=diff 
>>>>
>>>> ============================================================================== 
>>>>
>>>> --- llvm/trunk/include/llvm/IR/IntrinsicsHexagon.td (original)
>>>> +++ llvm/trunk/include/llvm/IR/IntrinsicsHexagon.td Wed Mar 28 
>>>> 12:38:29 2018
>>>> @@ -21,6 +21,13 @@ let TargetPrefix = "hexagon" in {
>>>>                                 list<IntrinsicProperty> properties>
>>>>       : GCCBuiltin<!strconcat("__builtin_", GCCIntSuffix)>,
>>>>         Intrinsic<ret_types, param_types, properties>;
>>>> +
>>>> +  /// Hexagon_NonGCC_Intrinsic - Base class for bitcode convertible 
>>>> Hexagon
>>>> +  /// intrinsics.
>>>> +  class Hexagon_NonGCC_Intrinsic<list<LLVMType> ret_types,
>>>> +                                 list<LLVMType> param_types,
>>>> +                                 list<IntrinsicProperty> properties>
>>>> +    : Intrinsic<ret_types, param_types, properties>;
>>>>   }
>>>> //===----------------------------------------------------------------------===// 
>>>>
>>>> @@ -9300,6 +9307,39 @@ Hexagon_vv128ivmemv1024_Intrinsic<"HEXAG
>>>>   def int_hexagon_V6_vmaskedstorentnq_128B :
>>>>   
>>>> Hexagon_vv128ivmemv1024_Intrinsic<"HEXAGON_V6_vmaskedstorentnq_128B">;
>>>> +multiclass Hexagon_custom_circ_ld_Intrinsic<LLVMType ElTy> {
>>>> +  def NAME#_pci : Hexagon_NonGCC_Intrinsic<
>>>> +    [ElTy, llvm_ptr_ty],
>>>> +    [llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty],
>>>> +    [IntrArgMemOnly, NoCapture<3>]>;
>>>> +  def NAME#_pcr : Hexagon_NonGCC_Intrinsic<
>>>> +    [ElTy, llvm_ptr_ty], [llvm_ptr_ty, llvm_i32_ty, llvm_ptr_ty],
>>>> +    [IntrArgMemOnly, NoCapture<2>]>;
>>>> +}
>>>> +
>>>> +defm int_hexagon_L2_loadrub : 
>>>> Hexagon_custom_circ_ld_Intrinsic<llvm_i32_ty>;
>>>> +defm int_hexagon_L2_loadrb : 
>>>> Hexagon_custom_circ_ld_Intrinsic<llvm_i32_ty>;
>>>> +defm int_hexagon_L2_loadruh : 
>>>> Hexagon_custom_circ_ld_Intrinsic<llvm_i32_ty>;
>>>> +defm int_hexagon_L2_loadrh : 
>>>> Hexagon_custom_circ_ld_Intrinsic<llvm_i32_ty>;
>>>> +defm int_hexagon_L2_loadri : 
>>>> Hexagon_custom_circ_ld_Intrinsic<llvm_i32_ty>;
>>>> +defm int_hexagon_L2_loadrd : 
>>>> Hexagon_custom_circ_ld_Intrinsic<llvm_i64_ty>;
>>>> +
>>>> +multiclass Hexagon_custom_circ_st_Intrinsic<LLVMType ElTy> {
>>>> +  def NAME#_pci : Hexagon_NonGCC_Intrinsic<
>>>> +    [llvm_ptr_ty],
>>>> +    [llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty, ElTy, llvm_ptr_ty],
>>>> +    [IntrArgMemOnly, NoCapture<4>]>;
>>>> +  def NAME#_pcr : Hexagon_NonGCC_Intrinsic<
>>>> +    [llvm_ptr_ty], [llvm_ptr_ty, llvm_i32_ty, ElTy, llvm_ptr_ty],
>>>> +    [IntrArgMemOnly, NoCapture<3>]>;
>>>> +}
>>>> +
>>>> +defm int_hexagon_S2_storerb : 
>>>> Hexagon_custom_circ_st_Intrinsic<llvm_i32_ty>;
>>>> +defm int_hexagon_S2_storerh : 
>>>> Hexagon_custom_circ_st_Intrinsic<llvm_i32_ty>;
>>>> +defm int_hexagon_S2_storerf : 
>>>> Hexagon_custom_circ_st_Intrinsic<llvm_i32_ty>;
>>>> +defm int_hexagon_S2_storeri : 
>>>> Hexagon_custom_circ_st_Intrinsic<llvm_i32_ty>;
>>>> +defm int_hexagon_S2_storerd : 
>>>> Hexagon_custom_circ_st_Intrinsic<llvm_i64_ty>;
>>>> +
>>>>   ///
>>>>   /// HexagonV62 intrinsics
>>>>
>>>> Modified: llvm/trunk/lib/Target/Hexagon/HexagonFrameLowering.cpp
>>>> URL: 
>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonFrameLowering.cpp?rev=328724&r1=328723&r2=328724&view=diff 
>>>>
>>>> ============================================================================== 
>>>>
>>>> --- llvm/trunk/lib/Target/Hexagon/HexagonFrameLowering.cpp (original)
>>>> +++ llvm/trunk/lib/Target/Hexagon/HexagonFrameLowering.cpp Wed Mar 
>>>> 28 12:38:29 2018
>>>> @@ -1867,11 +1867,11 @@ bool HexagonFrameLowering::expandSpillMa
>>>>             Changed |= expandCopy(B, I, MRI, HII, NewRegs);
>>>>             break;
>>>>           case Hexagon::STriw_pred:
>>>> -        case Hexagon::STriw_mod:
>>>> +        case Hexagon::STriw_ctr:
>>>>             Changed |= expandStoreInt(B, I, MRI, HII, NewRegs);
>>>>             break;
>>>>           case Hexagon::LDriw_pred:
>>>> -        case Hexagon::LDriw_mod:
>>>> +        case Hexagon::LDriw_ctr:
>>>>             Changed |= expandLoadInt(B, I, MRI, HII, NewRegs);
>>>>             break;
>>>>           case Hexagon::PS_vstorerq_ai:
>>>>
>>>> Modified: llvm/trunk/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp
>>>> URL: 
>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp?rev=328724&r1=328723&r2=328724&view=diff 
>>>>
>>>> ============================================================================== 
>>>>
>>>> --- llvm/trunk/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp (original)
>>>> +++ llvm/trunk/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp Wed Mar 28 
>>>> 12:38:29 2018
>>>> @@ -182,7 +182,6 @@ void HexagonDAGToDAGISel::SelectIndexedL
>>>>     CurDAG->RemoveDeadNode(LD);
>>>>   }
>>>> -
>>>>   MachineSDNode 
>>>> *HexagonDAGToDAGISel::LoadInstrForLoadIntrinsic(SDNode *IntN) {
>>>>     if (IntN->getOpcode() != ISD::INTRINSIC_W_CHAIN)
>>>>       return nullptr;
>>>> @@ -200,15 +199,14 @@ MachineSDNode *HexagonDAGToDAGISel::Load
>>>>     };
>>>>     auto FLC = LoadPciMap.find(IntNo);
>>>>     if (FLC != LoadPciMap.end()) {
>>>> -    SDNode *Mod = CurDAG->getMachineNode(Hexagon::A2_tfrrcr, dl, 
>>>> MVT::i32,
>>>> -          IntN->getOperand(4));
>>>>       EVT ValTy = (IntNo == Intrinsic::hexagon_circ_ldd) ? MVT::i64 
>>>> : MVT::i32;
>>>>       EVT RTys[] = { ValTy, MVT::i32, MVT::Other };
>>>>       // Operands: { Base, Increment, Modifier, Chain }
>>>>       auto Inc = cast<ConstantSDNode>(IntN->getOperand(5));
>>>>       SDValue I = CurDAG->getTargetConstant(Inc->getSExtValue(), dl, 
>>>> MVT::i32);
>>>>       MachineSDNode *Res = CurDAG->getMachineNode(FLC->second, dl, 
>>>> RTys,
>>>> -          { IntN->getOperand(2), I, SDValue(Mod,0), 
>>>> IntN->getOperand(0) });
>>>> +          { IntN->getOperand(2), I, IntN->getOperand(4),
>>>> +            IntN->getOperand(0) });
>>>>       return Res;
>>>>     }
>>>> @@ -337,6 +335,93 @@ bool HexagonDAGToDAGISel::tryLoadOfLoadI
>>>>       CurDAG->RemoveDeadNode(C);
>>>>       return true;
>>>>     }
>>>> +  return false;
>>>> +}
>>>> +
>>>> +/// Generate a machine instruction node for the new circlar buffer 
>>>> intrinsics.
>>>> +/// The new versions use a CSx register instead of the K field.
>>>> +bool HexagonDAGToDAGISel::SelectNewCircIntrinsic(SDNode *IntN) {
>>>> +  if (IntN->getOpcode() != ISD::INTRINSIC_W_CHAIN)
>>>> +    return false;
>>>> +
>>>> +  SDLoc DL(IntN);
>>>> +  unsigned IntNo = 
>>>> cast<ConstantSDNode>(IntN->getOperand(1))->getZExtValue();
>>>> +  SmallVector<SDValue, 7> Ops;
>>>> +
>>>> +  static std::map<unsigned,unsigned> LoadNPcMap = {
>>>> +    { Intrinsic::hexagon_L2_loadrub_pci, Hexagon::PS_loadrub_pci },
>>>> +    { Intrinsic::hexagon_L2_loadrb_pci, Hexagon::PS_loadrb_pci },
>>>> +    { Intrinsic::hexagon_L2_loadruh_pci, Hexagon::PS_loadruh_pci },
>>>> +    { Intrinsic::hexagon_L2_loadrh_pci, Hexagon::PS_loadrh_pci },
>>>> +    { Intrinsic::hexagon_L2_loadri_pci, Hexagon::PS_loadri_pci },
>>>> +    { Intrinsic::hexagon_L2_loadrd_pci, Hexagon::PS_loadrd_pci },
>>>> +    { Intrinsic::hexagon_L2_loadrub_pcr, Hexagon::PS_loadrub_pcr },
>>>> +    { Intrinsic::hexagon_L2_loadrb_pcr, Hexagon::PS_loadrb_pcr },
>>>> +    { Intrinsic::hexagon_L2_loadruh_pcr, Hexagon::PS_loadruh_pcr },
>>>> +    { Intrinsic::hexagon_L2_loadrh_pcr, Hexagon::PS_loadrh_pcr },
>>>> +    { Intrinsic::hexagon_L2_loadri_pcr, Hexagon::PS_loadri_pcr },
>>>> +    { Intrinsic::hexagon_L2_loadrd_pcr, Hexagon::PS_loadrd_pcr }
>>>> +  };
>>>> +  auto FLI = LoadNPcMap.find (IntNo);
>>>> +  if (FLI != LoadNPcMap.end()) {
>>>> +    EVT ValTy = MVT::i32;
>>>> +    if (IntNo == Intrinsic::hexagon_L2_loadrd_pci ||
>>>> +        IntNo == Intrinsic::hexagon_L2_loadrd_pcr)
>>>> +      ValTy = MVT::i64;
>>>> +    EVT RTys[] = { ValTy, MVT::i32, MVT::Other };
>>>> +    // Handle load.*_pci case which has 6 operands.
>>>> +    if (IntN->getNumOperands() == 6) {
>>>> +      auto Inc = cast<ConstantSDNode>(IntN->getOperand(3));
>>>> +      SDValue I = CurDAG->getTargetConstant(Inc->getSExtValue(), 
>>>> DL, MVT::i32);
>>>> +      // Operands: { Base, Increment, Modifier, Start, Chain }.
>>>> +      Ops = { IntN->getOperand(2), I, IntN->getOperand(4), 
>>>> IntN->getOperand(5),
>>>> +              IntN->getOperand(0) };
>>>> +    } else
>>>> +      // Handle load.*_pcr case which has 5 operands.
>>>> +      // Operands: { Base, Modifier, Start, Chain }.
>>>> +      Ops = { IntN->getOperand(2), IntN->getOperand(3), 
>>>> IntN->getOperand(4),
>>>> +              IntN->getOperand(0) };
>>>> +    MachineSDNode *Res = CurDAG->getMachineNode(FLI->second, DL, 
>>>> RTys, Ops);
>>>> +    ReplaceUses(SDValue(IntN, 0), SDValue(Res, 0));
>>>> +    ReplaceUses(SDValue(IntN, 1), SDValue(Res, 1));
>>>> +    ReplaceUses(SDValue(IntN, 2), SDValue(Res, 2));
>>>> +    CurDAG->RemoveDeadNode(IntN);
>>>> +    return true;
>>>> +  }
>>>> +
>>>> +  static std::map<unsigned,unsigned> StoreNPcMap = {
>>>> +    { Intrinsic::hexagon_S2_storerb_pci, Hexagon::PS_storerb_pci },
>>>> +    { Intrinsic::hexagon_S2_storerh_pci, Hexagon::PS_storerh_pci },
>>>> +    { Intrinsic::hexagon_S2_storerf_pci, Hexagon::PS_storerf_pci },
>>>> +    { Intrinsic::hexagon_S2_storeri_pci, Hexagon::PS_storeri_pci },
>>>> +    { Intrinsic::hexagon_S2_storerd_pci, Hexagon::PS_storerd_pci },
>>>> +    { Intrinsic::hexagon_S2_storerb_pcr, Hexagon::PS_storerb_pcr },
>>>> +    { Intrinsic::hexagon_S2_storerh_pcr, Hexagon::PS_storerh_pcr },
>>>> +    { Intrinsic::hexagon_S2_storerf_pcr, Hexagon::PS_storerf_pcr },
>>>> +    { Intrinsic::hexagon_S2_storeri_pcr, Hexagon::PS_storeri_pcr },
>>>> +    { Intrinsic::hexagon_S2_storerd_pcr, Hexagon::PS_storerd_pcr }
>>>> +  };
>>>> +  auto FSI = StoreNPcMap.find (IntNo);
>>>> +  if (FSI != StoreNPcMap.end()) {
>>>> +    EVT RTys[] = { MVT::i32, MVT::Other };
>>>> +    // Handle store.*_pci case which has 7 operands.
>>>> +    if (IntN->getNumOperands() == 7) {
>>>> +      auto Inc = cast<ConstantSDNode>(IntN->getOperand(3));
>>>> +      SDValue I = CurDAG->getTargetConstant(Inc->getSExtValue(), 
>>>> DL, MVT::i32);
>>>> +      // Operands: { Base, Increment, Modifier, Value, Start, Chain }.
>>>> +      Ops = { IntN->getOperand(2), I, IntN->getOperand(4), 
>>>> IntN->getOperand(5),
>>>> +              IntN->getOperand(6), IntN->getOperand(0) };
>>>> +    } else
>>>> +      // Handle store.*_pcr case which has 6 operands.
>>>> +      // Operands: { Base, Modifier, Value, Start, Chain }.
>>>> +      Ops = { IntN->getOperand(2), IntN->getOperand(3), 
>>>> IntN->getOperand(4),
>>>> +              IntN->getOperand(5), IntN->getOperand(0) };
>>>> +    MachineSDNode *Res = CurDAG->getMachineNode(FSI->second, DL, 
>>>> RTys, Ops);
>>>> +    ReplaceUses(SDValue(IntN, 0), SDValue(Res, 0));
>>>> +    ReplaceUses(SDValue(IntN, 1), SDValue(Res, 1));
>>>> +    CurDAG->RemoveDeadNode(IntN);
>>>> +    return true;
>>>> +  }
>>>>     return false;
>>>>   }
>>>> @@ -344,9 +429,9 @@ bool HexagonDAGToDAGISel::tryLoadOfLoadI
>>>>   void HexagonDAGToDAGISel::SelectLoad(SDNode *N) {
>>>>     SDLoc dl(N);
>>>>     LoadSDNode *LD = cast<LoadSDNode>(N);
>>>> -  ISD::MemIndexedMode AM = LD->getAddressingMode();
>>>>     // Handle indexed loads.
>>>> +  ISD::MemIndexedMode AM = LD->getAddressingMode();
>>>>     if (AM != ISD::UNINDEXED) {
>>>>       SelectIndexedLoad(LD, dl);
>>>>       return;
>>>> @@ -452,9 +537,9 @@ void HexagonDAGToDAGISel::SelectIndexedS
>>>>   void HexagonDAGToDAGISel::SelectStore(SDNode *N) {
>>>>     SDLoc dl(N);
>>>>     StoreSDNode *ST = cast<StoreSDNode>(N);
>>>> -  ISD::MemIndexedMode AM = ST->getAddressingMode();
>>>>     // Handle indexed stores.
>>>> +  ISD::MemIndexedMode AM = ST->getAddressingMode();
>>>>     if (AM != ISD::UNINDEXED) {
>>>>       SelectIndexedStore(ST, dl);
>>>>       return;
>>>> @@ -527,6 +612,9 @@ void HexagonDAGToDAGISel::SelectIntrinsi
>>>>       return;
>>>>     }
>>>> +  if (SelectNewCircIntrinsic(N))
>>>> +    return;
>>>> +
>>>>     unsigned IntNo = 
>>>> cast<ConstantSDNode>(N->getOperand(1))->getZExtValue();
>>>>     if (IntNo == Intrinsic::hexagon_V6_vgathermw ||
>>>>         IntNo == Intrinsic::hexagon_V6_vgathermw_128B ||
>>>> @@ -620,7 +708,6 @@ void HexagonDAGToDAGISel::SelectConstant
>>>>     SelectCode(N);
>>>>   }
>>>> -
>>>>   void HexagonDAGToDAGISel::SelectFrameIndex(SDNode *N) {
>>>>     MachineFrameInfo &MFI = MF->getFrameInfo();
>>>>     const HexagonFrameLowering *HFI = HST->getFrameLowering();
>>>>
>>>> Modified: llvm/trunk/lib/Target/Hexagon/HexagonISelDAGToDAG.h
>>>> URL: 
>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonISelDAGToDAG.h?rev=328724&r1=328723&r2=328724&view=diff 
>>>>
>>>> ============================================================================== 
>>>>
>>>> --- llvm/trunk/lib/Target/Hexagon/HexagonISelDAGToDAG.h (original)
>>>> +++ llvm/trunk/lib/Target/Hexagon/HexagonISelDAGToDAG.h Wed Mar 28 
>>>> 12:38:29 2018
>>>> @@ -90,6 +90,7 @@ public:
>>>>                                       unsigned ConstraintID,
>>>>                                       std::vector<SDValue> &OutOps) 
>>>> override;
>>>>     bool tryLoadOfLoadIntrinsic(LoadSDNode *N);
>>>> +  bool SelectNewCircIntrinsic(SDNode *IntN);
>>>>     void SelectLoad(SDNode *N);
>>>>     void SelectIndexedLoad(LoadSDNode *LD, const SDLoc &dl);
>>>>     void SelectIndexedStore(StoreSDNode *ST, const SDLoc &dl);
>>>>
>>>> Modified: llvm/trunk/lib/Target/Hexagon/HexagonInstrInfo.cpp
>>>> URL: 
>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonInstrInfo.cpp?rev=328724&r1=328723&r2=328724&view=diff 
>>>>
>>>> ============================================================================== 
>>>>
>>>> --- llvm/trunk/lib/Target/Hexagon/HexagonInstrInfo.cpp (original)
>>>> +++ llvm/trunk/lib/Target/Hexagon/HexagonInstrInfo.cpp Wed Mar 28 
>>>> 12:38:29 2018
>>>> @@ -240,41 +240,41 @@ static bool isDuplexPairMatch(unsigned G
>>>>   unsigned HexagonInstrInfo::isLoadFromStackSlot(const MachineInstr 
>>>> &MI,
>>>>                                                  int &FrameIndex) 
>>>> const {
>>>>     switch (MI.getOpcode()) {
>>>> -  default:
>>>> -    break;
>>>> -  case Hexagon::L2_loadri_io:
>>>> -  case Hexagon::L2_loadrd_io:
>>>> -  case Hexagon::V6_vL32b_ai:
>>>> -  case Hexagon::V6_vL32b_nt_ai:
>>>> -  case Hexagon::V6_vL32Ub_ai:
>>>> -  case Hexagon::LDriw_pred:
>>>> -  case Hexagon::LDriw_mod:
>>>> -  case Hexagon::PS_vloadrq_ai:
>>>> -  case Hexagon::PS_vloadrw_ai:
>>>> -  case Hexagon::PS_vloadrw_nt_ai: {
>>>> -    const MachineOperand OpFI = MI.getOperand(1);
>>>> -    if (!OpFI.isFI())
>>>> -      return 0;
>>>> -    const MachineOperand OpOff = MI.getOperand(2);
>>>> -    if (!OpOff.isImm() || OpOff.getImm() != 0)
>>>> -      return 0;
>>>> -    FrameIndex = OpFI.getIndex();
>>>> -    return MI.getOperand(0).getReg();
>>>> -  }
>>>> -
>>>> -  case Hexagon::L2_ploadrit_io:
>>>> -  case Hexagon::L2_ploadrif_io:
>>>> -  case Hexagon::L2_ploadrdt_io:
>>>> -  case Hexagon::L2_ploadrdf_io: {
>>>> -    const MachineOperand OpFI = MI.getOperand(2);
>>>> -    if (!OpFI.isFI())
>>>> -      return 0;
>>>> -    const MachineOperand OpOff = MI.getOperand(3);
>>>> -    if (!OpOff.isImm() || OpOff.getImm() != 0)
>>>> -      return 0;
>>>> -    FrameIndex = OpFI.getIndex();
>>>> -    return MI.getOperand(0).getReg();
>>>> -  }
>>>> +    default:
>>>> +      break;
>>>> +    case Hexagon::L2_loadri_io:
>>>> +    case Hexagon::L2_loadrd_io:
>>>> +    case Hexagon::V6_vL32b_ai:
>>>> +    case Hexagon::V6_vL32b_nt_ai:
>>>> +    case Hexagon::V6_vL32Ub_ai:
>>>> +    case Hexagon::LDriw_pred:
>>>> +    case Hexagon::LDriw_ctr:
>>>> +    case Hexagon::PS_vloadrq_ai:
>>>> +    case Hexagon::PS_vloadrw_ai:
>>>> +    case Hexagon::PS_vloadrw_nt_ai: {
>>>> +      const MachineOperand OpFI = MI.getOperand(1);
>>>> +      if (!OpFI.isFI())
>>>> +        return 0;
>>>> +      const MachineOperand OpOff = MI.getOperand(2);
>>>> +      if (!OpOff.isImm() || OpOff.getImm() != 0)
>>>> +        return 0;
>>>> +      FrameIndex = OpFI.getIndex();
>>>> +      return MI.getOperand(0).getReg();
>>>> +    }
>>>> +
>>>> +    case Hexagon::L2_ploadrit_io:
>>>> +    case Hexagon::L2_ploadrif_io:
>>>> +    case Hexagon::L2_ploadrdt_io:
>>>> +    case Hexagon::L2_ploadrdf_io: {
>>>> +      const MachineOperand OpFI = MI.getOperand(2);
>>>> +      if (!OpFI.isFI())
>>>> +        return 0;
>>>> +      const MachineOperand OpOff = MI.getOperand(3);
>>>> +      if (!OpOff.isImm() || OpOff.getImm() != 0)
>>>> +        return 0;
>>>> +      FrameIndex = OpFI.getIndex();
>>>> +      return MI.getOperand(0).getReg();
>>>> +    }
>>>>     }
>>>>     return 0;
>>>> @@ -288,45 +288,45 @@ unsigned HexagonInstrInfo::isLoadFromSta
>>>>   unsigned HexagonInstrInfo::isStoreToStackSlot(const MachineInstr &MI,
>>>>                                                 int &FrameIndex) 
>>>> const {
>>>>     switch (MI.getOpcode()) {
>>>> -  default:
>>>> -    break;
>>>> -  case Hexagon::S2_storerb_io:
>>>> -  case Hexagon::S2_storerh_io:
>>>> -  case Hexagon::S2_storeri_io:
>>>> -  case Hexagon::S2_storerd_io:
>>>> -  case Hexagon::V6_vS32b_ai:
>>>> -  case Hexagon::V6_vS32Ub_ai:
>>>> -  case Hexagon::STriw_pred:
>>>> -  case Hexagon::STriw_mod:
>>>> -  case Hexagon::PS_vstorerq_ai:
>>>> -  case Hexagon::PS_vstorerw_ai: {
>>>> -    const MachineOperand &OpFI = MI.getOperand(0);
>>>> -    if (!OpFI.isFI())
>>>> -      return 0;
>>>> -    const MachineOperand &OpOff = MI.getOperand(1);
>>>> -    if (!OpOff.isImm() || OpOff.getImm() != 0)
>>>> -      return 0;
>>>> -    FrameIndex = OpFI.getIndex();
>>>> -    return MI.getOperand(2).getReg();
>>>> -  }
>>>> -
>>>> -  case Hexagon::S2_pstorerbt_io:
>>>> -  case Hexagon::S2_pstorerbf_io:
>>>> -  case Hexagon::S2_pstorerht_io:
>>>> -  case Hexagon::S2_pstorerhf_io:
>>>> -  case Hexagon::S2_pstorerit_io:
>>>> -  case Hexagon::S2_pstorerif_io:
>>>> -  case Hexagon::S2_pstorerdt_io:
>>>> -  case Hexagon::S2_pstorerdf_io: {
>>>> -    const MachineOperand &OpFI = MI.getOperand(1);
>>>> -    if (!OpFI.isFI())
>>>> -      return 0;
>>>> -    const MachineOperand &OpOff = MI.getOperand(2);
>>>> -    if (!OpOff.isImm() || OpOff.getImm() != 0)
>>>> -      return 0;
>>>> -    FrameIndex = OpFI.getIndex();
>>>> -    return MI.getOperand(3).getReg();
>>>> -  }
>>>> +    default:
>>>> +      break;
>>>> +    case Hexagon::S2_storerb_io:
>>>> +    case Hexagon::S2_storerh_io:
>>>> +    case Hexagon::S2_storeri_io:
>>>> +    case Hexagon::S2_storerd_io:
>>>> +    case Hexagon::V6_vS32b_ai:
>>>> +    case Hexagon::V6_vS32Ub_ai:
>>>> +    case Hexagon::STriw_pred:
>>>> +    case Hexagon::STriw_ctr:
>>>> +    case Hexagon::PS_vstorerq_ai:
>>>> +    case Hexagon::PS_vstorerw_ai: {
>>>> +      const MachineOperand &OpFI = MI.getOperand(0);
>>>> +      if (!OpFI.isFI())
>>>> +        return 0;
>>>> +      const MachineOperand &OpOff = MI.getOperand(1);
>>>> +      if (!OpOff.isImm() || OpOff.getImm() != 0)
>>>> +        return 0;
>>>> +      FrameIndex = OpFI.getIndex();
>>>> +      return MI.getOperand(2).getReg();
>>>> +    }
>>>> +
>>>> +    case Hexagon::S2_pstorerbt_io:
>>>> +    case Hexagon::S2_pstorerbf_io:
>>>> +    case Hexagon::S2_pstorerht_io:
>>>> +    case Hexagon::S2_pstorerhf_io:
>>>> +    case Hexagon::S2_pstorerit_io:
>>>> +    case Hexagon::S2_pstorerif_io:
>>>> +    case Hexagon::S2_pstorerdt_io:
>>>> +    case Hexagon::S2_pstorerdf_io: {
>>>> +      const MachineOperand &OpFI = MI.getOperand(1);
>>>> +      if (!OpFI.isFI())
>>>> +        return 0;
>>>> +      const MachineOperand &OpOff = MI.getOperand(2);
>>>> +      if (!OpOff.isImm() || OpOff.getImm() != 0)
>>>> +        return 0;
>>>> +      FrameIndex = OpFI.getIndex();
>>>> +      return MI.getOperand(3).getReg();
>>>> +    }
>>>>     }
>>>>     return 0;
>>>> @@ -900,7 +900,7 @@ void HexagonInstrInfo::storeRegToStackSl
>>>>         .addFrameIndex(FI).addImm(0)
>>>>         .addReg(SrcReg, KillFlag).addMemOperand(MMO);
>>>>     } else if (Hexagon::ModRegsRegClass.hasSubClassEq(RC)) {
>>>> -    BuildMI(MBB, I, DL, get(Hexagon::STriw_mod))
>>>> +    BuildMI(MBB, I, DL, get(Hexagon::STriw_ctr))
>>>>         .addFrameIndex(FI).addImm(0)
>>>>         .addReg(SrcReg, KillFlag).addMemOperand(MMO);
>>>>     } else if (Hexagon::HvxQRRegClass.hasSubClassEq(RC)) {
>>>> @@ -962,7 +962,7 @@ void HexagonInstrInfo::loadRegFromStackS
>>>>       BuildMI(MBB, I, DL, get(Hexagon::LDriw_pred), DestReg)
>>>>         .addFrameIndex(FI).addImm(0).addMemOperand(MMO);
>>>>     } else if (Hexagon::ModRegsRegClass.hasSubClassEq(RC)) {
>>>> -    BuildMI(MBB, I, DL, get(Hexagon::LDriw_mod), DestReg)
>>>> +    BuildMI(MBB, I, DL, get(Hexagon::LDriw_ctr), DestReg)
>>>>         .addFrameIndex(FI).addImm(0).addMemOperand(MMO);
>>>>     } else if (Hexagon::HvxQRRegClass.hasSubClassEq(RC)) {
>>>>       BuildMI(MBB, I, DL, get(Hexagon::PS_vloadrq_ai), DestReg)
>>>> @@ -1016,6 +1016,20 @@ bool HexagonInstrInfo::expandPostRAPseud
>>>>     DebugLoc DL = MI.getDebugLoc();
>>>>     unsigned Opc = MI.getOpcode();
>>>> +  auto RealCirc = [&](unsigned Opc, bool HasImm = true, unsigned 
>>>> MxOp = 4) {
>>>> +    unsigned Mx = MI.getOperand(MxOp).getReg();
>>>> +    unsigned CSx = (Mx == Hexagon::M0 ? Hexagon::CS0 : Hexagon::CS1);
>>>> +    BuildMI(MBB, MI, DL, get(Hexagon::A2_tfrrcr), CSx)
>>>> +        .add(MI.getOperand((HasImm ? 5 : 4)));
>>>> +    auto MIB = BuildMI(MBB, MI, DL, get(Opc)).add(MI.getOperand(0))
>>>> + .add(MI.getOperand(1)).add(MI.getOperand(2)).add(MI.getOperand(3));
>>>> +    if (HasImm)
>>>> +      MIB.add(MI.getOperand(4));
>>>> +    MIB.addReg(CSx, RegState::Implicit);
>>>> +    MBB.erase(MI);
>>>> +    return true;
>>>> +  };
>>>> +
>>>>     switch (Opc) {
>>>>       case TargetOpcode::COPY: {
>>>>         MachineOperand &MD = MI.getOperand(0);
>>>> @@ -1394,6 +1408,50 @@ bool HexagonInstrInfo::expandPostRAPseud
>>>>         MBB.erase(MI);
>>>>         return true;
>>>> +    case Hexagon::PS_loadrub_pci:
>>>> +      return RealCirc(Hexagon::L2_loadrub_pci);
>>>> +    case Hexagon::PS_loadrb_pci:
>>>> +      return RealCirc(Hexagon::L2_loadrb_pci);
>>>> +    case Hexagon::PS_loadruh_pci:
>>>> +      return RealCirc(Hexagon::L2_loadruh_pci);
>>>> +    case Hexagon::PS_loadrh_pci:
>>>> +      return RealCirc(Hexagon::L2_loadrh_pci);
>>>> +    case Hexagon::PS_loadri_pci:
>>>> +      return RealCirc(Hexagon::L2_loadri_pci);
>>>> +    case Hexagon::PS_loadrd_pci:
>>>> +      return RealCirc(Hexagon::L2_loadrd_pci);
>>>> +    case Hexagon::PS_loadrub_pcr:
>>>> +      return RealCirc(Hexagon::L2_loadrub_pcr, /*HasImm=*/false, 
>>>> /*MxOp=*/3);
>>>> +    case Hexagon::PS_loadrb_pcr:
>>>> +      return RealCirc(Hexagon::L2_loadrb_pcr, /*HasImm=*/false, 
>>>> /*MxOp=*/3);
>>>> +    case Hexagon::PS_loadruh_pcr:
>>>> +      return RealCirc(Hexagon::L2_loadruh_pcr, /*HasImm=*/false, 
>>>> /*MxOp=*/3);
>>>> +    case Hexagon::PS_loadrh_pcr:
>>>> +      return RealCirc(Hexagon::L2_loadrh_pcr, /*HasImm=*/false, 
>>>> /*MxOp=*/3);
>>>> +    case Hexagon::PS_loadri_pcr:
>>>> +      return RealCirc(Hexagon::L2_loadri_pcr, /*HasImm=*/false, 
>>>> /*MxOp=*/3);
>>>> +    case Hexagon::PS_loadrd_pcr:
>>>> +      return RealCirc(Hexagon::L2_loadrd_pcr, /*HasImm=*/false, 
>>>> /*MxOp=*/3);
>>>> +    case Hexagon::PS_storerb_pci:
>>>> +      return RealCirc(Hexagon::S2_storerb_pci, /*HasImm=*/true, 
>>>> /*MxOp=*/3);
>>>> +    case Hexagon::PS_storerh_pci:
>>>> +      return RealCirc(Hexagon::S2_storerh_pci, /*HasImm=*/true, 
>>>> /*MxOp=*/3);
>>>> +    case Hexagon::PS_storerf_pci:
>>>> +      return RealCirc(Hexagon::S2_storerf_pci, /*HasImm=*/true, 
>>>> /*MxOp=*/3);
>>>> +    case Hexagon::PS_storeri_pci:
>>>> +      return RealCirc(Hexagon::S2_storeri_pci, /*HasImm=*/true, 
>>>> /*MxOp=*/3);
>>>> +    case Hexagon::PS_storerd_pci:
>>>> +      return RealCirc(Hexagon::S2_storerd_pci, /*HasImm=*/true, 
>>>> /*MxOp=*/3);
>>>> +    case Hexagon::PS_storerb_pcr:
>>>> +      return RealCirc(Hexagon::S2_storerb_pcr, /*HasImm=*/false, 
>>>> /*MxOp=*/2);
>>>> +    case Hexagon::PS_storerh_pcr:
>>>> +      return RealCirc(Hexagon::S2_storerh_pcr, /*HasImm=*/false, 
>>>> /*MxOp=*/2);
>>>> +    case Hexagon::PS_storerf_pcr:
>>>> +      return RealCirc(Hexagon::S2_storerf_pcr, /*HasImm=*/false, 
>>>> /*MxOp=*/2);
>>>> +    case Hexagon::PS_storeri_pcr:
>>>> +      return RealCirc(Hexagon::S2_storeri_pcr, /*HasImm=*/false, 
>>>> /*MxOp=*/2);
>>>> +    case Hexagon::PS_storerd_pcr:
>>>> +      return RealCirc(Hexagon::S2_storerd_pcr, /*HasImm=*/false, 
>>>> /*MxOp=*/2);
>>>>     }
>>>>     return false;
>>>> @@ -2658,8 +2716,8 @@ bool HexagonInstrInfo::isValidOffset(uns
>>>>     // any size. Later pass knows how to handle it.
>>>>     case Hexagon::STriw_pred:
>>>>     case Hexagon::LDriw_pred:
>>>> -  case Hexagon::STriw_mod:
>>>> -  case Hexagon::LDriw_mod:
>>>> +  case Hexagon::STriw_ctr:
>>>> +  case Hexagon::LDriw_ctr:
>>>>       return true;
>>>>     case Hexagon::PS_fi:
>>>>
>>>> Modified: llvm/trunk/lib/Target/Hexagon/HexagonPseudo.td
>>>> URL: 
>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonPseudo.td?rev=328724&r1=328723&r2=328724&view=diff 
>>>>
>>>> ============================================================================== 
>>>>
>>>> --- llvm/trunk/lib/Target/Hexagon/HexagonPseudo.td (original)
>>>> +++ llvm/trunk/lib/Target/Hexagon/HexagonPseudo.td Wed Mar 28 
>>>> 12:38:29 2018
>>>> @@ -24,7 +24,7 @@ let PrintMethod = "printGlobalOperand" i
>>>>   let isPseudo = 1 in {
>>>>   let isCodeGenOnly = 0 in
>>>>   def A2_iconst : Pseudo<(outs IntRegs:$Rd32),
>>>> -    (ins s27_2Imm:$Ii), "${Rd32}=iconst(#${Ii})">;
>>>> +    (ins s27_2Imm:$Ii), "${Rd32} = iconst(#${Ii})">;
>>>>   def DUPLEX_Pseudo : InstHexagon<(outs),
>>>>       (ins s32_0Imm:$offset), "DUPLEX", [], "", DUPLEX, TypePSEUDO>;
>>>> @@ -34,7 +34,7 @@ let isExtendable = 1, opExtendable = 1,
>>>>       isAsmParserOnly = 1 in
>>>>   def TFRI64_V2_ext : InstHexagon<(outs DoubleRegs:$dst),
>>>>       (ins s32_0Imm:$src1, s8_0Imm:$src2),
>>>> -    "$dst=combine(#$src1,#$src2)", [], "",
>>>> +    "$dst = combine(#$src1,#$src2)", [], "",
>>>>       A2_combineii.Itinerary, TypeALU32_2op>, OpcodeHexagon;
>>>>   // HI/LO Instructions
>>>> @@ -44,7 +44,7 @@ class REG_IMMED<string RegHalf, bit Rs,
>>>>                   InstHexagon rootInst>
>>>>     : InstHexagon<(outs IntRegs:$dst),
>>>>                   (ins u16_0Imm:$imm_value),
>>>> -                "$dst"#RegHalf#"=#$imm_value", [], "",
>>>> +                "$dst"#RegHalf#" = #$imm_value", [], "",
>>>>                   rootInst.Itinerary, rootInst.Type>, OpcodeHexagon {
>>>>       bits<5> dst;
>>>>       bits<32> imm_value;
>>>> @@ -316,7 +316,7 @@ def LDriw_pred : LDInst<(outs PredRegs:$
>>>>   // Load modifier.
>>>>   let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, 
>>>> opExtentBits = 13,
>>>>       isCodeGenOnly = 1, isPseudo = 1, hasSideEffects = 0 in
>>>> -def LDriw_mod : LDInst<(outs ModRegs:$dst),
>>>> +def LDriw_ctr : LDInst<(outs CtrRegs:$dst),
>>>>                           (ins IntRegs:$addr, s32_0Imm:$off),
>>>>                           ".error \"should not emit\"", []>;
>>>> @@ -465,8 +465,8 @@ def STriw_pred : STInst<(outs),
>>>>   // Store modifier.
>>>>   let isExtendable = 1, opExtendable = 1, isExtentSigned = 1, 
>>>> opExtentBits = 13,
>>>>       isCodeGenOnly = 1, isPseudo = 1, hasSideEffects = 0 in
>>>> -def STriw_mod : STInst<(outs),
>>>> -      (ins IntRegs:$addr, s32_0Imm:$off, ModRegs:$src1),
>>>> +def STriw_ctr : STInst<(outs),
>>>> +      (ins IntRegs:$addr, s32_0Imm:$off, CtrRegs:$src1),
>>>>         ".error \"should not emit\"", []>;
>>>>   let isExtendable = 1, opExtendable = 1, opExtentBits = 6,
>>>> @@ -507,3 +507,46 @@ def DuplexIClassC:  InstDuplex < 0xC >;
>>>>   def DuplexIClassD:  InstDuplex < 0xD >;
>>>>   def DuplexIClassE:  InstDuplex < 0xE >;
>>>>   def DuplexIClassF:  InstDuplex < 0xF >;
>>>> +
>>>> +// Pseudos for circular buffer instructions. These are needed in 
>>>> order to
>>>> +// allocate the correct pair of CSx and Mx registers.
>>>> +multiclass NewCircularLoad<RegisterClass RC, MemAccessSize MS> {
>>>> +
>>>> +let isCodeGenOnly = 1, isPseudo = 1, Defs = [CS], Uses = [CS],
>>>> +    addrMode = PostInc, accessSize = MS, hasSideEffects = 0 in {
>>>> +  def NAME#_pci : LDInst<(outs RC:$Rd32, IntRegs:$Rx32),
>>>> +       (ins IntRegs:$Rx32in, s4_0Imm:$Ii, ModRegs:$Mu2, IntRegs:$Cs),
>>>> +       ".error \"should not emit\" ", [], "$Rx32 = $Rx32in", 
>>>> tc_4403ca65>;
>>>> +
>>>> +  def NAME#_pcr : LDInst<(outs RC:$Rd32, IntRegs:$Rx32),
>>>> +       (ins IntRegs:$Rx32in, ModRegs:$Mu2, IntRegs:$Cs),
>>>> +       ".error \"should not emit\" ", [], "$Rx32 = $Rx32in", 
>>>> tc_2fc0c436>;
>>>> +}
>>>> +}
>>>> +
>>>> +defm PS_loadrub : NewCircularLoad<IntRegs, ByteAccess>;
>>>> +defm PS_loadrb : NewCircularLoad<IntRegs, ByteAccess>;
>>>> +defm PS_loadruh : NewCircularLoad<IntRegs, HalfWordAccess>;
>>>> +defm PS_loadrh : NewCircularLoad<IntRegs, HalfWordAccess>;
>>>> +defm PS_loadri : NewCircularLoad<IntRegs, WordAccess>;
>>>> +defm PS_loadrd : NewCircularLoad<DoubleRegs, DoubleWordAccess>;
>>>> +
>>>> +multiclass NewCircularStore<RegisterClass RC, MemAccessSize MS> {
>>>> +
>>>> +let isCodeGenOnly = 1, isPseudo = 1, Defs = [CS], Uses = [CS],
>>>> +    addrMode = PostInc, accessSize = MS, hasSideEffects = 0 in {
>>>> +  def NAME#_pci : STInst<(outs IntRegs:$Rx32),
>>>> +       (ins IntRegs:$Rx32in, s4_0Imm:$Ii, ModRegs:$Mu2, RC:$Rt32, 
>>>> IntRegs:$Cs),
>>>> +       ".error \"should not emit\" ", [], "$Rx32 = $Rx32in", 
>>>> tc_9fdb5406>;
>>>> +
>>>> +  def NAME#_pcr : STInst<(outs IntRegs:$Rx32),
>>>> +       (ins IntRegs:$Rx32in, ModRegs:$Mu2, RC:$Rt32, IntRegs:$Cs),
>>>> +       ".error \"should not emit\" ", [], "$Rx32 = $Rx32in", 
>>>> tc_f86c328a>;
>>>> +}
>>>> +}
>>>> +
>>>> +defm PS_storerb : NewCircularStore<IntRegs, ByteAccess>;
>>>> +defm PS_storerh : NewCircularStore<IntRegs, HalfWordAccess>;
>>>> +defm PS_storerf : NewCircularStore<IntRegs, HalfWordAccess>;
>>>> +defm PS_storeri : NewCircularStore<IntRegs, WordAccess>;
>>>> +defm PS_storerd : NewCircularStore<DoubleRegs, WordAccess>;
>>>>
>>>> Added: llvm/trunk/test/CodeGen/Hexagon/circ_new.ll
>>>> URL: 
>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Hexagon/circ_new.ll?rev=328724&view=auto 
>>>>
>>>> ============================================================================== 
>>>>
>>>> --- llvm/trunk/test/CodeGen/Hexagon/circ_new.ll (added)
>>>> +++ llvm/trunk/test/CodeGen/Hexagon/circ_new.ll Wed Mar 28 12:38:29 
>>>> 2018
>>>> @@ -0,0 +1,294 @@
>>>> +; RUN: llc -march=hexagon < %s | FileCheck %s
>>>> +
>>>> +; CHECK-LABEL: test1
>>>> +; CHECK: m[[REG1:([0-1])]] = r0
>>>> +; CHECK: cs[[REG1]] = r1
>>>> +; CHECK: = memub(r1++#4:circ(m[[REG1]])
>>>> +define zeroext i8 @test1(i32 %mod, i8* %start) local_unnamed_addr #0 {
>>>> +entry:
>>>> +  %0 = tail call { i32, i8* } @llvm.hexagon.L2.loadrub.pci(i8* 
>>>> %start, i32 4, i32 %mod, i8* %start)
>>>> +  %1 = extractvalue { i32, i8* } %0, 0
>>>> +  %conv = trunc i32 %1 to i8
>>>> +  ret i8 %conv
>>>> +}
>>>> +
>>>> +declare { i32, i8* } @llvm.hexagon.L2.loadrub.pci(i8*, i32, i32, 
>>>> i8* nocapture) #1
>>>> +
>>>> +; CHECK-LABEL: test2
>>>> +; CHECK: m[[REG2:([0-1])]] = r0
>>>> +; CHECK: cs[[REG2]] = r1
>>>> +; CHECK: = memb(r1++#4:circ(m[[REG2]])
>>>> +define zeroext i8 @test2(i32 %mod, i8* %start) local_unnamed_addr #0 {
>>>> +entry:
>>>> +  %0 = tail call { i32, i8* } @llvm.hexagon.L2.loadrb.pci(i8* 
>>>> %start, i32 4, i32 %mod, i8* %start)
>>>> +  %1 = extractvalue { i32, i8* } %0, 0
>>>> +  %conv = trunc i32 %1 to i8
>>>> +  ret i8 %conv
>>>> +}
>>>> +
>>>> +declare { i32, i8* } @llvm.hexagon.L2.loadrb.pci(i8*, i32, i32, i8* 
>>>> nocapture) #1
>>>> +
>>>> +; CHECK-LABEL: test3
>>>> +; CHECK: m[[REG3:([0-1])]] = r0
>>>> +; CHECK: cs[[REG3]] = r1
>>>> +; CHECK: = memuh(r1++#4:circ(m[[REG3]])
>>>> +define zeroext i16 @test3(i32 %mod, i8* %start) local_unnamed_addr 
>>>> #0 {
>>>> +entry:
>>>> +  %0 = tail call { i32, i8* } @llvm.hexagon.L2.loadruh.pci(i8* 
>>>> %start, i32 4, i32 %mod, i8* %start)
>>>> +  %1 = extractvalue { i32, i8* } %0, 0
>>>> +  %conv = trunc i32 %1 to i16
>>>> +  ret i16 %conv
>>>> +}
>>>> +
>>>> +declare { i32, i8* } @llvm.hexagon.L2.loadruh.pci(i8*, i32, i32, 
>>>> i8* nocapture) #1
>>>> +
>>>> +; CHECK-LABEL: test4
>>>> +; CHECK: m[[REG4:([0-1])]] = r0
>>>> +; CHECK: cs[[REG4]] = r1
>>>> +; CHECK: = memh(r1++#4:circ(m[[REG4]])
>>>> +define signext i16 @test4(i32 %mod, i8* %start) local_unnamed_addr 
>>>> #0 {
>>>> +entry:
>>>> +  %0 = tail call { i32, i8* } @llvm.hexagon.L2.loadrh.pci(i8* 
>>>> %start, i32 4, i32 %mod, i8* %start)
>>>> +  %1 = extractvalue { i32, i8* } %0, 0
>>>> +  %conv = trunc i32 %1 to i16
>>>> +  ret i16 %conv
>>>> +}
>>>> +
>>>> +declare { i32, i8* } @llvm.hexagon.L2.loadrh.pci(i8*, i32, i32, i8* 
>>>> nocapture) #1
>>>> +
>>>> +; CHECK-LABEL: test5
>>>> +; CHECK: m[[REG5:([0-1])]] = r0
>>>> +; CHECK: cs[[REG5]] = r1
>>>> +; CHECK: = memw(r1++#4:circ(m[[REG5]])
>>>> +define i32 @test5(i32 %mod, i8* %start) local_unnamed_addr #0 {
>>>> +entry:
>>>> +  %0 = tail call { i32, i8* } @llvm.hexagon.L2.loadri.pci(i8* 
>>>> %start, i32 4, i32 %mod, i8* %start)
>>>> +  %1 = extractvalue { i32, i8* } %0, 0
>>>> +  ret i32 %1
>>>> +}
>>>> +
>>>> +declare { i32, i8* } @llvm.hexagon.L2.loadri.pci(i8*, i32, i32, i8* 
>>>> nocapture) #1
>>>> +
>>>> +; CHECK-LABEL: test6
>>>> +; CHECK: m[[REG6:([0-1])]] = r0
>>>> +; CHECK: cs[[REG6]] = r1
>>>> +; CHECK: = memd(r1++#8:circ(m[[REG6]])
>>>> +define i64 @test6(i32 %mod, i8* %start) local_unnamed_addr #0 {
>>>> +entry:
>>>> +  %0 = tail call { i64, i8* } @llvm.hexagon.L2.loadrd.pci(i8* 
>>>> %start, i32 8, i32 %mod, i8* %start)
>>>> +  %1 = extractvalue { i64, i8* } %0, 0
>>>> +  ret i64 %1
>>>> +}
>>>> +
>>>> +declare { i64, i8* } @llvm.hexagon.L2.loadrd.pci(i8*, i32, i32, i8* 
>>>> nocapture) #1
>>>> +
>>>> +; CHECK-LABEL: test7
>>>> +; CHECK: m[[REG7:([0-1])]] = r0
>>>> +; CHECK: cs[[REG7]] = r1
>>>> +; CHECK: = memub(r1++I:circ(m[[REG7]])
>>>> +define zeroext i8 @test7(i32 %mod, i8* %start) local_unnamed_addr #0 {
>>>> +entry:
>>>> +  %0 = tail call { i32, i8* } @llvm.hexagon.L2.loadrub.pcr(i8* 
>>>> %start, i32 %mod, i8* %start)
>>>> +  %1 = extractvalue { i32, i8* } %0, 0
>>>> +  %conv = trunc i32 %1 to i8
>>>> +  ret i8 %conv
>>>> +}
>>>> +
>>>> +declare { i32, i8* } @llvm.hexagon.L2.loadrub.pcr(i8*, i32, i8* 
>>>> nocapture) #1
>>>> +
>>>> +; CHECK-LABEL: test8
>>>> +; CHECK: m[[REG8:([0-1])]] = r0
>>>> +; CHECK: cs[[REG8]] = r1
>>>> +; CHECK: = memb(r1++I:circ(m[[REG8]])
>>>> +define zeroext i8 @test8(i32 %mod, i8* %start) local_unnamed_addr #0 {
>>>> +entry:
>>>> +  %0 = tail call { i32, i8* } @llvm.hexagon.L2.loadrb.pcr(i8* 
>>>> %start, i32 %mod, i8* %start)
>>>> +  %1 = extractvalue { i32, i8* } %0, 0
>>>> +  %conv = trunc i32 %1 to i8
>>>> +  ret i8 %conv
>>>> +}
>>>> +
>>>> +declare { i32, i8* } @llvm.hexagon.L2.loadrb.pcr(i8*, i32, i8* 
>>>> nocapture) #1
>>>> +
>>>> +; CHECK-LABEL: test9
>>>> +; CHECK: m[[REG9:([0-1])]] = r0
>>>> +; CHECK: cs[[REG9]] = r1
>>>> +; CHECK: = memuh(r1++I:circ(m[[REG9]])
>>>> +define zeroext i16 @test9(i32 %mod, i8* %start) local_unnamed_addr 
>>>> #0 {
>>>> +entry:
>>>> +  %0 = tail call { i32, i8* } @llvm.hexagon.L2.loadruh.pcr(i8* 
>>>> %start, i32 %mod, i8* %start)
>>>> +  %1 = extractvalue { i32, i8* } %0, 0
>>>> +  %conv = trunc i32 %1 to i16
>>>> +  ret i16 %conv
>>>> +}
>>>> +
>>>> +declare { i32, i8* } @llvm.hexagon.L2.loadruh.pcr(i8*, i32, i8* 
>>>> nocapture) #1
>>>> +
>>>> +; CHECK-LABEL: test10
>>>> +; CHECK: m[[REG10:([0-1])]] = r0
>>>> +; CHECK: cs[[REG10]] = r1
>>>> +; CHECK: = memh(r1++I:circ(m[[REG10]])
>>>> +define signext i16 @test10(i32 %mod, i8* %start) local_unnamed_addr 
>>>> #0 {
>>>> +entry:
>>>> +  %0 = tail call { i32, i8* } @llvm.hexagon.L2.loadrh.pcr(i8* 
>>>> %start, i32 %mod, i8* %start)
>>>> +  %1 = extractvalue { i32, i8* } %0, 0
>>>> +  %conv = trunc i32 %1 to i16
>>>> +  ret i16 %conv
>>>> +}
>>>> +
>>>> +declare { i32, i8* } @llvm.hexagon.L2.loadrh.pcr(i8*, i32, i8* 
>>>> nocapture) #1
>>>> +
>>>> +; CHECK-LABEL: test11
>>>> +; CHECK: m[[REG11:([0-1])]] = r0
>>>> +; CHECK: cs[[REG11]] = r1
>>>> +; CHECK: = memw(r1++I:circ(m[[REG11]])
>>>> +define i32 @test11(i32 %mod, i8* %start) local_unnamed_addr #0 {
>>>> +entry:
>>>> +  %0 = tail call { i32, i8* } @llvm.hexagon.L2.loadri.pcr(i8* 
>>>> %start, i32 %mod, i8* %start)
>>>> +  %1 = extractvalue { i32, i8* } %0, 0
>>>> +  ret i32 %1
>>>> +}
>>>> +
>>>> +declare { i32, i8* } @llvm.hexagon.L2.loadri.pcr(i8*, i32, i8* 
>>>> nocapture) #1
>>>> +
>>>> +; CHECK-LABEL: test12
>>>> +; CHECK: m[[REG12:([0-1])]] = r0
>>>> +; CHECK: cs[[REG12]] = r1
>>>> +; CHECK: = memd(r1++I:circ(m[[REG12]])
>>>> +define i64 @test12(i32 %mod, i8* %start) local_unnamed_addr #0 {
>>>> +entry:
>>>> +  %0 = tail call { i64, i8* } @llvm.hexagon.L2.loadrd.pcr(i8* 
>>>> %start, i32 %mod, i8* %start)
>>>> +  %1 = extractvalue { i64, i8* } %0, 0
>>>> +  ret i64 %1
>>>> +}
>>>> +
>>>> +declare { i64, i8* } @llvm.hexagon.L2.loadrd.pcr(i8*, i32, i8* 
>>>> nocapture) #1
>>>> +
>>>> +; CHECK-LABEL: test13
>>>> +; CHECK: m[[REG13:([0-1])]] = r0
>>>> +; CHECK: cs[[REG13]] = r1
>>>> +; CHECK: memb(r1++#4:circ(m[[REG13]])) =
>>>> +define void @test13(i32 %mod, i8* %start, i8 zeroext %v) 
>>>> local_unnamed_addr #0 {
>>>> +entry:
>>>> +  %conv = zext i8 %v to i32
>>>> +  %0 = tail call i8* @llvm.hexagon.S2.storerb.pci(i8* %start, i32 
>>>> 4, i32 %mod, i32 %conv, i8* %start)
>>>> +  ret void
>>>> +}
>>>> +
>>>> +declare i8* @llvm.hexagon.S2.storerb.pci(i8*, i32, i32, i32, i8* 
>>>> nocapture) #1
>>>> +
>>>> +; CHECK-LABEL: test14
>>>> +; CHECK: m[[REG14:([0-1])]] = r0
>>>> +; CHECK: cs[[REG14]] = r1
>>>> +; CHECK: memh(r1++#4:circ(m[[REG14]])) =
>>>> +define void @test14(i32 %mod, i8* %start, i16 signext %v) 
>>>> local_unnamed_addr #0 {
>>>> +entry:
>>>> +  %conv = sext i16 %v to i32
>>>> +  %0 = tail call i8* @llvm.hexagon.S2.storerh.pci(i8* %start, i32 
>>>> 4, i32 %mod, i32 %conv, i8* %start)
>>>> +  ret void
>>>> +}
>>>> +
>>>> +declare i8* @llvm.hexagon.S2.storerh.pci(i8*, i32, i32, i32, i8* 
>>>> nocapture) #1
>>>> +
>>>> +; CHECK-LABEL: test15
>>>> +; CHECK: m[[REG15:([0-1])]] = r0
>>>> +; CHECK: cs[[REG15]] = r1
>>>> +; CHECK: memh(r1++#4:circ(m[[REG15]])) = r{{[0-9]+}}.h
>>>> +define void @test15(i32 %mod, i8* %start, i16 signext %v) 
>>>> local_unnamed_addr #0 {
>>>> +entry:
>>>> +  %conv = sext i16 %v to i32
>>>> +  %0 = tail call i8* @llvm.hexagon.S2.storerf.pci(i8* %start, i32 
>>>> 4, i32 %mod, i32 %conv, i8* %start)
>>>> +  ret void
>>>> +}
>>>> +
>>>> +declare i8* @llvm.hexagon.S2.storerf.pci(i8*, i32, i32, i32, i8* 
>>>> nocapture) #1
>>>> +
>>>> +; CHECK-LABEL: test16
>>>> +; CHECK: m[[REG16:([0-1])]] = r0
>>>> +; CHECK: cs[[REG16]] = r1
>>>> +; CHECK: memw(r1++#4:circ(m[[REG16]])) =
>>>> +define void @test16(i32 %mod, i8* %start, i32 %v) 
>>>> local_unnamed_addr #0 {
>>>> +entry:
>>>> +  %0 = tail call i8* @llvm.hexagon.S2.storeri.pci(i8* %start, i32 
>>>> 4, i32 %mod, i32 %v, i8* %start)
>>>> +  ret void
>>>> +}
>>>> +
>>>> +declare i8* @llvm.hexagon.S2.storeri.pci(i8*, i32, i32, i32, i8* 
>>>> nocapture) #1
>>>> +
>>>> +; CHECK-LABEL: test17
>>>> +; CHECK: m[[REG17:([0-1])]] = r0
>>>> +; CHECK: cs[[REG17]] = r1
>>>> +; CHECK: memd(r1++#8:circ(m[[REG17]])) =
>>>> +define void @test17(i32 %mod, i8* %start, i64 %v) 
>>>> local_unnamed_addr #0 {
>>>> +entry:
>>>> +  %0 = tail call i8* @llvm.hexagon.S2.storerd.pci(i8* %start, i32 
>>>> 8, i32 %mod, i64 %v, i8* %start)
>>>> +  ret void
>>>> +}
>>>> +
>>>> +declare i8* @llvm.hexagon.S2.storerd.pci(i8*, i32, i32, i64, i8* 
>>>> nocapture) #1
>>>> +
>>>> +; CHECK-LABEL: test18
>>>> +; CHECK: m[[REG18:([0-1])]] = r0
>>>> +; CHECK: cs[[REG18]] = r1
>>>> +; CHECK: memb(r1++I:circ(m[[REG18]])) =
>>>> +define void @test18(i32 %mod, i8* %start, i8 zeroext %v) 
>>>> local_unnamed_addr #0 {
>>>> +entry:
>>>> +  %conv = zext i8 %v to i32
>>>> +  %0 = tail call i8* @llvm.hexagon.S2.storerb.pcr(i8* %start, i32 
>>>> %mod, i32 %conv, i8* %start)
>>>> +  ret void
>>>> +}
>>>> +
>>>> +declare i8* @llvm.hexagon.S2.storerb.pcr(i8*, i32, i32, i8* 
>>>> nocapture) #1
>>>> +
>>>> +; CHECK-LABEL: test19
>>>> +; CHECK: m[[REG19:([0-1])]] = r0
>>>> +; CHECK: cs[[REG19]] = r1
>>>> +; CHECK: memh(r1++I:circ(m[[REG19]])) =
>>>> +define void @test19(i32 %mod, i8* %start, i16 signext %v) 
>>>> local_unnamed_addr #0 {
>>>> +entry:
>>>> +  %conv = sext i16 %v to i32
>>>> +  %0 = tail call i8* @llvm.hexagon.S2.storerh.pcr(i8* %start, i32 
>>>> %mod, i32 %conv, i8* %start)
>>>> +  ret void
>>>> +}
>>>> +
>>>> +declare i8* @llvm.hexagon.S2.storerh.pcr(i8*, i32, i32, i8* 
>>>> nocapture) #1
>>>> +
>>>> +; CHECK-LABEL: test20
>>>> +; CHECK: m[[REG20:([0-1])]] = r0
>>>> +; CHECK: cs[[REG20]] = r1
>>>> +; CHECK: memh(r1++I:circ(m[[REG20]])) = r{{[0-9]+}}.h
>>>> +define void @test20(i32 %mod, i8* %start, i16 signext %v) 
>>>> local_unnamed_addr #0 {
>>>> +entry:
>>>> +  %conv = sext i16 %v to i32
>>>> +  %0 = tail call i8* @llvm.hexagon.S2.storerf.pcr(i8* %start, i32 
>>>> %mod, i32 %conv, i8* %start)
>>>> +  ret void
>>>> +}
>>>> +
>>>> +declare i8* @llvm.hexagon.S2.storerf.pcr(i8*, i32, i32, i8* 
>>>> nocapture) #1
>>>> +
>>>> +; CHECK-LABEL: test21
>>>> +; CHECK: m[[REG21:([0-1])]] = r0
>>>> +; CHECK: cs[[REG21]] = r1
>>>> +; CHECK: memw(r1++I:circ(m[[REG21]])) =
>>>> +define void @test21(i32 %mod, i8* %start, i32 %v) 
>>>> local_unnamed_addr #0 {
>>>> +entry:
>>>> +  %0 = tail call i8* @llvm.hexagon.S2.storeri.pcr(i8* %start, i32 
>>>> %mod, i32 %v, i8* %start)
>>>> +  ret void
>>>> +}
>>>> +
>>>> +declare i8* @llvm.hexagon.S2.storeri.pcr(i8*, i32, i32, i8* 
>>>> nocapture) #1
>>>> +
>>>> +; CHECK-LABEL: test22
>>>> +; CHECK: m[[REG22:([0-1])]] = r0
>>>> +; CHECK: cs[[REG22]] = r1
>>>> +; CHECK: memd(r1++I:circ(m[[REG1]])) =
>>>> +define void @test22(i32 %mod, i8* %start, i64 %v) 
>>>> local_unnamed_addr #0 {
>>>> +entry:
>>>> +  %0 = tail call i8* @llvm.hexagon.S2.storerd.pcr(i8* %start, i32 
>>>> %mod, i64 %v, i8* %start)
>>>> +  ret void
>>>> +}
>>>> +
>>>> +declare i8* @llvm.hexagon.S2.storerd.pcr(i8*, i32, i64, i8* 
>>>> nocapture) #1
>>>> +
>>>> +attributes #0 = { nounwind "target-cpu"="hexagonv60" }
>>>> +attributes #1 = { argmemonly nounwind }
>>>>
>>>>
>>>> _______________________________________________
>>>> llvm-commits mailing list
>>>> llvm-commits at lists.llvm.org
>>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>>>>
>>
> 

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, 
hosted by The Linux Foundation


More information about the llvm-commits mailing list