[SystemZ] Be more careful about inverting CC masks (conditional loads)
authorRichard Sandiford <rsandifo@linux.vnet.ibm.com>
Wed, 31 Jul 2013 12:38:08 +0000 (12:38 +0000)
committerRichard Sandiford <rsandifo@linux.vnet.ibm.com>
Wed, 31 Jul 2013 12:38:08 +0000 (12:38 +0000)
Extend r187495 to conditional loads.  I split this out because the
easiest way seemed to be to force a particular operand order in
SystemZISelDAGToDAG.cpp.

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

lib/Target/SystemZ/SystemZISelDAGToDAG.cpp
lib/Target/SystemZ/SystemZInstrFormats.td
lib/Target/SystemZ/SystemZInstrInfo.td
lib/Target/SystemZ/SystemZOperands.td
lib/Target/SystemZ/SystemZPatterns.td
test/CodeGen/SystemZ/cond-load-01.ll
test/CodeGen/SystemZ/cond-load-02.ll

index b7e966ff011f7f4706c0490eaf59251a21ae495b..d9794b1d6437ffd5c260aa861b5e5f291831acf9 100644 (file)
@@ -1012,6 +1012,27 @@ SDNode *SystemZDAGToDAGISel::Select(SDNode *Node) {
       }
     }
     break;
+
+  case SystemZISD::SELECT_CCMASK: {
+    SDValue Op0 = Node->getOperand(0);
+    SDValue Op1 = Node->getOperand(1);
+    // Prefer to put any load first, so that it can be matched as a
+    // conditional load.
+    if (Op1.getOpcode() == ISD::LOAD && Op0.getOpcode() != ISD::LOAD) {
+      SDValue CCValid = Node->getOperand(2);
+      SDValue CCMask = Node->getOperand(3);
+      uint64_t ConstCCValid =
+        cast<ConstantSDNode>(CCValid.getNode())->getZExtValue();
+      uint64_t ConstCCMask =
+        cast<ConstantSDNode>(CCMask.getNode())->getZExtValue();
+      // Invert the condition.
+      CCMask = CurDAG->getConstant(ConstCCValid ^ ConstCCMask,
+                                   CCMask.getValueType());
+      SDValue Op4 = Node->getOperand(4);
+      Node = CurDAG->UpdateNodeOperands(Node, Op1, Op0, CCValid, CCMask, Op4);
+    }
+    break;
+  }
   }
 
   // Select the default instruction
index c0bb7b73c7633e8ce033c8f3214c1914a09704cd..915891d09d7c19bd1e52b6f231c147eb1c65bdbe 100644 (file)
@@ -735,10 +735,14 @@ class UnaryRILPC<string mnemonic, bits<12> opcode, SDPatternOperator operator,
 }
 
 class CondUnaryRSY<string mnemonic, bits<16> opcode,
