[llvm] r330326 - [mips] Correct the definitions of the unaligned word memory operation instructions

Simon Dardis via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 19 06:33:51 PDT 2018


Author: sdardis
Date: Thu Apr 19 06:33:51 2018
New Revision: 330326

URL: http://llvm.org/viewvc/llvm-project?rev=330326&view=rev
Log:
[mips] Correct the definitions of the unaligned word memory operation instructions

These instructions lacked the correct predicates, were not marked
as loads and stores and lacked the proper instruction mapping information.

In the case of microMIPS sw(l|r)e (EVA) these instructions were using the load
EVA description.

Reviewers: abeserminji, smaksimovic, atanasyan

Differential Revision: https://reviews.llvm.org/D45626

Added:
    llvm/trunk/test/CodeGen/Mips/unaligned-memops-mapping.mir
    llvm/trunk/test/CodeGen/Mips/unaligned-memops.ll
Modified:
    llvm/trunk/lib/Target/Mips/MicroMipsInstrFormats.td
    llvm/trunk/lib/Target/Mips/MicroMipsInstrInfo.td
    llvm/trunk/lib/Target/Mips/MipsEVAInstrInfo.td
    llvm/trunk/lib/Target/Mips/MipsInstrInfo.td

Modified: llvm/trunk/lib/Target/Mips/MicroMipsInstrFormats.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MicroMipsInstrFormats.td?rev=330326&r1=330325&r2=330326&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MicroMipsInstrFormats.td (original)
+++ llvm/trunk/lib/Target/Mips/MicroMipsInstrFormats.td Thu Apr 19 06:33:51 2018
@@ -406,7 +406,7 @@ class POOL32C_LHUE_FM_MM<bits<6> op, bit
   let Inst{8-0}  = offset;
 }
 
