[mips] Add microMIPS specific addressing patterns.
authorSimon Dardis <simon.dardis@mips.com>
Wed, 20 Jun 2018 22:40:12 +0000 (22:40 +0000)
committerSimon Dardis <simon.dardis@mips.com>
Wed, 20 Jun 2018 22:40:12 +0000 (22:40 +0000)
These are identical but use microMIPS instructions instead of MIPS instructions.

Also, flatten the 'let AdditionalPredicates = [InMicroMips]' by using the
ISA_MICROMIPS adjective. Add tests for constant materialization.

Reviewers: atanasyan, abeserminji, smaksimovic

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

llvm-svn: 335185

llvm/lib/Target/Mips/MicroMipsInstrInfo.td
llvm/lib/Target/Mips/MipsInstrInfo.td
llvm/test/CodeGen/Mips/address-selection.ll [new file with mode: 0644]
llvm/test/CodeGen/Mips/cstmaterialization/isel-materialization.ll [new file with mode: 0644]

index cd19f1c..171e5ed 100644 (file)
@@ -1165,75 +1165,96 @@ let DecoderNamespace = "MicroMips" in {
 // MicroMips arbitrary patterns that map to one or more instructions
 //===----------------------------------------------------------------------===//
 
-let AdditionalPredicates = [InMicroMips] in {
-  def : MipsPat<(i32 immLi16:$imm),
-                (LI16_MM immLi16:$imm)>;
-
-  defm :  MaterializeImms<i32, ZERO, ADDiu_MM, LUi_MM, ORi_MM>;
-}
-
-let Predicates = [InMicroMips] in {
-  def : MipsPat<(not GPRMM16:$in),
-                (NOT16_MM GPRMM16:$in)>;
-  def : MipsPat<(not GPR32:$in),
-                (NOR_MM GPR32Opnd:$in, ZERO)>;
-
-  def : MipsPat<(add GPRMM16:$src, immSExtAddiur2:$imm),
-                (ADDIUR2_MM GPRMM16:$src, immSExtAddiur2:$imm)>;
-  def : MipsPat<(add GPR32:$src, immSExtAddius5:$imm),
-                (ADDIUS5_MM GPR32:$src, immSExtAddius5:$imm)>;
-  def : MipsPat<(add GPR32:$src, immSExt16:$imm),
-                (ADDiu_MM GPR32:$src, immSExt16:$imm)>;
-
-  def : MipsPat<(and GPRMM16:$src, immZExtAndi16:$imm),
-                (ANDI16_MM GPRMM16:$src, immZExtAndi16:$imm)>;
-  def : MipsPat<(and GPR32:$src, immZExt16:$imm),
-                (ANDi_MM GPR32:$src, immZExt16:$imm)>;
-
-  def : MipsPat<(shl GPRMM16:$src, immZExt2Shift:$imm),
-                (SLL16_MM GPRMM16:$src, immZExt2Shift:$imm)>;
-  def : MipsPat<(shl GPR32:$src, immZExt5:$imm),
-                (SLL_MM GPR32:$src, immZExt5:$imm)>;
-  def : MipsPat<(shl GPR32:$lhs, GPR32:$rhs),
-                (SLLV_MM GPR32:$lhs, GPR32:$rhs)>;
-
-  def : MipsPat<(srl GPRMM16:$src, immZExt2Shift:$imm),
-                (SRL16_MM GPRMM16:$src, immZExt2Shift:$imm)>;
-  def : MipsPat<(srl GPR32:$src, immZExt5:$imm),
-                (SRL_MM GPR32:$src, immZExt5:$imm)>;
-  def : MipsPat<(srl GPR32:$lhs, GPR32:$rhs),
-                (SRLV_MM GPR32:$lhs, GPR32:$rhs)>;
-
-  def : MipsPat<(sra GPR32:$src, immZExt5:$imm),
-                (SRA_MM GPR32:$src, immZExt5:$imm)>;
-  def : MipsPat<(sra GPR32:$lhs, GPR32:$rhs),
-                (SRAV_MM GPR32:$lhs, GPR32:$rhs)>;
-
-  def : MipsPat<(store GPRMM16:$src, addrimm4lsl2:$addr),
-                (SW16_MM GPRMM16:$src, addrimm4lsl2:$addr)>;
-  def : MipsPat<(store GPR32:$src, addr:$addr),
-                (SW_MM GPR32:$src, addr:$addr)>;
-
-  def : MipsPat<(load addrimm4lsl2:$addr),
-                (LW16_MM addrimm4lsl2:$addr)>;
-  def : MipsPat<(load addr:$addr),
-                (LW_MM addr:$addr)>;
-  def : MipsPat<(subc GPR32:$lhs, GPR32:$rhs),
-                (SUBu_MM GPR32:$lhs, GPR32:$rhs)>;
-
-  def : MipsPat<(i32 (extloadi1  addr:$src)), (LBu_MM addr:$src)>,
-        ISA_MICROMIPS;
+defm : MipsHiLoRelocs<LUi_MM, ADDiu_MM, ZERO, GPR32Opnd>, ISA_MICROMIPS;
 
-  def : MipsPat<(i32 (extloadi8  addr:$src)), (LBu_MM addr:$src)>,
-        ISA_MICROMIPS;
+def : MipsPat<(MipsGotHi tglobaladdr:$in), (LUi_MM tglobaladdr:$in)>,
+      ISA_MICROMIPS;
+def : MipsPat<(MipsGotHi texternalsym:$in), (LUi_MM texternalsym:$in)>,
+      ISA_MICROMIPS;
 
-  def : MipsPat<(i32 (extloadi16 addr:$src)), (LHu_MM addr:$src)>,
-        ISA_MICROMIPS;
+// gp_rel relocs
+def : MipsPat<(add GPR32:$gp, (MipsGPRel tglobaladdr:$in)),
+              (ADDiu_MM GPR32:$gp, tglobaladdr:$in)>, ISA_MICROMIPS;
+def : MipsPat<(add GPR32:$gp, (MipsGPRel tconstpool:$in)),
+              (ADDiu_MM GPR32:$gp, tconstpool:$in)>, ISA_MICROMIPS;
+
+def : WrapperPat<tglobaladdr, ADDiu_MM, GPR32>, ISA_MICROMIPS;
+def : WrapperPat<tconstpool, ADDiu_MM, GPR32>, ISA_MICROMIPS;
+def : WrapperPat<texternalsym, ADDiu_MM, GPR32>, ISA_MICROMIPS;
+def : WrapperPat<tblockaddress, ADDiu_MM, GPR32>, ISA_MICROMIPS;
+def : WrapperPat<tjumptable, ADDiu_MM, GPR32>, ISA_MICROMIPS;
+def : WrapperPat<tglobaltlsaddr, ADDiu_MM, GPR32>, ISA_MICROMIPS;
+
+def : MipsPat<(atomic_load_8 addr:$a), (LB_MM addr:$a)>, ISA_MICROMIPS;
+def : MipsPat<(atomic_load_16 addr:$a), (LH_MM addr:$a)>, ISA_MICROMIPS;
+def : MipsPat<(atomic_load_32 addr:$a), (LW_MM addr:$a)>, ISA_MICROMIPS;
+
+def : MipsPat<(i32 immLi16:$imm),
+              (LI16_MM immLi16:$imm)>, ISA_MICROMIPS;
+
+defm :  MaterializeImms<i32, ZERO, ADDiu_MM, LUi_MM, ORi_MM>, ISA_MICROMIPS;
+
+def : MipsPat<(not GPRMM16:$in),
+              (NOT16_MM GPRMM16:$in)>, ISA_MICROMIPS;
+def : MipsPat<(not GPR32:$in),
+              (NOR_MM GPR32Opnd:$in, ZERO)>, ISA_MICROMIPS;
+
+def : MipsPat<(add GPRMM16:$src, immSExtAddiur2:$imm),
+              (ADDIUR2_MM GPRMM16:$src, immSExtAddiur2:$imm)>, ISA_MICROMIPS;
+def : MipsPat<(add GPR32:$src, immSExtAddius5:$imm),
+              (ADDIUS5_MM GPR32:$src, immSExtAddius5:$imm)>, ISA_MICROMIPS;
+def : MipsPat<(add GPR32:$src, immSExt16:$imm),
+              (ADDiu_MM GPR32:$src, immSExt16:$imm)>, ISA_MICROMIPS;
+
+def : MipsPat<(and GPRMM16:$src, immZExtAndi16:$imm),
+              (ANDI16_MM GPRMM16:$src, immZExtAndi16:$imm)>, ISA_MICROMIPS;
+def : MipsPat<(and GPR32:$src, immZExt16:$imm),
+              (ANDi_MM GPR32:$src, immZExt16:$imm)>, ISA_MICROMIPS;
+
+def : MipsPat<(shl GPRMM16:$src, immZExt2Shift:$imm),
+              (SLL16_MM GPRMM16:$src, immZExt2Shift:$imm)>, ISA_MICROMIPS;
+def : MipsPat<(shl GPR32:$src, immZExt5:$imm),
+              (SLL_MM GPR32:$src, immZExt5:$imm)>, ISA_MICROMIPS;
+def : MipsPat<(shl GPR32:$lhs, GPR32:$rhs),
+              (SLLV_MM GPR32:$lhs, GPR32:$rhs)>, ISA_MICROMIPS;
+
+def : MipsPat<(srl GPRMM16:$src, immZExt2Shift:$imm),
+              (SRL16_MM GPRMM16:$src, immZExt2Shift:$imm)>, ISA_MICROMIPS;
+def : MipsPat<(srl GPR32:$src, immZExt5:$imm),
+              (SRL_MM GPR32:$src, immZExt5:$imm)>, ISA_MICROMIPS;
+def : MipsPat<(srl GPR32:$lhs, GPR32:$rhs),
+              (SRLV_MM GPR32:$lhs, GPR32:$rhs)>, ISA_MICROMIPS;
+
+def : MipsPat<(sra GPR32:$src, immZExt5:$imm),
+              (SRA_MM GPR32:$src, immZExt5:$imm)>, ISA_MICROMIPS;
+def : MipsPat<(sra GPR32:$lhs, GPR32:$rhs),
+              (SRAV_MM GPR32:$lhs, GPR32:$rhs)>, ISA_MICROMIPS;
+
+def : MipsPat<(store GPRMM16:$src, addrimm4lsl2:$addr),
+              (SW16_MM GPRMM16:$src, addrimm4lsl2:$addr)>, ISA_MICROMIPS;
+def : MipsPat<(store GPR32:$src, addr:$addr),
+              (SW_MM GPR32:$src, addr:$addr)>, ISA_MICROMIPS;
+
+def : MipsPat<(load addrimm4lsl2:$addr),
+              (LW16_MM addrimm4lsl2:$addr)>, ISA_MICROMIPS;
+def : MipsPat<(load addr:$addr),
+              (LW_MM addr:$addr)>, ISA_MICROMIPS;
+def : MipsPat<(subc GPR32:$lhs, GPR32:$rhs),
+              (SUBu_MM GPR32:$lhs, GPR32:$rhs)>, ISA_MICROMIPS;
+
+def : MipsPat<(i32 (extloadi1  addr:$src)), (LBu_MM addr:$src)>,
+      ISA_MICROMIPS;
+
+def : MipsPat<(i32 (extloadi8  addr:$src)), (LBu_MM addr:$src)>,
+      ISA_MICROMIPS;
+
+def : MipsPat<(i32 (extloadi16 addr:$src)), (LHu_MM addr:$src)>,
+      ISA_MICROMIPS;
+
+let AddedComplexity = 40 in
+  def : MipsPat<(i32 (sextloadi16 addrRegImm:$a)),
+                (LH_MM addrRegImm:$a)>, ISA_MICROMIPS;
 
-  let AddedComplexity = 40 in
-    def : MipsPat<(i32 (sextloadi16 addrRegImm:$a)),
-                  (LH_MM addrRegImm:$a)>, ISA_MICROMIPS;
-}
 
 def : MipsPat<(bswap GPR32:$rt), (ROTR_MM (WSBH_MM GPR32:$rt), 16)>,
       ISA_MICROMIPS;
index d4ab92b..6cd36ac 100644 (file)
@@ -3016,33 +3016,34 @@ multiclass MipsHiLoRelocs<Instruction Lui, Instruction Addiu,
               (Addiu GPROpnd:$hi, tglobaltlsaddr:$lo)>;
 }
 
