[llvm] [PowerPC ]convert `(setcc (and X, 1), 0, eq)` to `XORI (and X, 1), 1` (PR #168384)
zhijian lin via llvm-commits
llvm-commits at lists.llvm.org
Tue Nov 25 07:13:53 PST 2025
- Previous message: [llvm] [PowerPC ]convert `(setcc (and X, 1), 0, eq)` to `XORI (and X, 1), 1` (PR #168384)
- Next message: [llvm] [PowerPC ]convert `(setcc (and X, 1), 0, eq)` to `XORI (and X, 1), 1` (PR #168384)
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
https://github.com/diggerlin updated https://github.com/llvm/llvm-project/pull/168384
>From 426ad3ae76c80252bd8aa59ba2a6361b6967c163 Mon Sep 17 00:00:00 2001
From: zhijian <zhijian at ca.ibm.com>
Date: Mon, 17 Nov 2025 15:17:57 +0000
Subject: [PATCH 1/4] convert (setcc (and X, 1), 0, eq) --> XORI (and X, 1), 1
---
llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 71 +++++++++++++++++++
.../memCmpUsedInZeroEqualityComparison.ll | 3 +-
2 files changed, 72 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index f55336bafd2518..ea0e31ae470829 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -15775,11 +15775,82 @@ SDValue convertTwoLoadsAndCmpToVCMPEQUB(SelectionDAG &DAG, SDNode *N,
CC == ISD::SETNE ? ISD::SETEQ : ISD::SETNE);
}
+// Detect whether there is a pattern like (setcc (and X, 1), 0, eq).
+// If it is , return true; otherwise return false.
+static bool canConvertSETCCToXori(SDNode *N) {
+ if (N->getOpcode() != ISD::SETCC)
+ return false;
+
+ ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(2))->get();
+ if (CC != ISD::SETEQ)
+ return false;
+
+ SDValue LHS = N->getOperand(0);
+ SDValue RHS = N->getOperand(1);
+
+ // Check the `SDValue &V` is from `and` with `1`.
+ auto IsAndWithOne = [](SDValue &V) {
+ if (V.getOpcode() == ISD::AND) {
+ SDNode *AndNode = V.getNode();
+ for (const SDValue &Op : AndNode->ops())
+ if (auto *C = dyn_cast<ConstantSDNode>(Op))
+ if (C->isOne())
+ return true;
+ }
+ return false;
+ };
+
+ // Check whether the SETCC compare with zero.
+ auto IsCompareWithZero = [](SDValue &V) {
+ if (auto *C = dyn_cast<ConstantSDNode>(V))
+ if (C->isZero())
+ return true;
+ return false;
+ };
+
+ return (IsAndWithOne(LHS) && IsCompareWithZero(RHS)) ||
+ (IsAndWithOne(RHS) && IsCompareWithZero(LHS));
+}
+
+// You must check whether the `SDNode* N` can be converted to Xori using
+// the function `static bool canConvertSETCCToXori(SDNode *N)`
+// before calling the function; otherwise, it may produce incorrect results.
+static SDValue ConvertSETCCToXori(SDNode *N, SelectionDAG &DAG) {
+
+ assert(N->getOpcode() == ISD::SETCC && "Should SETCC SDNode here.");
+ SDValue LHS = N->getOperand(0);
+ SDValue RHS = N->getOperand(1);
+ SDLoc DL(N);
+
+ ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(2))->get();
+ assert((CC == ISD::SETEQ) && "CC must be ISD::SETEQ.");
+ // Rewrite it as XORI (and X, 1), 1.
+ auto MakeXor1 = [&](SDValue V) {
+ EVT VT = V.getValueType();
+ SDValue One = DAG.getConstant(1, DL, VT);
+ SDValue Xor = DAG.getNode(ISD::XOR, DL, VT, V, One);
+ return DAG.getNode(ISD::TRUNCATE, DL, MVT::i1, Xor);
+ };
+
+ if (LHS.getOpcode() == ISD::AND && RHS.getOpcode() != ISD::AND)
+ return MakeXor1(LHS);
+
+ if (RHS.getOpcode() == ISD::AND && LHS.getOpcode() != ISD::AND)
+ return MakeXor1(RHS);
+
+ llvm_unreachable("Should not reach here.");
+}
+
SDValue PPCTargetLowering::combineSetCC(SDNode *N,
DAGCombinerInfo &DCI) const {
assert(N->getOpcode() == ISD::SETCC &&
"Should be called with a SETCC node");
+ // Check if the pattern (setcc (and X, 1), 0, eq) is present.
+ // If it is, rewrite it as XORI (and X, 1), 1.
+ if (canConvertSETCCToXori(N))
+ return ConvertSETCCToXori(N, DCI.DAG);
+
ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(2))->get();
if (CC == ISD::SETNE || CC == ISD::SETEQ) {
SDValue LHS = N->getOperand(0);
diff --git a/llvm/test/CodeGen/PowerPC/memCmpUsedInZeroEqualityComparison.ll b/llvm/test/CodeGen/PowerPC/memCmpUsedInZeroEqualityComparison.ll
index bf86695818689f..8d4dce122a4378 100644
--- a/llvm/test/CodeGen/PowerPC/memCmpUsedInZeroEqualityComparison.ll
+++ b/llvm/test/CodeGen/PowerPC/memCmpUsedInZeroEqualityComparison.ll
@@ -39,9 +39,8 @@ define signext i32 @zeroEqualityTest01(ptr %x, ptr %y) {
; CHECK-NEXT: lxvd2x 35, 0, 3
; CHECK-NEXT: vcmpequb. 2, 3, 2
; CHECK-NEXT: mfocrf 3, 2
+; CHECK-NEXT: not 3, 3
; CHECK-NEXT: rlwinm 3, 3, 25, 31, 31
-; CHECK-NEXT: cntlzw 3, 3
-; CHECK-NEXT: srwi 3, 3, 5
; CHECK-NEXT: blr
%call = tail call signext i32 @memcmp(ptr %x, ptr %y, i64 16)
%not.tobool = icmp ne i32 %call, 0
>From 77e9c5e5af6d2147cb2e71fa28c17e7d8dc7d69b Mon Sep 17 00:00:00 2001
From: zhijian <zhijian at ca.ibm.com>
Date: Mon, 24 Nov 2025 16:07:06 +0000
Subject: [PATCH 2/4] address comment
---
llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index ea0e31ae470829..0008d996241ec0 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -15778,8 +15778,7 @@ SDValue convertTwoLoadsAndCmpToVCMPEQUB(SelectionDAG &DAG, SDNode *N,
// Detect whether there is a pattern like (setcc (and X, 1), 0, eq).
// If it is , return true; otherwise return false.
static bool canConvertSETCCToXori(SDNode *N) {
- if (N->getOpcode() != ISD::SETCC)
- return false;
+ assert(N->getOpcode() == ISD::SETCC && "Should ibe SETCC SDNode here.");
ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(2))->get();
if (CC != ISD::SETEQ)
@@ -15791,8 +15790,7 @@ static bool canConvertSETCCToXori(SDNode *N) {
// Check the `SDValue &V` is from `and` with `1`.
auto IsAndWithOne = [](SDValue &V) {
if (V.getOpcode() == ISD::AND) {
- SDNode *AndNode = V.getNode();
- for (const SDValue &Op : AndNode->ops())
+ for (const SDValue &Op : V.getNode()->ops())
if (auto *C = dyn_cast<ConstantSDNode>(Op))
if (C->isOne())
return true;
@@ -15817,7 +15815,7 @@ static bool canConvertSETCCToXori(SDNode *N) {
// before calling the function; otherwise, it may produce incorrect results.
static SDValue ConvertSETCCToXori(SDNode *N, SelectionDAG &DAG) {
- assert(N->getOpcode() == ISD::SETCC && "Should SETCC SDNode here.");
+ assert(N->getOpcode() == ISD::SETCC && "Should ibe SETCC SDNode here.");
SDValue LHS = N->getOperand(0);
SDValue RHS = N->getOperand(1);
SDLoc DL(N);
>From acd5c6d251003e56c6b6a1e63667b8fb8ea6b989 Mon Sep 17 00:00:00 2001
From: zhijian <zhijian at ca.ibm.com>
Date: Mon, 24 Nov 2025 17:02:09 +0000
Subject: [PATCH 3/4] minor change
---
llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index 0008d996241ec0..8dd4f1eec15b42 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -15778,7 +15778,7 @@ SDValue convertTwoLoadsAndCmpToVCMPEQUB(SelectionDAG &DAG, SDNode *N,
// Detect whether there is a pattern like (setcc (and X, 1), 0, eq).
// If it is , return true; otherwise return false.
static bool canConvertSETCCToXori(SDNode *N) {
- assert(N->getOpcode() == ISD::SETCC && "Should ibe SETCC SDNode here.");
+ assert(N->getOpcode() == ISD::SETCC && "Should be SETCC SDNode here.");
ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(2))->get();
if (CC != ISD::SETEQ)
@@ -15815,7 +15815,7 @@ static bool canConvertSETCCToXori(SDNode *N) {
// before calling the function; otherwise, it may produce incorrect results.
static SDValue ConvertSETCCToXori(SDNode *N, SelectionDAG &DAG) {
- assert(N->getOpcode() == ISD::SETCC && "Should ibe SETCC SDNode here.");
+ assert(N->getOpcode() == ISD::SETCC && "Should be SETCC SDNode here.");
SDValue LHS = N->getOperand(0);
SDValue RHS = N->getOperand(1);
SDLoc DL(N);
>From 3960133eb11f167b05373b5fd70d72d6762312e9 Mon Sep 17 00:00:00 2001
From: zhijian <zhijian at ca.ibm.com>
Date: Tue, 25 Nov 2025 15:22:04 +0000
Subject: [PATCH 4/4] address comment
---
llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index 8dd4f1eec15b42..f1025ad5c3cd57 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -15790,7 +15790,7 @@ static bool canConvertSETCCToXori(SDNode *N) {
// Check the `SDValue &V` is from `and` with `1`.
auto IsAndWithOne = [](SDValue &V) {
if (V.getOpcode() == ISD::AND) {
- for (const SDValue &Op : V.getNode()->ops())
+ for (const SDValue &Op : V->ops())
if (auto *C = dyn_cast<ConstantSDNode>(Op))
if (C->isOne())
return true;
- Previous message: [llvm] [PowerPC ]convert `(setcc (and X, 1), 0, eq)` to `XORI (and X, 1), 1` (PR #168384)
- Next message: [llvm] [PowerPC ]convert `(setcc (and X, 1), 0, eq)` to `XORI (and X, 1), 1` (PR #168384)
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the llvm-commits
mailing list