[llvm] [PowerPC] Combine sub within setcc back to sext (PR #66978)
Qiu Chaofan via llvm-commits
llvm-commits at lists.llvm.org
Tue Apr 9 19:44:08 PDT 2024
https://github.com/ecnelises updated https://github.com/llvm/llvm-project/pull/66978
>From d91592afbcd97e2ec3f0f3825fc3a6efc8ab84b0 Mon Sep 17 00:00:00 2001
From: Qiu Chaofan <qiucofan at cn.ibm.com>
Date: Wed, 6 Sep 2023 16:16:34 +0800
Subject: [PATCH 1/3] [PowerPC] Combine sub within setcc back to sext
---
llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 60 +++++++++++++++++----
llvm/test/CodeGen/PowerPC/setcc-to-sub.ll | 51 ++++++++----------
2 files changed, 72 insertions(+), 39 deletions(-)
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index 43e4a34a9b3483..ce518015793515 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -14527,15 +14527,18 @@ SDValue PPCTargetLowering::DAGCombineExtBoolTrunc(SDNode *N,
ShiftCst);
}
-SDValue PPCTargetLowering::combineSetCC(SDNode *N,
- DAGCombinerInfo &DCI) const {
- assert(N->getOpcode() == ISD::SETCC &&
- "Should be called with a SETCC node");
+SDValue PPCTargetLowering::combineSetCC(SDNode *N, DAGCombinerInfo &DCI) const {
+ assert(N->getOpcode() == ISD::SETCC && "Should be called with a SETCC node");
ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(2))->get();
+ SDValue LHS = N->getOperand(0);
+ SDValue RHS = N->getOperand(1);
+ SDLoc DL(N);
+ SelectionDAG &DAG = DCI.DAG;
+ EVT VT = N->getValueType(0);
+ EVT OpVT = LHS.getValueType();
+
if (CC == ISD::SETNE || CC == ISD::SETEQ) {
- SDValue LHS = N->getOperand(0);
- SDValue RHS = N->getOperand(1);
// If there is a '0 - y' pattern, canonicalize the pattern to the RHS.
if (LHS.getOpcode() == ISD::SUB && isNullConstant(LHS.getOperand(0)) &&
@@ -14546,15 +14549,52 @@ SDValue PPCTargetLowering::combineSetCC(SDNode *N,
// x != 0-y --> x+y != 0
if (RHS.getOpcode() == ISD::SUB && isNullConstant(RHS.getOperand(0)) &&
RHS.hasOneUse()) {
- SDLoc DL(N);
- SelectionDAG &DAG = DCI.DAG;
- EVT VT = N->getValueType(0);
- EVT OpVT = LHS.getValueType();
SDValue Add = DAG.getNode(ISD::ADD, DL, OpVT, LHS, RHS.getOperand(1));
return DAG.getSetCC(DL, VT, Add, DAG.getConstant(0, DL, OpVT), CC);
}
}
+ if (CC == ISD::SETULT && isa<ConstantSDNode>(RHS)) {
+ uint64_t RHSVal = cast<ConstantSDNode>(RHS)->getZExtValue();
+ if (LHS.getOpcode() == ISD::ADD && isa<ConstantSDNode>(LHS.getOperand(1))) {
+ uint64_t Addend = cast<ConstantSDNode>(LHS.getOperand(1))->getZExtValue();
+ if (OpVT == MVT::i64) {
+ uint64_t ShiftVal = ~Addend + 1;
+ uint64_t CmpVal = ~RHSVal + 1;
+ if (isPowerOf2_64(ShiftVal) && ShiftVal << 1 == CmpVal) {
+ unsigned DestBits = Log2_64(CmpVal);
+ if (DestBits == 8 || DestBits == 16 || DestBits == 32) {
+ SDValue Conv = DAG.getSExtOrTrunc(
+ DAG.getSExtOrTrunc(LHS.getOperand(0), DL,
+ MVT::getIntegerVT(DestBits)),
+ DL, OpVT);
+ return DAG.getSetCC(DL, VT, LHS.getOperand(0), Conv, ISD::SETNE);
+ }
+ }
+ } else if (OpVT == MVT::i32) {
+ if (RHSVal == 0xffffff00 && Addend == 0xffffff80) {
+ SDValue Conv = DAG.getSExtOrTrunc(
+ DAG.getSExtOrTrunc(LHS.getOperand(0), DL, MVT::i8), DL, OpVT);
+ return DAG.getSetCC(DL, VT, LHS.getOperand(0), Conv, ISD::SETNE);
+ }
+ }
+ } else if (LHS.getOpcode() == ISD::SRL &&
+ LHS.getOperand(0).getOpcode() == ISD::ADD &&
+ isa<ConstantSDNode>(LHS.getOperand(1)) &&
+ isa<ConstantSDNode>(LHS.getOperand(0).getOperand(1))) {
+ if (RHSVal == 0xffff &&
+ cast<ConstantSDNode>(LHS.getOperand(1))->getZExtValue() == 16 &&
+ cast<ConstantSDNode>(LHS.getOperand(0).getOperand(1))
+ ->getZExtValue() == 0xffff8000) {
+ SDValue Conv = DAG.getSExtOrTrunc(
+ DAG.getSExtOrTrunc(LHS.getOperand(0).getOperand(0), DL, MVT::i16),
+ DL, OpVT);
+ return DAG.getSetCC(DL, VT, LHS.getOperand(0).getOperand(0), Conv,
+ ISD::SETNE);
+ }
+ }
+ }
+
return DAGCombineTruncBoolExt(N, DCI);
}
diff --git a/llvm/test/CodeGen/PowerPC/setcc-to-sub.ll b/llvm/test/CodeGen/PowerPC/setcc-to-sub.ll
index 20dcb8ccf4908a..1e4d2db2509b25 100644
--- a/llvm/test/CodeGen/PowerPC/setcc-to-sub.ll
+++ b/llvm/test/CodeGen/PowerPC/setcc-to-sub.ll
@@ -92,12 +92,10 @@ entry:
define zeroext i1 @test5(i64 %a) {
; CHECK-LABEL: test5:
; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: li 4, -1
-; CHECK-NEXT: addis 3, 3, -32768
-; CHECK-NEXT: rldic 4, 4, 32, 0
-; CHECK-NEXT: subc 4, 3, 4
-; CHECK-NEXT: subfe 3, 3, 3
-; CHECK-NEXT: neg 3, 3
+; CHECK-NEXT: extsw 4, 3
+; CHECK-NEXT: xor 3, 3, 4
+; CHECK-NEXT: addic 4, 3, -1
+; CHECK-NEXT: subfe 3, 4, 3
; CHECK-NEXT: blr
entry:
%0 = add i64 %a, -2147483648
@@ -108,11 +106,10 @@ entry:
define zeroext i1 @test6(i64 %a) {
; CHECK-LABEL: test6:
; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: addi 3, 3, -32768
-; CHECK-NEXT: lis 4, -1
-; CHECK-NEXT: subc 4, 3, 4
-; CHECK-NEXT: subfe 3, 3, 3
-; CHECK-NEXT: neg 3, 3
+; CHECK-NEXT: extsh 4, 3
+; CHECK-NEXT: xor 3, 3, 4
+; CHECK-NEXT: addic 4, 3, -1
+; CHECK-NEXT: subfe 3, 4, 3
; CHECK-NEXT: blr
entry:
%0 = add i64 %a, -32768
@@ -123,11 +120,10 @@ entry:
define zeroext i1 @test7(i64 %a) {
; CHECK-LABEL: test7:
; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: addi 3, 3, -128
-; CHECK-NEXT: li 4, -256
-; CHECK-NEXT: subc 4, 3, 4
-; CHECK-NEXT: subfe 3, 3, 3
-; CHECK-NEXT: neg 3, 3
+; CHECK-NEXT: extsb 4, 3
+; CHECK-NEXT: xor 3, 3, 4
+; CHECK-NEXT: addic 4, 3, -1
+; CHECK-NEXT: subfe 3, 4, 3
; CHECK-NEXT: blr
entry:
%0 = add i64 %a, -128
@@ -138,12 +134,11 @@ entry:
define zeroext i1 @test8(i32 %a) {
; CHECK-LABEL: test8:
; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: addi 3, 3, -32768
-; CHECK-NEXT: lis 4, -1
-; CHECK-NEXT: rlwinm 3, 3, 16, 16, 31
-; CHECK-NEXT: ori 4, 4, 1
-; CHECK-NEXT: add 3, 3, 4
-; CHECK-NEXT: rldicl 3, 3, 1, 63
+; CHECK-NEXT: extsh 4, 3
+; CHECK-NEXT: xor 3, 3, 4
+; CHECK-NEXT: cntlzw 3, 3
+; CHECK-NEXT: srwi 3, 3, 5
+; CHECK-NEXT: xori 3, 3, 1
; CHECK-NEXT: blr
entry:
%0 = add i32 %a, -32768
@@ -154,13 +149,11 @@ entry:
define zeroext i1 @test9(i32 %a) {
; CHECK-LABEL: test9:
; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: lis 4, -256
-; CHECK-NEXT: addi 3, 3, -128
-; CHECK-NEXT: ori 4, 4, 1
-; CHECK-NEXT: clrldi 3, 3, 32
-; CHECK-NEXT: rldic 4, 4, 8, 0
-; CHECK-NEXT: add 3, 3, 4
-; CHECK-NEXT: rldicl 3, 3, 1, 63
+; CHECK-NEXT: extsb 4, 3
+; CHECK-NEXT: xor 3, 3, 4
+; CHECK-NEXT: cntlzw 3, 3
+; CHECK-NEXT: srwi 3, 3, 5
+; CHECK-NEXT: xori 3, 3, 1
; CHECK-NEXT: blr
entry:
%0 = add i32 %a, -128
>From 574c969c51943ca86a9ff1176496bb9990a52d99 Mon Sep 17 00:00:00 2001
From: Qiu Chaofan <qiucofan at cn.ibm.com>
Date: Wed, 3 Apr 2024 17:33:37 +0800
Subject: [PATCH 2/3] Simplify patterns
---
llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 71 ++++++++++-----------
llvm/test/CodeGen/PowerPC/setcc-to-sub.ll | 13 ++--
2 files changed, 42 insertions(+), 42 deletions(-)
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index ce518015793515..e20a3da79e9309 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -14554,44 +14554,43 @@ SDValue PPCTargetLowering::combineSetCC(SDNode *N, DAGCombinerInfo &DCI) const {
}
}
- if (CC == ISD::SETULT && isa<ConstantSDNode>(RHS)) {
- uint64_t RHSVal = cast<ConstantSDNode>(RHS)->getZExtValue();
- if (LHS.getOpcode() == ISD::ADD && isa<ConstantSDNode>(LHS.getOperand(1))) {
- uint64_t Addend = cast<ConstantSDNode>(LHS.getOperand(1))->getZExtValue();
- if (OpVT == MVT::i64) {
- uint64_t ShiftVal = ~Addend + 1;
- uint64_t CmpVal = ~RHSVal + 1;
- if (isPowerOf2_64(ShiftVal) && ShiftVal << 1 == CmpVal) {
- unsigned DestBits = Log2_64(CmpVal);
- if (DestBits == 8 || DestBits == 16 || DestBits == 32) {
- SDValue Conv = DAG.getSExtOrTrunc(
- DAG.getSExtOrTrunc(LHS.getOperand(0), DL,
- MVT::getIntegerVT(DestBits)),
- DL, OpVT);
- return DAG.getSetCC(DL, VT, LHS.getOperand(0), Conv, ISD::SETNE);
- }
- }
- } else if (OpVT == MVT::i32) {
- if (RHSVal == 0xffffff00 && Addend == 0xffffff80) {
- SDValue Conv = DAG.getSExtOrTrunc(
- DAG.getSExtOrTrunc(LHS.getOperand(0), DL, MVT::i8), DL, OpVT);
- return DAG.getSetCC(DL, VT, LHS.getOperand(0), Conv, ISD::SETNE);
- }
+ if (CC == ISD::SETULT) {
+ auto GetTruncExtCmp = [&](SDValue Src, EVT DstVT) {
+ return DAG.getSetCC(
+ DL, VT, Src,
+ DAG.getSExtOrTrunc(DAG.getSExtOrTrunc(Src, DL, DstVT), DL, OpVT),
+ ISD::SETNE);
+ };
+ // ult (add x -0x80000000) -0x100000000 -> ne x (sext:i64 (trunc:i32 x))
+ // ult (add x -0x8000) -0x10000 -> ne x (sext:i64 (trunc:i16 x))
+ // ult (add x -0x80) -0x100 -> ne x (sext:i64 (trunc:i8 x))
+ // ult (add x -0x80) -0x100 -> ne x (sext:i32 (trunc:i16 x))
+ // ult (add x -0x80) -0x100 -> ne x (sext:i16 (trunc:i8 x))
+ if (LHS.getOpcode() == ISD::ADD) {
+ const auto *Addend = dyn_cast<ConstantSDNode>(LHS.getOperand(1));
+ const auto *RhsC = dyn_cast<ConstantSDNode>(RHS);
+ if (Addend && RhsC) {
+ int64_t AddendVal = Addend->getSExtValue();
+ int64_t RhsVal = RhsC->getSExtValue();
+ if (AddendVal == -0x80000000L && RhsVal == -0x100000000L &&
+ OpVT == MVT::i64)
+ return GetTruncExtCmp(LHS.getOperand(0), MVT::i32);
+ if (AddendVal == -0x8000 && RhsVal == -0x10000 && OpVT == MVT::i64)
+ return GetTruncExtCmp(LHS.getOperand(0), MVT::i16);
+ if (AddendVal == -0x80 && RhsVal == -0x100 &&
+ (OpVT == MVT::i64 || OpVT == MVT::i32 || OpVT == MVT::i16))
+ return GetTruncExtCmp(LHS.getOperand(0), MVT::i8);
}
+ // ult (srl (add x -0x8000) 16) 0xffff -> ne x (sext:i32 (trunc:i16 x))
} else if (LHS.getOpcode() == ISD::SRL &&
- LHS.getOperand(0).getOpcode() == ISD::ADD &&
- isa<ConstantSDNode>(LHS.getOperand(1)) &&
- isa<ConstantSDNode>(LHS.getOperand(0).getOperand(1))) {
- if (RHSVal == 0xffff &&
- cast<ConstantSDNode>(LHS.getOperand(1))->getZExtValue() == 16 &&
- cast<ConstantSDNode>(LHS.getOperand(0).getOperand(1))
- ->getZExtValue() == 0xffff8000) {
- SDValue Conv = DAG.getSExtOrTrunc(
- DAG.getSExtOrTrunc(LHS.getOperand(0).getOperand(0), DL, MVT::i16),
- DL, OpVT);
- return DAG.getSetCC(DL, VT, LHS.getOperand(0).getOperand(0), Conv,
- ISD::SETNE);
- }
+ LHS.getOperand(0).getOpcode() == ISD::ADD) {
+ const auto *SrlAmt = dyn_cast<ConstantSDNode>(LHS.getOperand(1));
+ const auto *Addend =
+ dyn_cast<ConstantSDNode>(LHS.getOperand(0).getOperand(1));
+ const auto *RhsC = dyn_cast<ConstantSDNode>(RHS);
+ if (SrlAmt && Addend && RhsC && SrlAmt->getSExtValue() == 16 &&
+ Addend->getSExtValue() == -0x8000 && RhsC->getSExtValue() == 0xffff)
+ return GetTruncExtCmp(LHS.getOperand(0).getOperand(0), MVT::i8);
}
}
diff --git a/llvm/test/CodeGen/PowerPC/setcc-to-sub.ll b/llvm/test/CodeGen/PowerPC/setcc-to-sub.ll
index 1e4d2db2509b25..7e55e4cee605e8 100644
--- a/llvm/test/CodeGen/PowerPC/setcc-to-sub.ll
+++ b/llvm/test/CodeGen/PowerPC/setcc-to-sub.ll
@@ -134,7 +134,7 @@ entry:
define zeroext i1 @test8(i32 %a) {
; CHECK-LABEL: test8:
; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: extsh 4, 3
+; CHECK-NEXT: extsb 4, 3
; CHECK-NEXT: xor 3, 3, 4
; CHECK-NEXT: cntlzw 3, 3
; CHECK-NEXT: srwi 3, 3, 5
@@ -164,12 +164,13 @@ entry:
define zeroext i1 @test10(i16 %a) {
; CHECK-LABEL: test10:
; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: addi 3, 3, -128
-; CHECK-NEXT: lis 4, -1
+; CHECK-NEXT: clrlwi 4, 3, 16
+; CHECK-NEXT: extsb 3, 3
; CHECK-NEXT: clrlwi 3, 3, 16
-; CHECK-NEXT: ori 4, 4, 256
-; CHECK-NEXT: add 3, 3, 4
-; CHECK-NEXT: rldicl 3, 3, 1, 63
+; CHECK-NEXT: xor 3, 4, 3
+; CHECK-NEXT: cntlzw 3, 3
+; CHECK-NEXT: srwi 3, 3, 5
+; CHECK-NEXT: xori 3, 3, 1
; CHECK-NEXT: blr
entry:
%0 = add i16 %a, -128
>From f297069711fbff3d323a6084ff0cb9ff4c4e056c Mon Sep 17 00:00:00 2001
From: Qiu Chaofan <qiucofan at cn.ibm.com>
Date: Wed, 10 Apr 2024 10:43:44 +0800
Subject: [PATCH 3/3] Add signext to cases
---
llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 4 +---
llvm/test/CodeGen/PowerPC/setcc-to-sub.ll | 12 +++++-------
2 files changed, 6 insertions(+), 10 deletions(-)
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index e20a3da79e9309..b13d603efb9479 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -14563,9 +14563,7 @@ SDValue PPCTargetLowering::combineSetCC(SDNode *N, DAGCombinerInfo &DCI) const {
};
// ult (add x -0x80000000) -0x100000000 -> ne x (sext:i64 (trunc:i32 x))
// ult (add x -0x8000) -0x10000 -> ne x (sext:i64 (trunc:i16 x))
- // ult (add x -0x80) -0x100 -> ne x (sext:i64 (trunc:i8 x))
- // ult (add x -0x80) -0x100 -> ne x (sext:i32 (trunc:i16 x))
- // ult (add x -0x80) -0x100 -> ne x (sext:i16 (trunc:i8 x))
+ // ult (add x -0x80) -0x100 -> ne x (sext:i64/i32/i16 (trunc:i8/i16/i8 x))
if (LHS.getOpcode() == ISD::ADD) {
const auto *Addend = dyn_cast<ConstantSDNode>(LHS.getOperand(1));
const auto *RhsC = dyn_cast<ConstantSDNode>(RHS);
diff --git a/llvm/test/CodeGen/PowerPC/setcc-to-sub.ll b/llvm/test/CodeGen/PowerPC/setcc-to-sub.ll
index 7e55e4cee605e8..cb6170ab175e7e 100644
--- a/llvm/test/CodeGen/PowerPC/setcc-to-sub.ll
+++ b/llvm/test/CodeGen/PowerPC/setcc-to-sub.ll
@@ -131,7 +131,7 @@ entry:
ret i1 %cmp
}
-define zeroext i1 @test8(i32 %a) {
+define zeroext i1 @test8(i32 signext %a) {
; CHECK-LABEL: test8:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: extsb 4, 3
@@ -146,7 +146,7 @@ entry:
ret i1 %cmp
}
-define zeroext i1 @test9(i32 %a) {
+define zeroext i1 @test9(i32 signext %a) {
; CHECK-LABEL: test9:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: extsb 4, 3
@@ -161,13 +161,11 @@ entry:
ret i1 %cmp
}
-define zeroext i1 @test10(i16 %a) {
+define zeroext i1 @test10(i16 signext %a) {
; CHECK-LABEL: test10:
; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: clrlwi 4, 3, 16
-; CHECK-NEXT: extsb 3, 3
-; CHECK-NEXT: clrlwi 3, 3, 16
-; CHECK-NEXT: xor 3, 4, 3
+; CHECK-NEXT: extsb 4, 3
+; CHECK-NEXT: xor 3, 3, 4
; CHECK-NEXT: cntlzw 3, 3
; CHECK-NEXT: srwi 3, 3, 5
; CHECK-NEXT: xori 3, 3, 1
More information about the llvm-commits
mailing list