-class LWL_FM_MM<bits<4> funct> {
+class LWL_FM_MM<bits<4> funct> : MMArch {
   bits<5> rt;
   bits<21> addr;
 
@@ -419,7 +419,7 @@ class LWL_FM_MM<bits<4> funct> {
   let Inst{11-0}  = addr{11-0};
 }
 
-class POOL32C_STEVA_LDEVA_FM_MM<bits<4> type, bits<3> funct> {
+class POOL32C_STEVA_LDEVA_FM_MM<bits<4> type, bits<3> funct> : MMArch {
   bits<5> rt;
   bits<21> addr;
   bits<5> base = addr{20-16};

Modified: llvm/trunk/lib/Target/Mips/MicroMipsInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MicroMipsInstrInfo.td?rev=330326&r1=330325&r2=330326&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MicroMipsInstrInfo.td (original)
+++ llvm/trunk/lib/Target/Mips/MicroMipsInstrInfo.td Thu Apr 19 06:33:51 2018
@@ -201,6 +201,9 @@ class LoadLeftRightMM<string opstr, SDNo
          Itin, FrmI> {
   let DecoderMethod = "DecodeMemMMImm12";
   string Constraints = "$src = $rt";
+  let BaseOpcode = opstr;
+  bit mayLoad = 1;
+  bit mayStore = 0;
 }
 
 class StoreLeftRightMM<string opstr, SDNode OpNode, RegisterOperand RO,
@@ -209,6 +212,9 @@ class StoreLeftRightMM<string opstr, SDN
          !strconcat(opstr, "\t$rt, $addr"),
          [(OpNode RO:$rt, addrimm12:$addr)], Itin, FrmI> {
   let DecoderMethod = "DecodeMemMMImm12";
+  let BaseOpcode = opstr;
+  bit mayLoad = 0;
+  bit mayStore = 1;
 }
 
 /// A register pair used by movep instruction.
@@ -820,19 +826,25 @@ let DecoderNamespace = "MicroMips" in {
                   ISA_MICROMIPS32_NOT_MIPS32R6, ASE_EVA;
   }
 }
-let DecoderNamespace = "MicroMips", Predicates = [InMicroMips] in {
-  def LWXS_MM : LoadWordIndexedScaledMM<"lwxs", GPR32Opnd>, LWXS_FM_MM<0x118>;
+let DecoderNamespace = "MicroMips" in {
+  let Predicates = [InMicroMips] in
+    def LWXS_MM : LoadWordIndexedScaledMM<"lwxs", GPR32Opnd>, LWXS_FM_MM<0x118>;
 
   /// Load and Store Instructions - unaligned
-  def LWL_MM : LoadLeftRightMM<"lwl", MipsLWL, GPR32Opnd, mem_mm_12, II_LWL>,
-               LWL_FM_MM<0x0>;
-  def LWR_MM : LoadLeftRightMM<"lwr", MipsLWR, GPR32Opnd, mem_mm_12, II_LWR>,
-               LWL_FM_MM<0x1>;
-  def SWL_MM : StoreLeftRightMM<"swl", MipsSWL, GPR32Opnd, mem_mm_12, II_SWL>,
-               LWL_FM_MM<0x8>;
-  def SWR_MM : StoreLeftRightMM<"swr", MipsSWR, GPR32Opnd, mem_mm_12, II_SWR>,
-               LWL_FM_MM<0x9>;
-
+  def LWL_MM : MMRel, LoadLeftRightMM<"lwl", MipsLWL, GPR32Opnd, mem_mm_12,
+                                      II_LWL>, LWL_FM_MM<0x0>,
+               ISA_MICROMIPS32_NOT_MIPS32R6;
+  def LWR_MM : MMRel, LoadLeftRightMM<"lwr", MipsLWR, GPR32Opnd, mem_mm_12,
+                                      II_LWR>, LWL_FM_MM<0x1>,
+               ISA_MICROMIPS32_NOT_MIPS32R6;
+  def SWL_MM : MMRel, StoreLeftRightMM<"swl", MipsSWL, GPR32Opnd, mem_mm_12,
+                                       II_SWL>, LWL_FM_MM<0x8>,
+               ISA_MICROMIPS32_NOT_MIPS32R6;
+  def SWR_MM : MMRel, StoreLeftRightMM<"swr", MipsSWR, GPR32Opnd, mem_mm_12,
+                                       II_SWR>, LWL_FM_MM<0x9>,
+               ISA_MICROMIPS32_NOT_MIPS32R6;
+}
+let DecoderNamespace = "MicroMips", Predicates = [InMicroMips] in {
   /// Load and Store Instructions - multiple
   def SWM32_MM  : StoreMultMM<"swm32", II_SWM>, LWM_FM_MM<0xd>;
   def LWM32_MM  : LoadMultMM<"lwm32", II_LWM>, LWM_FM_MM<0x5>;

Modified: llvm/trunk/lib/Target/Mips/MipsEVAInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsEVAInstrInfo.td?rev=330326&r1=330325&r2=330326&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsEVAInstrInfo.td (original)
+++ llvm/trunk/lib/Target/Mips/MipsEVAInstrInfo.td Thu Apr 19 06:33:51 2018
@@ -99,10 +99,12 @@ class LOAD_LEFT_RIGHT_EVA_DESC_BASE<stri
   string Constraints = "$src = $rt";
   bit canFoldAsLoad = 1;
   InstrItinClass Itinerary = itin;
+  bit mayLoad = 1;
+  bit mayStore = 0;
 }
 
-class LWLE_DESC  : LOAD_LEFT_RIGHT_EVA_DESC_BASE<"lwle",  GPR32Opnd, II_LWLE>;
-class LWRE_DESC  : LOAD_LEFT_RIGHT_EVA_DESC_BASE<"lwre",  GPR32Opnd, II_LWRE>;
+class LWLE_DESC : LOAD_LEFT_RIGHT_EVA_DESC_BASE<"lwle", GPR32Opnd, II_LWLE>;
+class LWRE_DESC : LOAD_LEFT_RIGHT_EVA_DESC_BASE<"lwre", GPR32Opnd, II_LWRE>;
 
 class STORE_LEFT_RIGHT_EVA_DESC_BASE<string instr_asm, RegisterOperand GPROpnd,
                                      InstrItinClass itin = NoItinerary> {
@@ -113,10 +115,12 @@ class STORE_LEFT_RIGHT_EVA_DESC_BASE<str
   string DecoderMethod = "DecodeMemEVA";
   string BaseOpcode = instr_asm;
   InstrItinClass Itinerary = itin;
+  bit mayLoad = 0;
+  bit mayStore = 1;
 }
 
-class SWLE_DESC  : LOAD_LEFT_RIGHT_EVA_DESC_BASE<"swle",  GPR32Opnd, II_SWLE>;
-class SWRE_DESC  : LOAD_LEFT_RIGHT_EVA_DESC_BASE<"swre",  GPR32Opnd, II_SWRE>;
+class SWLE_DESC : STORE_LEFT_RIGHT_EVA_DESC_BASE<"swle", GPR32Opnd, II_SWLE>;
+class SWRE_DESC : STORE_LEFT_RIGHT_EVA_DESC_BASE<"swre", GPR32Opnd, II_SWRE>;
 
 // Load-linked EVA, Store-conditional EVA descriptions
 class LLE_DESC_BASE<string instr_asm, RegisterOperand GPROpnd,

Modified: llvm/trunk/lib/Target/Mips/MipsInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsInstrInfo.td?rev=330326&r1=330325&r2=330326&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsInstrInfo.td (original)
+++ llvm/trunk/lib/Target/Mips/MipsInstrInfo.td Thu Apr 19 06:33:51 2018
@@ -1429,6 +1429,7 @@ class LoadLeftRight<string opstr, SDNode
          [(set RO:$rt, (OpNode addr:$addr, RO:$src))], Itin, FrmI> {
   let DecoderMethod = "DecodeMem";
   string Constraints = "$src = $rt";
+  let BaseOpcode = opstr;
 }
 
 class StoreLeftRight<string opstr, SDNode OpNode, RegisterOperand RO,
@@ -1436,6 +1437,7 @@ class StoreLeftRight<string opstr, SDNod
   InstSE<(outs), (ins RO:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
          [(OpNode RO:$rt, addr:$addr)], Itin, FrmI> {
   let DecoderMethod = "DecodeMem";
+  let BaseOpcode = opstr;
 }
 
 // COP2 Load/Store
@@ -2015,19 +2017,16 @@ def SW  : Store<"sw", GPR32Opnd, store,
 }
 
 /// load/store left/right
-let EncodingPredicates = []<Predicate>, // FIXME: Lack of HasStdEnc is probably a bug
-    AdditionalPredicates = [NotInMicroMips] in {
-def LWL : LoadLeftRight<"lwl", MipsLWL, GPR32Opnd, II_LWL>, LW_FM<0x22>,
+let AdditionalPredicates = [NotInMicroMips] in {
+def LWL : MMRel, LoadLeftRight<"lwl", MipsLWL, GPR32Opnd, II_LWL>, LW_FM<0x22>,
           ISA_MIPS1_NOT_32R6_64R6;
-def LWR : LoadLeftRight<"lwr", MipsLWR, GPR32Opnd, II_LWR>, LW_FM<0x26>,
+def LWR : MMRel, LoadLeftRight<"lwr", MipsLWR, GPR32Opnd, II_LWR>, LW_FM<0x26>,
           ISA_MIPS1_NOT_32R6_64R6;
-def SWL : StoreLeftRight<"swl", MipsSWL, GPR32Opnd, II_SWL>, LW_FM<0x2a>,
+def SWL : MMRel, StoreLeftRight<"swl", MipsSWL, GPR32Opnd, II_SWL>, LW_FM<0x2a>,
           ISA_MIPS1_NOT_32R6_64R6;
-def SWR : StoreLeftRight<"swr", MipsSWR, GPR32Opnd, II_SWR>, LW_FM<0x2e>,
+def SWR : MMRel, StoreLeftRight<"swr", MipsSWR, GPR32Opnd, II_SWR>, LW_FM<0x2e>,
           ISA_MIPS1_NOT_32R6_64R6;
-}
 
-let AdditionalPredicates = [NotInMicroMips] in {
 // COP2 Memory Instructions
 def LWC2 : StdMMR6Rel, LW_FT2<"lwc2", COP2Opnd, II_LWC2, load>, LW_FM<0x32>,
            ISA_MIPS1_NOT_32R6_64R6;

Added: llvm/trunk/test/CodeGen/Mips/unaligned-memops-mapping.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Mips/unaligned-memops-mapping.mir?rev=330326&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/Mips/unaligned-memops-mapping.mir (added)
+++ llvm/trunk/test/CodeGen/Mips/unaligned-memops-mapping.mir Thu Apr 19 06:33:51 2018
@@ -0,0 +1,124 @@
+# RUN: llc -O0 -march=mips -mcpu=mips32r3 -mattr=+micromips,+eva -start-after=expand-isel-pseudos \
+# RUN:     -filetype obj %s -o - | llvm-objdump -mattr=+eva -d - | FileCheck %s
+
+# Test that MIPS unaligned load/store instructions can be mapped to their
+# corresponding microMIPS instructions.
+--- |
+  define void @g(i32* %a, i32* %b) {
+  entry:
+    %0 = load i32, i32* %a, align 1
+    store i32 %0, i32* %b, align 1
+    ret void
+  }
+
+  define void @g2(i32* %a, i32* %b) {
+  entry:
+    %0 = load i32, i32* %a, align 1
+    store i32 %0, i32* %b, align 1
+    ret void
+  }
+...
+---
+name:            g
+alignment:       2
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+failedISel:      false
+tracksRegLiveness: true
+liveins:
+  - { reg: '$a0', virtual-reg: '%0' }
+  - { reg: '$a1', virtual-reg: '%1' }
+frameInfo:
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    1
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:
+stack:
+constants:
+body:             |
+  bb.0.entry:
+    liveins: $a0, $a1
+
+    %1:gpr32 = COPY $a1
+    %0:gpr32 = COPY $a0
+    %3:gpr32 = IMPLICIT_DEF
+    %2:gpr32 = LWL %0, 0, %3 :: (load 4 from %ir.a, align 1)
+    %4:gpr32 = LWR %0, 3, %2 :: (load 4 from %ir.a, align 1)
+    SWL %4, %1, 0 :: (store 4 into %ir.b, align 1)
+    SWR %4, %1, 3 :: (store 4 into %ir.b, align 1)
+    RetRA
+
+...
+---
+name:            g2
+alignment:       2
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+failedISel:      false
+tracksRegLiveness: true
+liveins:
+  - { reg: '$a0', virtual-reg: '%0' }
+  - { reg: '$a1', virtual-reg: '%1' }
+frameInfo:
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    1
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:
+stack:
+constants:
+body:             |
+  bb.0.entry:
+    liveins: $a0, $a1
+
+    %1:gpr32 = COPY $a1
+    %0:gpr32 = COPY $a0
+    %3:gpr32 = IMPLICIT_DEF
+    %2:gpr32 = LWLE %0, 0, %3 :: (load 4 from %ir.a, align 1)
+    %4:gpr32 = LWRE %0, 3, %2 :: (load 4 from %ir.a, align 1)
+    SWLE %4, %1, 0 :: (store 4 into %ir.b, align 1)
+    SWRE %4, %1, 3 :: (store 4 into %ir.b, align 1)
+    RetRA
+
+...
+
+# CHECK-LABEL: g:
+# CHECK:  0: 60 24 00 00   lwl $1, 0($4)
+# CHECK:  4: 60 24 10 03   lwr $1, 3($4)
+# CHECK:  8: 60 25 80 00   swl $1, 0($5)
+# CHECK:  c: 60 25 90 03   swr $1, 3($5)
+
+# CHECK-LABEL: g2:
+# CHECK: 14: 60 24 64 00   lwle  $1, 0($4)
+# CHECK: 18: 60 24 66 03   lwre  $1, 3($4)
+# CHECK: 1c: 60 25 a0 00   swle  $1, 0($5)
+# CHECK: 20: 60 25 a2 03   swre  $1, 3($5)

Added: llvm/trunk/test/CodeGen/Mips/unaligned-memops.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Mips/unaligned-memops.ll?rev=330326&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/Mips/unaligned-memops.ll (added)
+++ llvm/trunk/test/CodeGen/Mips/unaligned-memops.ll Thu Apr 19 06:33:51 2018
@@ -0,0 +1,35 @@
+; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+; RUN: llc -march=mips -mcpu=mips32r2 -stop-before=expand-isel-pseudos < %s | FileCheck %s --check-prefix=MIPS
+; RUN: llc -march=mips -mcpu=mips32r2 -mattr=+micromips -stop-before=expand-isel-pseudos < %s | FileCheck %s --check-prefix=MICROMIPS
+
+; Test that the correct ISA version of the unaligned memory operations is
+; selected up front.
+
+define void @g2(i32* %a, i32* %b) {
+  ; MIPS-LABEL: name: g2
+  ; MIPS: bb.0.entry:
+  ; MIPS:   liveins: $a0, $a1
+  ; MIPS:   [[COPY:%[0-9]+]]:gpr32 = COPY $a1
+  ; MIPS:   [[COPY1:%[0-9]+]]:gpr32 = COPY $a0
+  ; MIPS:   [[DEF:%[0-9]+]]:gpr32 = IMPLICIT_DEF
+  ; MIPS:   [[LWL:%[0-9]+]]:gpr32 = LWL [[COPY1]], 0, [[DEF]] :: (load 4 from %ir.a, align 1)
+  ; MIPS:   [[LWR:%[0-9]+]]:gpr32 = LWR [[COPY1]], 3, [[LWL]] :: (load 4 from %ir.a, align 1)
+  ; MIPS:   SWL [[LWR]], [[COPY]], 0 :: (store 4 into %ir.b, align 1)
+  ; MIPS:   SWR [[LWR]], [[COPY]], 3 :: (store 4 into %ir.b, align 1)
+  ; MIPS:   RetRA
+  ; MICROMIPS-LABEL: name: g2
+  ; MICROMIPS: bb.0.entry:
+  ; MICROMIPS:   liveins: $a0, $a1
+  ; MICROMIPS:   [[COPY:%[0-9]+]]:gpr32 = COPY $a1
+  ; MICROMIPS:   [[COPY1:%[0-9]+]]:gpr32 = COPY $a0
+  ; MICROMIPS:   [[DEF:%[0-9]+]]:gpr32 = IMPLICIT_DEF
+  ; MICROMIPS:   [[LWL_MM:%[0-9]+]]:gpr32 = LWL_MM [[COPY1]], 0, [[DEF]] :: (load 4 from %ir.a, align 1)
+  ; MICROMIPS:   [[LWR_MM:%[0-9]+]]:gpr32 = LWR_MM [[COPY1]], 3, [[LWL_MM]] :: (load 4 from %ir.a, align 1)
+  ; MICROMIPS:   SWL_MM [[LWR_MM]], [[COPY]], 0 :: (store 4 into %ir.b, align 1)
+  ; MICROMIPS:   SWR_MM [[LWR_MM]], [[COPY]], 3 :: (store 4 into %ir.b, align 1)
+  ; MICROMIPS:   RetRA
+entry:
+  %0 = load i32, i32* %a, align 1
+  store i32 %0, i32* %b, align 1
+  ret void
+}




More information about the llvm-commits mailing list