summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp5
-rw-r--r--llvm/test/CodeGen/SystemZ/not-01.ll26
2 files changed, 29 insertions, 2 deletions
diff --git a/llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp b/llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp
index 74d66516321..3927a977e6f 100644
--- a/llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp
@@ -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)
diff --git a/llvm/test/CodeGen/SystemZ/not-01.ll b/llvm/test/CodeGen/SystemZ/not-01.ll
index be2a5a88d73..62248d6a1eb 100644
--- a/llvm/test/CodeGen/SystemZ/not-01.ll
+++ b/llvm/test/CodeGen/SystemZ/not-01.ll
@@ -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
+}
+
OpenPOWER on IntegriCloud