[SystemZ] Fix TMHH and TMHL usage for z10 with -O0
authorRichard Sandiford <rsandifo@linux.vnet.ibm.com>
Fri, 22 Nov 2013 17:28:28 +0000 (17:28 +0000)
committerRichard Sandiford <rsandifo@linux.vnet.ibm.com>
Fri, 22 Nov 2013 17:28:28 +0000 (17:28 +0000)
I've no idea why I decided to handle TMxx differently from all the other
high/low logic operations, but it was a stupid thing to do.  The high
registers aren't available as separate 32-bit registers on z10,
so subreg_h32 can't be used on a GR64 there.

I've normally been testing with z196 and with -O3 and so hadn't noticed
this until now.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@195473 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/SystemZ/SystemZAsmPrinter.cpp
lib/Target/SystemZ/SystemZInstrFormats.td
lib/Target/SystemZ/SystemZInstrInfo.td
lib/Target/SystemZ/SystemZPatterns.td
test/CodeGen/SystemZ/int-cmp-47.ll
test/CodeGen/SystemZ/int-cmp-49.ll [new file with mode: 0644]

index 75efdb0941ac5fd1d8b445fb522f4d1e2ed51629..75cbda4958a221f1b2a2f5b394981a78bcacb93e 100644 (file)
@@ -29,19 +29,29 @@ using namespace llvm;
 // Return an RI instruction like MI with opcode Opcode, but with the
 // GR64 register operands turned into GR32s.
 static MCInst lowerRILow(const MachineInstr *MI, unsigned Opcode) {
-  return MCInstBuilder(Opcode)
-    .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg()))
-    .addReg(SystemZMC::getRegAsGR32(MI->getOperand(1).getReg()))
-    .addImm(MI->getOperand(2).getImm());
+  if (MI->isCompare())
+    return MCInstBuilder(Opcode)
+      .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg()))
+      .addImm(MI->getOperand(1).getImm());
+  else
+    return MCInstBuilder(Opcode)
+      .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg()))
+      .addReg(SystemZMC::getRegAsGR32(MI->getOperand(1).getReg()))
+      .addImm(MI->getOperand(2).getImm());
 }
 
 // Return an RI instruction like MI with opcode Opcode, but with the
 // GR64 register operands turned into GRH32s.
 static MCInst lowerRIHigh(const MachineInstr *MI, unsigned Opcode) {
-  return MCInstBuilder(Opcode)
-    .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg()))
-    .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(1).getReg()))
-    .addImm(MI->getOperand(2).getImm());
+  if (MI->isCompare())
+    return MCInstBuilder(Opcode)
+      .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg()))
+      .addImm(MI->getOperand(1).getImm());
+  else
+    return MCInstBuilder(Opcode)
+      .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg()))
+      .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(1).getReg()))
+      .addImm(MI->getOperand(2).getImm());
 }
 
 // Return an RI instruction like MI with opcode Opcode, but with the
