[SystemZ] Fix matching another pattern for nxgrk (PR44496)
authorUlrich Weigand <ulrich.weigand@de.ibm.com>
Thu, 9 Jan 2020 18:03:16 +0000 (19:03 +0100)
committerUlrich Weigand <ulrich.weigand@de.ibm.com>
Thu, 9 Jan 2020 18:06:22 +0000 (19:06 +0100)
SystemZDAGToDAGISel::Select will attempt to split logical instruction
with a large immediate constant.  This must not happen if the result
matches one of the z15 combined operations, so the code checks for
those.  However, one of them was missed, causing invalid code to
be generated in the test case for PR44496.

llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp
llvm/test/CodeGen/SystemZ/not-01.ll

index 74d6651..3927a97 100644 (file)
@@ -1497,8 +1497,9 @@ void SystemZDAGToDAGISel::Select(SDNode *Node) {
             if (ChildOpcode == ISD::AND || ChildOpcode == ISD::OR ||
                 ChildOpcode == ISD::XOR)
               break;
-          // Check whether this expression matches OR-with-complement.
-          if (Opcode == ISD::OR && ChildOpcode == ISD::XOR) {
+          // Check whether this expression matches OR-with-complement
+          // (or matches an alternate pattern for NXOR).
+          if (ChildOpcode == ISD::XOR) {
             auto Op0 = Node->getOperand(0);
             if (auto *Op0Op1 = dyn_cast<ConstantSDNode>(Op0->getOperand(1)))
               if (Op0Op1->getZExtValue() == (uint64_t)-1)
index be2a5a8..62248d6 100644 (file)
@@ -124,3 +124,29 @@ define i64 @f12(i64 %a) {
   ret i64 %ret
 }
 
+; NXOR 32-bit (alternate match).
+define i32 @f13(i32 %a) {
+; CHECK-LABEL: f13:
+; CHECK: lhi [[REG:%r[0-5]]], -256
+; CHECK: nxrk %r2, %r2, [[REG]]
+; CHECK: br %r14
+  ; Use an opaque const so the pattern doesn't get optimized away early.
+  %const = bitcast i32 -256 to i32
+  %neg = xor i32 %a, -1
+  %ret = xor i32 %neg, %const
+  ret i32 %ret
+}
+
+; NXOR 64-bit (alternate match).
+define i64 @f14(i64 %a) {
+; CHECK-LABEL: f14:
+; CHECK: lghi [[REG:%r[0-5]]], -256
+; CHECK: nxgrk %r2, %r2, [[REG]]
+; CHECK: br %r14
+  ; Use an opaque const so the pattern doesn't get optimized away early.
+  %const = bitcast i64 -256 to i64
+  %neg = xor i64 %a, -1
+  %ret = xor i64 %neg, %const
+  ret i64 %ret
+}
+