[llvm] d1d7fc9 - [X86] Canonicalize (x > 1) ? x : 1 -> (x >= 1) ? x : 1 for sign and unsigned to enable the use of test instructions for the compare.
Craig Topper via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 30 13:52:15 PDT 2020
Author: Craig Topper
Date: 2020-09-30T13:50:52-07:00
New Revision: d1d7fc98325d948bede85e6304c5ca93f79e050e
URL: https://github.com/llvm/llvm-project/commit/d1d7fc98325d948bede85e6304c5ca93f79e050e
DIFF: https://github.com/llvm/llvm-project/commit/d1d7fc98325d948bede85e6304c5ca93f79e050e.diff
LOG: [X86] Canonicalize (x > 1) ? x : 1 -> (x >= 1) ? x : 1 for sign and unsigned to enable the use of test instructions for the compare.
This will be further canonicalized to a compare involving 0
which will enable the use of test instructions. Either using
cmovg for signed for cmovne for unsigned.
Fixes more case for PR47049
Added:
Modified:
llvm/lib/Target/X86/X86ISelLowering.cpp
llvm/test/CodeGen/X86/cmov.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index d0fd1046fdeb..8306e3a23f47 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -40939,8 +40939,7 @@ static SDValue combineSelect(SDNode *N, SelectionDAG &DAG,
// (x > 0) ? x : 0 -> (x >= 0) ? x : 0
// (x < -1) ? x : -1 -> (x <= -1) ? x : -1
// This allows use of COND_S / COND_NS (see TranslateX86CC) which eliminates
- // the need for an extra compare
- // against zero. e.g.
+ // the need for an extra compare against zero. e.g.
// (a - b) > 0 : (a - b) ? 0 -> (a - b) >= 0 : (a - b) ? 0
// subl %esi, %edi
// testl %edi, %edi
@@ -40950,17 +40949,28 @@ static SDValue combineSelect(SDNode *N, SelectionDAG &DAG,
// xorl %eax, %eax
// subl %esi, $edi
// cmovsl %eax, %edi
+ //
+ // We can also canonicalize
+ // (x s> 1) ? x : 1 -> (x s>= 1) ? x : 1 -> (x s> 0) ? x : 1
+ // (x u> 1) ? x : 1 -> (x u>= 1) ? x : 1 -> (x != 0) ? x : 1
+ // This allows the use of a test instruction for the compare.
if (N->getOpcode() == ISD::SELECT && Cond.getOpcode() == ISD::SETCC &&
Cond.hasOneUse() &&
LHS == Cond.getOperand(0) && RHS == Cond.getOperand(1)) {
ISD::CondCode CC = cast<CondCodeSDNode>(Cond.getOperand(2))->get();
- if ((CC == ISD::SETGT && isNullConstant(RHS)) ||
+ if ((CC == ISD::SETGT && (isNullConstant(RHS) || isOneConstant(RHS))) ||
(CC == ISD::SETLT && isAllOnesConstant(RHS))) {
ISD::CondCode NewCC = CC == ISD::SETGT ? ISD::SETGE : ISD::SETLE;
Cond = DAG.getSetCC(SDLoc(Cond), Cond.getValueType(),
Cond.getOperand(0), Cond.getOperand(1), NewCC);
return DAG.getSelect(DL, VT, Cond, LHS, RHS);
}
+ if (CC == ISD::SETUGT && isOneConstant(RHS)) {
+ ISD::CondCode NewCC = ISD::SETUGE;
+ Cond = DAG.getSetCC(SDLoc(Cond), Cond.getValueType(),
+ Cond.getOperand(0), Cond.getOperand(1), NewCC);
+ return DAG.getSelect(DL, VT, Cond, LHS, RHS);
+ }
}
// Match VSELECTs into subs with unsigned saturation.
diff --git a/llvm/test/CodeGen/X86/cmov.ll b/llvm/test/CodeGen/X86/cmov.ll
index 41ebc322b430..b77d3c8e10e0 100644
--- a/llvm/test/CodeGen/X86/cmov.ll
+++ b/llvm/test/CodeGen/X86/cmov.ll
@@ -235,3 +235,27 @@ define i32 @pr47049_2(i32 %0) {
%3 = select i1 %2, i32 %0, i32 -1
ret i32 %3
}
+
+define i32 @pr47049_3(i32 %0) {
+; CHECK-LABEL: pr47049_3:
+; CHECK: # %bb.0:
+; CHECK-NEXT: testl %edi, %edi
+; CHECK-NEXT: movl $1, %eax
+; CHECK-NEXT: cmovgl %edi, %eax
+; CHECK-NEXT: retq
+ %2 = icmp sgt i32 %0, 1
+ %3 = select i1 %2, i32 %0, i32 1
+ ret i32 %3
+}
+
+define i32 @pr47049_4(i32 %0) {
+; CHECK-LABEL: pr47049_4:
+; CHECK: # %bb.0:
+; CHECK-NEXT: testl %edi, %edi
+; CHECK-NEXT: movl $1, %eax
+; CHECK-NEXT: cmovnel %edi, %eax
+; CHECK-NEXT: retq
+ %2 = icmp ugt i32 %0, 1
+ %3 = select i1 %2, i32 %0, i32 1
+ ret i32 %3
+}
More information about the llvm-commits
mailing list