Skip to content

Commit 0c9c62a

Browse files
authored
[PowerPC ]convert (setcc (and X, 1), 0, eq) to XORI (and X, 1), 1 (#168384)
Convert `(setcc (and X, 1), 0, eq)` to `XORI (and X, 1), 1` , it will save one instruction.
1 parent f545c2c commit 0c9c62a

File tree

2 files changed

+70
-2
lines changed

2 files changed

+70
-2
lines changed

llvm/lib/Target/PowerPC/PPCISelLowering.cpp

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15628,11 +15628,80 @@ SDValue convertTwoLoadsAndCmpToVCMPEQUB(SelectionDAG &DAG, SDNode *N,
1562815628
CC == ISD::SETNE ? ISD::SETEQ : ISD::SETNE);
1562915629
}
1563015630

15631+
// Detect whether there is a pattern like (setcc (and X, 1), 0, eq).
15632+
// If it is , return true; otherwise return false.
15633+
static bool canConvertSETCCToXori(SDNode *N) {
15634+
assert(N->getOpcode() == ISD::SETCC && "Should be SETCC SDNode here.");
15635+
15636+
ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(2))->get();
15637+
if (CC != ISD::SETEQ)
15638+
return false;
15639+
15640+
SDValue LHS = N->getOperand(0);
15641+
SDValue RHS = N->getOperand(1);
15642+
15643+
// Check the `SDValue &V` is from `and` with `1`.
15644+
auto IsAndWithOne = [](SDValue &V) {
15645+
if (V.getOpcode() == ISD::AND) {
15646+
for (const SDValue &Op : V->ops())
15647+
if (auto *C = dyn_cast<ConstantSDNode>(Op))
15648+
if (C->isOne())
15649+
return true;
15650+
}
15651+
return false;
15652+
};
15653+
15654+
// Check whether the SETCC compare with zero.
15655+
auto IsCompareWithZero = [](SDValue &V) {
15656+
if (auto *C = dyn_cast<ConstantSDNode>(V))
15657+
if (C->isZero())
15658+
return true;
15659+
return false;
15660+
};
15661+
15662+
return (IsAndWithOne(LHS) && IsCompareWithZero(RHS)) ||
15663+
(IsAndWithOne(RHS) && IsCompareWithZero(LHS));
15664+
}
15665+
15666+
// You must check whether the `SDNode* N` can be converted to Xori using
15667+
// the function `static bool canConvertSETCCToXori(SDNode *N)`
15668+
// before calling the function; otherwise, it may produce incorrect results.
15669+
static SDValue ConvertSETCCToXori(SDNode *N, SelectionDAG &DAG) {
15670+
15671+
assert(N->getOpcode() == ISD::SETCC && "Should be SETCC SDNode here.");
15672+
SDValue LHS = N->getOperand(0);
15673+
SDValue RHS = N->getOperand(1);
15674+
SDLoc DL(N);
15675+
15676+
ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(2))->get();
15677+
assert((CC == ISD::SETEQ) && "CC must be ISD::SETEQ.");
15678+
// Rewrite it as XORI (and X, 1), 1.
15679+
auto MakeXor1 = [&](SDValue V) {
15680+
EVT VT = V.getValueType();
15681+
SDValue One = DAG.getConstant(1, DL, VT);
15682+
SDValue Xor = DAG.getNode(ISD::XOR, DL, VT, V, One);
15683+
return DAG.getNode(ISD::TRUNCATE, DL, MVT::i1, Xor);
15684+
};
15685+
15686+
if (LHS.getOpcode() == ISD::AND && RHS.getOpcode() != ISD::AND)
15687+
return MakeXor1(LHS);
15688+
15689+
if (RHS.getOpcode() == ISD::AND && LHS.getOpcode() != ISD::AND)
15690+
return MakeXor1(RHS);
15691+
15692+
llvm_unreachable("Should not reach here.");
15693+
}
15694+
1563115695
SDValue PPCTargetLowering::combineSetCC(SDNode *N,
1563215696
DAGCombinerInfo &DCI) const {
1563315697
assert(N->getOpcode() == ISD::SETCC &&
1563415698
"Should be called with a SETCC node");
1563515699

15700+
// Check if the pattern (setcc (and X, 1), 0, eq) is present.
15701+
// If it is, rewrite it as XORI (and X, 1), 1.
15702+
if (canConvertSETCCToXori(N))
15703+
return ConvertSETCCToXori(N, DCI.DAG);
15704+
1563615705
ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(2))->get();
1563715706
if (CC == ISD::SETNE || CC == ISD::SETEQ) {
1563815707
SDValue LHS = N->getOperand(0);

llvm/test/CodeGen/PowerPC/memCmpUsedInZeroEqualityComparison.ll

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,8 @@ define signext i32 @zeroEqualityTest01(ptr %x, ptr %y) {
3939
; CHECK-NEXT: lxvd2x 35, 0, 3
4040
; CHECK-NEXT: vcmpequb. 2, 3, 2
4141
; CHECK-NEXT: mfocrf 3, 2
42+
; CHECK-NEXT: not 3, 3
4243
; CHECK-NEXT: rlwinm 3, 3, 25, 31, 31
43-
; CHECK-NEXT: cntlzw 3, 3
44-
; CHECK-NEXT: srwi 3, 3, 5
4544
; CHECK-NEXT: blr
4645
%call = tail call signext i32 @memcmp(ptr %x, ptr %y, i64 16)
4746
%not.tobool = icmp ne i32 %call, 0

0 commit comments

Comments
 (0)