diff options
-rw-r--r-- | llvm/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp | 5 | ||||
-rw-r--r-- | llvm/test/CodeGen/SystemZ/not-01.ll | 26 |
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 +} + |