@@ -112,6 +122,8 @@ void SystemZAsmPrinter::EmitInstruction(const MachineInstr *MI) {
 
   LOWER_LOW(IILL);
   LOWER_LOW(IILH);
+  LOWER_LOW(TMLL);
+  LOWER_LOW(TMLH);
   LOWER_LOW(NILL);
   LOWER_LOW(NILH);
   LOWER_LOW(NILF);
@@ -127,6 +139,8 @@ void SystemZAsmPrinter::EmitInstruction(const MachineInstr *MI) {
 
   LOWER_HIGH(IIHL);
   LOWER_HIGH(IIHH);
+  LOWER_HIGH(TMHL);
+  LOWER_HIGH(TMHH);
   LOWER_HIGH(NIHL);
   LOWER_HIGH(NIHH);
   LOWER_HIGH(NIHF);
index 353a0d3f73748cc7030bf35d1cec5def6c237dce..a8efe165e36f172f3db2bc2fff90d698ecc3db5c 100644 (file)
@@ -1588,6 +1588,13 @@ class BinaryAliasRIL<SDPatternOperator operator, RegisterOperand cls,
   let Constraints = "$R1 = $R1src";
 }
 
+// An alias of a CompareRI, but with different register sizes.
+class CompareAliasRI<SDPatternOperator operator, RegisterOperand cls,
+                     Immediate imm>
+  : Alias<4, (outs), (ins cls:$R1, imm:$I2), [(operator cls:$R1, imm:$I2)]> {
+  let isCompare = 1;
+}
+
 // An alias of a RotateSelectRIEf, but with different register sizes.
 class RotateSelectAliasRIEf<RegisterOperand cls1, RegisterOperand cls2>
   : Alias<6, (outs cls1:$R1),
index eb416036bf663dea0592569ca94837e25d6a6fb9..6524e442b63d893efb40b46001949d77bcaa8eda 100644 (file)
@@ -1176,12 +1176,13 @@ let Defs = [CC] in {
   def TMHL : CompareRI<"tmhl", 0xA73, z_tm_reg, GRH32, imm32ll16>;
   def TMHH : CompareRI<"tmhh", 0xA72, z_tm_reg, GRH32, imm32lh16>;
 
+  def TMLL64 : CompareAliasRI<z_tm_reg, GR64, imm64ll16>;
+  def TMLH64 : CompareAliasRI<z_tm_reg, GR64, imm64lh16>;
+  def TMHL64 : CompareAliasRI<z_tm_reg, GR64, imm64hl16>;
+  def TMHH64 : CompareAliasRI<z_tm_reg, GR64, imm64hh16>;
+
   defm TM : CompareSIPair<"tm", 0x91, 0xEB51, z_tm_mem, anyextloadi8, imm32zx8>;
 }
-def : CompareGR64RI<TMLL, z_tm_reg, imm64ll16, subreg_l32>;
-def : CompareGR64RI<TMLH, z_tm_reg, imm64lh16, subreg_l32>;
-def : CompareGR64RI<TMHL, z_tm_reg, imm64hl16, subreg_h32>;
-def : CompareGR64RI<TMHH, z_tm_reg, imm64hh16, subreg_h32>;
 
 //===----------------------------------------------------------------------===//
 // Prefetch
index f3ca60b27ad9dc79c35a36b16ac7879b81dbab8b..7706351e54b3a15fe5ecc23e461390a1f1e3333a 100644 (file)
@@ -112,14 +112,6 @@ multiclass CondStores64<Instruction insn, Instruction insninv,
                      uimm8zx4:$valid, uimm8zx4:$cc)>;
 }
 
-// INSN performs a comparison between a 32-bit register and a constant.
-// Record that it is equivalent to comparing subreg SUBREG of a GR64 with IMM.
-class CompareGR64RI<Instruction insn, SDPatternOperator compare,
-                    Immediate imm, SubRegIndex subreg>
-  : Pat<(compare GR64:$R1, imm:$I2),
-        (insn (EXTRACT_SUBREG GR64:$R1, subreg),
-              (imm.OperandTransform imm:$I2))>;
-
 // Try to use MVC instruction INSN for a load of type LOAD followed by a store
 // of the same size.  VT is the type of the intermediate (legalized) value and
 // LENGTH is the number of bytes loaded by LOAD.
index c770ccdbb96968d9136058a0a0deef3ec8241f4a..9ebcbfe525babda2c9fb5cd2a6113e6e7bc57a3c 100644 (file)
@@ -1,5 +1,6 @@
 ; Test the use of TEST UNDER MASK for 64-bit operations.
 ;
+; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 | FileCheck %s
 ; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 | FileCheck %s
 
 @g = global i32 0
diff --git a/test/CodeGen/SystemZ/int-cmp-49.ll b/test/CodeGen/SystemZ/int-cmp-49.ll
new file mode 100644 (file)
index 0000000..83f18a2
--- /dev/null
@@ -0,0 +1,49 @@
+; That that we don't try to use z196 instructions on z10 for TMHH and TMHL.
+;
+; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 -O0 | FileCheck %s
+
+@g = global i32 0
+
+; Check the lowest useful TMHL value.
+define void @f1(i64 %a) {
+; CHECK-LABEL: f1:
+; CHECK-NOT: risblg
+; CHECK-NOT: risbhg
+; CHECK: tmhl {{%r[0-5]}}, 1
+; CHECK-NOT: risblg
+; CHECK-NOT: risbhg
+; CHECK: br %r14
+entry:
+  %and = and i64 %a, 4294967296
+  %cmp = icmp eq i64 %and, 0
+  br i1 %cmp, label %exit, label %store
+
+store:
+  store i32 1, i32 *@g
+  br label %exit
+
+exit:
+  ret void
+}
+
+; Check the lowest useful TMHH value.
+define void @f2(i64 %a) {
+; CHECK-LABEL: f2:
+; CHECK-NOT: risblg
+; CHECK-NOT: risbhg
+; CHECK: tmhh {{%r[0-5]}}, 1
+; CHECK-NOT: risblg
+; CHECK-NOT: risbhg
+; CHECK: br %r14
+entry:
+  %and = and i64 %a, 281474976710656
+  %cmp = icmp ne i64 %and, 0
+  br i1 %cmp, label %exit, label %store
+
+store:
+  store i32 1, i32 *@g
+  br label %exit
+
+exit:
+  ret void
+}