-                   RegisterOperand cls, bits<5> bytes,
-                   AddressingMode mode = bdaddr20only>
-  : InstRSY<opcode, (outs cls:$R1), (ins cls:$R1src, mode:$BD2, cond4:$R3),
-            mnemonic#"$R3\t$R1, $BD2", []>,
+                   SDPatternOperator operator, RegisterOperand cls,
+                   bits<5> bytes, AddressingMode mode = bdaddr20only>
+  : InstRSY<opcode, (outs cls:$R1),
+            (ins cls:$R1src, mode:$BD2, cond4:$valid, cond4:$R3),
+            mnemonic#"$R3\t$R1, $BD2",
+            [(set cls:$R1,
+                  (z_select_ccmask (load bdaddr20only:$BD2), cls:$R1src,
+                                   cond4:$valid, cond4:$R3))]>,
     Requires<[FeatureLoadStoreOnCond]> {
   let Constraints = "$R1 = $R1src";
   let DisableEncoding = "$R1src";
index a6efd41d043abaa0c2de85cfb1d36f8d0de5c6d4..341eb90404090a853cab80f73fb3a244795eb0ca 100644 (file)
@@ -272,15 +272,13 @@ let canFoldAsLoad = 1 in {
 
 // Load on condition.
 let isCodeGenOnly = 1, Uses = [CC] in {
-  def LOC  : CondUnaryRSY<"loc",  0xEBF2, GR32, 4>;
-  def LOCG : CondUnaryRSY<"locg", 0xEBE2, GR64, 8>;
+  def LOC  : CondUnaryRSY<"loc",  0xEBF2, nonvolatile_load, GR32, 4>;
+  def LOCG : CondUnaryRSY<"locg", 0xEBE2, nonvolatile_load, GR64, 8>;
 }
 let Uses = [CC] in {
   def AsmLOC  : AsmCondUnaryRSY<"loc",  0xEBF2, GR32, 4>;
   def AsmLOCG : AsmCondUnaryRSY<"locg", 0xEBE2, GR64, 8>;
 }
-defm : CondLoad<LOC,  GR32, nonvolatile_load>;
-defm : CondLoad<LOCG, GR64, nonvolatile_load>;
 
 // Register stores.
 let SimpleBDXStore = 1 in {
index 696ec4f15a17ff03a9d1c1137d12d7407812d8a6..9d7943922807c104761a8af2bba2eeb29c2b6e35 100644 (file)
@@ -110,15 +110,6 @@ class BDLMode<string type, string bitsize, string dispsize, string suffix,
                         !cast<Immediate>("disp"##dispsize##"imm"##bitsize),
                         !cast<Immediate>("imm"##bitsize))>;
 
-//===----------------------------------------------------------------------===//
-// Manipulating CC masks
-//===----------------------------------------------------------------------===//
-
-def INVCC : SDNodeXForm<imm, [{
-  unsigned Value = N->getZExtValue() ^ SystemZ::CCMASK_ANY;
-  return CurDAG->getTargetConstant(Value, MVT::i8);
-}]>;
-
 //===----------------------------------------------------------------------===//
 // Extracting immediate operands from nodes
 // These all create MVT::i64 nodes to ensure the value is not sign-extended
index 5419c2badf9d745a86b4efe80b5a4d23446a7141..74cc5f019a813acff7d20741a1176353d9c7829c 100644 (file)
@@ -54,20 +54,6 @@ multiclass RMWIByte<SDPatternOperator operator, AddressingMode mode,
   def : RMWI<anyextloadi8, operator, truncstorei8, mode, imm64, insn>;
 }
 
-// Record that INSN conditionally performs load operation LOAD into a
-// register of class CLS.  The load may trap even if the condition is false.
-multiclass CondLoad<Instruction insn, RegisterOperand cls,
-                    SDPatternOperator load> {
-  def : Pat<(z_select_ccmask (load bdaddr20only:$addr), cls:$new, uimm8zx4,
-                             uimm8zx4:$cc),
-            (insn cls:$new, bdaddr20only:$addr, uimm8zx4:$cc)>,
-        Requires<[FeatureLoadStoreOnCond]>;
-  def : Pat<(z_select_ccmask cls:$new, (load bdaddr20only:$addr), uimm8zx4,
-                             uimm8zx4:$cc),
-            (insn cls:$new, bdaddr20only:$addr, (INVCC uimm8zx4:$cc))>,
-        Requires<[FeatureLoadStoreOnCond]>;
-}
-
 // Record that INSN performs insertion TYPE into a register of class CLS.
 // The inserted operand is loaded using LOAD from an address of mode MODE.
 multiclass InsertMem<string type, Instruction insn, RegisterOperand cls,
index 59ed90c99e6d5f8e3c2da453edadbad9f0357580..1030226798d1c61a89af33a6f040a01aa6e4b731 100644 (file)
@@ -8,7 +8,7 @@ declare i32 @foo(i32 *)
 define i32 @f1(i32 %easy, i32 *%ptr, i32 %limit) {
 ; CHECK-LABEL: f1:
 ; CHECK: clfi %r4, 42
-; CHECK: locnl %r2, 0(%r3)
+; CHECK: loche %r2, 0(%r3)
 ; CHECK: br %r14
   %cond = icmp ult i32 %limit, 42
   %other = load i32 *%ptr
@@ -32,7 +32,7 @@ define i32 @f2(i32 %easy, i32 *%ptr, i32 %limit) {
 define i32 @f3(i32 %easy, i32 *%base, i32 %limit) {
 ; CHECK-LABEL: f3:
 ; CHECK: clfi %r4, 42
-; CHECK: locnl %r2, 524284(%r3)
+; CHECK: loche %r2, 524284(%r3)
 ; CHECK: br %r14
   %ptr = getelementptr i32 *%base, i64 131071
   %cond = icmp ult i32 %limit, 42
@@ -46,7 +46,7 @@ define i32 @f4(i32 %easy, i32 *%base, i32 %limit) {
 ; CHECK-LABEL: f4:
 ; CHECK: agfi %r3, 524288
 ; CHECK: clfi %r4, 42
-; CHECK: locnl %r2, 0(%r3)
+; CHECK: loche %r2, 0(%r3)
 ; CHECK: br %r14
   %ptr = getelementptr i32 *%base, i64 131072
   %cond = icmp ult i32 %limit, 42
@@ -59,7 +59,7 @@ define i32 @f4(i32 %easy, i32 *%base, i32 %limit) {
 define i32 @f5(i32 %easy, i32 *%base, i32 %limit) {
 ; CHECK-LABEL: f5:
 ; CHECK: clfi %r4, 42
-; CHECK: locnl %r2, -524288(%r3)
+; CHECK: loche %r2, -524288(%r3)
 ; CHECK: br %r14
   %ptr = getelementptr i32 *%base, i64 -131072
   %cond = icmp ult i32 %limit, 42
@@ -73,7 +73,7 @@ define i32 @f6(i32 %easy, i32 *%base, i32 %limit) {
 ; CHECK-LABEL: f6:
 ; CHECK: agfi %r3, -524292
 ; CHECK: clfi %r4, 42
-; CHECK: locnl %r2, 0(%r3)
+; CHECK: loche %r2, 0(%r3)
 ; CHECK: br %r14
   %ptr = getelementptr i32 *%base, i64 -131073
   %cond = icmp ult i32 %limit, 42
@@ -86,7 +86,7 @@ define i32 @f6(i32 %easy, i32 *%base, i32 %limit) {
 define i32 @f7(i32 %alt, i32 %limit) {
 ; CHECK-LABEL: f7:
 ; CHECK: brasl %r14, foo@PLT
-; CHECK: locnl %r2, {{[0-9]+}}(%r15)
+; CHECK: loche %r2, {{[0-9]+}}(%r15)
 ; CHECK: br %r14
   %ptr = alloca i32
   %easy = call i32 @foo(i32 *%ptr)
@@ -100,7 +100,7 @@ define i32 @f7(i32 %alt, i32 %limit) {
 define i32 @f8(i32 %easy, i32 %limit, i64 %base, i64 %index) {
 ; CHECK-LABEL: f8:
 ; CHECK: clfi %r3, 42
-; CHECK: locnl %r2, 0({{%r[1-5]}})
+; CHECK: loche %r2, 0({{%r[1-5]}})
 ; CHECK: br %r14
   %add = add i64 %base, %index
   %ptr = inttoptr i64 %add to i32 *
index 50adb3507dcf0328de59a017e73d40ffed58fcd9..e97f4728bc0b3f6952af1212ba7b4fb93fddbc05 100644 (file)
@@ -8,7 +8,7 @@ declare i64 @foo(i64 *)
 define i64 @f1(i64 %easy, i64 *%ptr, i64 %limit) {
 ; CHECK-LABEL: f1:
 ; CHECK: clgfi %r4, 42
-; CHECK: locgnl %r2, 0(%r3)
+; CHECK: locghe %r2, 0(%r3)
 ; CHECK: br %r14
   %cond = icmp ult i64 %limit, 42
   %other = load i64 *%ptr
@@ -32,7 +32,7 @@ define i64 @f2(i64 %easy, i64 *%ptr, i64 %limit) {
 define i64 @f3(i64 %easy, i64 *%base, i64 %limit) {
 ; CHECK-LABEL: f3:
 ; CHECK: clgfi %r4, 42
-; CHECK: locgnl %r2, 524280(%r3)
+; CHECK: locghe %r2, 524280(%r3)
 ; CHECK: br %r14
   %ptr = getelementptr i64 *%base, i64 65535
   %cond = icmp ult i64 %limit, 42
@@ -46,7 +46,7 @@ define i64 @f4(i64 %easy, i64 *%base, i64 %limit) {
 ; CHECK-LABEL: f4:
 ; CHECK: agfi %r3, 524288
 ; CHECK: clgfi %r4, 42
-; CHECK: locgnl %r2, 0(%r3)
+; CHECK: locghe %r2, 0(%r3)
 ; CHECK: br %r14
   %ptr = getelementptr i64 *%base, i64 65536
   %cond = icmp ult i64 %limit, 42
@@ -59,7 +59,7 @@ define i64 @f4(i64 %easy, i64 *%base, i64 %limit) {
 define i64 @f5(i64 %easy, i64 *%base, i64 %limit) {
 ; CHECK-LABEL: f5:
 ; CHECK: clgfi %r4, 42
-; CHECK: locgnl %r2, -524288(%r3)
+; CHECK: locghe %r2, -524288(%r3)
 ; CHECK: br %r14
   %ptr = getelementptr i64 *%base, i64 -65536
   %cond = icmp ult i64 %limit, 42
@@ -73,7 +73,7 @@ define i64 @f6(i64 %easy, i64 *%base, i64 %limit) {
 ; CHECK-LABEL: f6:
 ; CHECK: agfi %r3, -524296
 ; CHECK: clgfi %r4, 42
-; CHECK: locgnl %r2, 0(%r3)
+; CHECK: locghe %r2, 0(%r3)
 ; CHECK: br %r14
   %ptr = getelementptr i64 *%base, i64 -65537
   %cond = icmp ult i64 %limit, 42
@@ -86,7 +86,7 @@ define i64 @f6(i64 %easy, i64 *%base, i64 %limit) {
 define i64 @f7(i64 %alt, i64 %limit) {
 ; CHECK-LABEL: f7:
 ; CHECK: brasl %r14, foo@PLT
-; CHECK: locgnl %r2, {{[0-9]+}}(%r15)
+; CHECK: locghe %r2, {{[0-9]+}}(%r15)
 ; CHECK: br %r14
   %ptr = alloca i64
   %easy = call i64 @foo(i64 *%ptr)
@@ -100,7 +100,7 @@ define i64 @f7(i64 %alt, i64 %limit) {
 define i64 @f8(i64 %easy, i64 %limit, i64 %base, i64 %index) {
 ; CHECK-LABEL: f8:
 ; CHECK: clgfi %r3, 42
-; CHECK: locgnl %r2, 0({{%r[1-5]}})
+; CHECK: locghe %r2, 0({{%r[1-5]}})
 ; CHECK: br %r14
   %add = add i64 %base, %index
   %ptr = inttoptr i64 %add to i64 *