-defm : MipsHiLoRelocs<LUi, ADDiu, ZERO, GPR32Opnd>;
-
-def : MipsPat<(MipsGotHi tglobaladdr:$in), (LUi tglobaladdr:$in)>;
-def : MipsPat<(MipsGotHi texternalsym:$in), (LUi texternalsym:$in)>;
-
-// gp_rel relocs
-def : MipsPat<(add GPR32:$gp, (MipsGPRel tglobaladdr:$in)),
-              (ADDiu GPR32:$gp, tglobaladdr:$in)>, ABI_NOT_N64;
-def : MipsPat<(add GPR32:$gp, (MipsGPRel tconstpool:$in)),
-              (ADDiu GPR32:$gp, tconstpool:$in)>, ABI_NOT_N64;
-
-// wrapper_pic
-class WrapperPat<SDNode node, Instruction ADDiuOp, RegisterClass RC>:
-      MipsPat<(MipsWrapper RC:$gp, node:$in),
-              (ADDiuOp RC:$gp, node:$in)>;
+let AdditionalPredicates = [NotInMicroMips] in {
+  defm : MipsHiLoRelocs<LUi, ADDiu, ZERO, GPR32Opnd>, ISA_MIPS1;
 
-def : WrapperPat<tglobaladdr, ADDiu, GPR32>;
-def : WrapperPat<tconstpool, ADDiu, GPR32>;
-def : WrapperPat<texternalsym, ADDiu, GPR32>;
-def : WrapperPat<tblockaddress, ADDiu, GPR32>;
-def : WrapperPat<tjumptable, ADDiu, GPR32>;
-def : WrapperPat<tglobaltlsaddr, ADDiu, GPR32>;
+  def : MipsPat<(MipsGotHi tglobaladdr:$in), (LUi tglobaladdr:$in)>, ISA_MIPS1;
+  def : MipsPat<(MipsGotHi texternalsym:$in), (LUi texternalsym:$in)>,
+        ISA_MIPS1;
 
-let AdditionalPredicates = [NotInMicroMips] in {
-// Mips does not have "not", so we expand our way
-def : MipsPat<(not GPR32:$in),
-              (NOR GPR32Opnd:$in, ZERO)>;
+  // gp_rel relocs
+  def : MipsPat<(add GPR32:$gp, (MipsGPRel tglobaladdr:$in)),
+                (ADDiu GPR32:$gp, tglobaladdr:$in)>, ISA_MIPS1, ABI_NOT_N64;
+  def : MipsPat<(add GPR32:$gp, (MipsGPRel tconstpool:$in)),
+                (ADDiu GPR32:$gp, tconstpool:$in)>, ISA_MIPS1, ABI_NOT_N64;
+
+  // wrapper_pic
+  class WrapperPat<SDNode node, Instruction ADDiuOp, RegisterClass RC>:
+        MipsPat<(MipsWrapper RC:$gp, node:$in),
+                (ADDiuOp RC:$gp, node:$in)>;
+
+  def : WrapperPat<tglobaladdr, ADDiu, GPR32>, ISA_MIPS1;
+  def : WrapperPat<tconstpool, ADDiu, GPR32>, ISA_MIPS1;
+  def : WrapperPat<texternalsym, ADDiu, GPR32>, ISA_MIPS1;
+  def : WrapperPat<tblockaddress, ADDiu, GPR32>, ISA_MIPS1;
+  def : WrapperPat<tjumptable, ADDiu, GPR32>, ISA_MIPS1;
+  def : WrapperPat<tglobaltlsaddr, ADDiu, GPR32>, ISA_MIPS1;
+
+  // Mips does not have "not", so we expand our way
+  def : MipsPat<(not GPR32:$in),
+                (NOR GPR32Opnd:$in, ZERO)>, ISA_MIPS1;
 }
 
 // extended loads
diff --git a/llvm/test/CodeGen/Mips/address-selection.ll b/llvm/test/CodeGen/Mips/address-selection.ll
new file mode 100644 (file)
index 0000000..36a1d51
--- /dev/null
@@ -0,0 +1,38 @@
+; RUN: llc -march=mips < %s -debug 2>&1 | FileCheck %s --check-prefix=MIPS
+; RUN: llc -march=mips -relocation-model=pic -mxgot < %s -debug 2>&1 | FileCheck %s --check-prefix=MIPS-XGOT
+
+; RUN: llc -march=mips -mattr=+micromips < %s -debug 2>&1 | FileCheck %s --check-prefix=MM
+; RUN: llc -march=mips -relocation-model=pic -mxgot -mattr=+micromips < %s -debug 2>&1 | FileCheck %s --check-prefix=MM-XGOT
+
+; REQUIRES: asserts
+
+; Tests that the correct ISA is selected for computing a global address.
+
+@x = global i32 0
+@a = global i32 1
+declare i32 @y(i32*, i32)
+
+define i32 @z() {
+entry:
+  %0 = load i32, i32* @a, align 4
+  %1 = call i32 @y(i32 * @x, i32 %0)
+  ret i32 %1
+}
+
+; MIPS-LABEL: ===== Instruction selection ends:
+; MIPS: t[[A:[0-9]+]]: i32 = LUi TargetGlobalAddress:i32<i32* @x> 0 [TF=4]
+; MIPS: t{{.*}}: i32 = ADDiu t[[A]], TargetGlobalAddress:i32<i32* @x> 0 [TF=5]
+
+; MIPS-XGOT-LABEL: ===== Instruction selection ends:
+; MIPS-XGOT: t[[B:[0-9]+]]: i32 = LUi TargetGlobalAddress:i32<i32* @x> 0 [TF=20]
+; MIPS-XGOT: t[[C:[0-9]+]]: i32 = ADDu t[[B]], Register:i32 %0
+; MIPS-XGOT: t{{.*}}: i32,ch = LW<Mem:(load 4 from got)> t[[C]], TargetGlobalAddress:i32<i32* @x> 0 [TF=21], t{{.*}}
+
+; MM-LABEL: ===== Instruction selection ends:
+; MM: t[[A:[0-9]+]]: i32 = LUi_MM TargetGlobalAddress:i32<i32* @x> 0 [TF=4]
+; MM: t{{.*}}: i32 = ADDiu_MM t[[A]], TargetGlobalAddress:i32<i32* @x> 0 [TF=5]
+
+; MM-XGOT-LABEL: ===== Instruction selection ends:
+; MM-XGOT: t[[B:[0-9]+]]: i32 = LUi_MM TargetGlobalAddress:i32<i32* @x> 0 [TF=20]
+; MM-XGOT: t[[C:[0-9]+]]: i32 = ADDU16_MM t[[B]], Register:i32 %0
+; MM-XGOT: t{{.*}}: i32,ch = LW_MM<Mem:(load 4 from got)> t[[C]], TargetGlobalAddress:i32<i32* @x> 0 [TF=21], t0
diff --git a/llvm/test/CodeGen/Mips/cstmaterialization/isel-materialization.ll b/llvm/test/CodeGen/Mips/cstmaterialization/isel-materialization.ll
new file mode 100644 (file)
index 0000000..cc6a7af
--- /dev/null
@@ -0,0 +1,36 @@
+; RUN: llc -march=mips < %s -debug 2>&1 | FileCheck %s --check-prefix=MIPS
+; RUN: llc -march=mips -mattr=+micromips < %s -debug 2>&1 | FileCheck %s --check-prefix=MM
+
+; REQUIRES: asserts
+
+; Test that the correct ISA is selected for the materialization of constants.
+
+; The four parameters are picked to use these instructions: li16, addiu, lui,
+; lui+addiu.
+
+declare void @e(i32)
+declare void @f(i32, i32, i32)
+define void @g() {
+entry:
+  call void @f (i32 1, i32 2048, i32 8388608)
+  call void @e (i32 150994946)
+  ret void
+}
+
+; MIPS-LABEL: ===== Instruction selection ends:
+; MIPS-DAG: t{{[0-9]+}}: i32 = ADDiu Register:i32 $zero, TargetConstant:i32<1>
+; MIPS-DAG: t{{[0-9]+}}: i32 = ADDiu Register:i32 $zero, TargetConstant:i32<2048>
+; MIPS-DAG: t{{[0-9]+}}: i32 = LUi TargetConstant:i32<128>
+; MIPS:     t{{[0-9]+}}: ch,glue = JAL TargetGlobalAddress:i32<void (i32, i32, i32)* @f>
+
+; MIPS:     t[[A:[0-9]+]]: i32 = LUi TargetConstant:i32<2304>
+; MIPS:     t{{[0-9]+}}: i32 = ORi t[[A]], TargetConstant:i32<2>
+
+; MM-LABEL: ===== Instruction selection ends:
+; MM-DAG: t{{[0-9]+}}: i32 = LI16_MM TargetConstant:i32<1>
+; MM-DAG: t{{[0-9]+}}: i32 = ADDiu_MM Register:i32 $zero, TargetConstant:i32<2048>
+; MM-DAG: t{{[0-9]+}}: i32 = LUi_MM TargetConstant:i32<128>
+; MM:     t{{[0-9]+}}: ch,glue = JAL_MM TargetGlobalAddress:i32<void (i32, i32, i32)* @f>
+
+; MM:     t[[A:[0-9]+]]: i32 = LUi_MM TargetConstant:i32<2304>
+; MM:     t{{[0-9]+}}: i32 = ORi_MM t[[A]], TargetConstant:i32<2>