[PATCH] D144449: [X86] Improve select of constants
Kazu Hirata via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Mon Feb 20 23:14:04 PST 2023
kazu created this revision.
Herald added subscribers: pengfei, hiraditya.
Herald added a project: All.
kazu requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.
Without this patch:
%cmp = icmp eq i32 %a, %b
%cond = select i1 %cmp, i32 1, i32 2
is compiled as:
31 c9 xor %ecx,%ecx
39 f7 cmp %esi,%edi
0f 94 c1 sete %cl
b8 02 00 00 00 mov $0x2,%eax
29 c8 sub %ecx,%eax
With this patch, the compiler generates:
31 c0 xor %eax,%eax
39 f7 cmp %esi,%edi
0f 95 c0 setne %al
ff c0 inc %eax
saving 5 bytes while reducing register usage.
This patch transforms C - setcc into inverted_setcc + (C-1) if C is a
nonzero constant.
This patch fixes:
https://github.com/llvm/llvm-project/issues/60854
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D144449
Files:
llvm/lib/Target/X86/X86ISelLowering.cpp
llvm/test/CodeGen/X86/select-constant-xor.ll
llvm/test/CodeGen/X86/select_const.ll
Index: llvm/test/CodeGen/X86/select_const.ll
===================================================================
--- llvm/test/CodeGen/X86/select_const.ll
+++ llvm/test/CodeGen/X86/select_const.ll
@@ -584,11 +584,10 @@
define i32 @select_eq_1_2(i32 %a, i32 %b) {
; CHECK-LABEL: select_eq_1_2:
; CHECK: # %bb.0:
-; CHECK-NEXT: xorl %ecx, %ecx
+; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: cmpl %esi, %edi
-; CHECK-NEXT: sete %cl
-; CHECK-NEXT: movl $2, %eax
-; CHECK-NEXT: subl %ecx, %eax
+; CHECK-NEXT: setne %al
+; CHECK-NEXT: incl %eax
; CHECK-NEXT: retq
%cmp = icmp eq i32 %a, %b
Index: llvm/test/CodeGen/X86/select-constant-xor.ll
===================================================================
--- llvm/test/CodeGen/X86/select-constant-xor.ll
+++ llvm/test/CodeGen/X86/select-constant-xor.ll
@@ -30,11 +30,10 @@
define i32 @selecti64i32(i64 %a) {
; CHECK-LABEL: selecti64i32:
; CHECK: # %bb.0:
-; CHECK-NEXT: xorl %ecx, %ecx
+; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: testq %rdi, %rdi
-; CHECK-NEXT: setns %cl
-; CHECK-NEXT: movl $-2147483648, %eax # imm = 0x80000000
-; CHECK-NEXT: subl %ecx, %eax
+; CHECK-NEXT: sets %al
+; CHECK-NEXT: addl $2147483647, %eax # imm = 0x7FFFFFFF
; CHECK-NEXT: retq
%c = icmp sgt i64 %a, -1
%s = select i1 %c, i32 2147483647, i32 -2147483648
Index: llvm/lib/Target/X86/X86ISelLowering.cpp
===================================================================
--- llvm/lib/Target/X86/X86ISelLowering.cpp
+++ llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -55480,6 +55480,33 @@
return DAG.getNode(ISD::ADD, DL, VT, N0, Cmov);
}
+static SDValue combineSubSetcc(SDNode *N, SelectionDAG &DAG) {
+ SDValue Op0 = N->getOperand(0);
+ SDValue Op1 = N->getOperand(1);
+
+ // (sub C (zero_extend (setcc)))
+ // =>
+ // (add (zero_extend (setcc inverted) C-1)) if C is a nonzero immediate
+ // Don't disturb (sub 0 setcc), which is easily done with neg.
+ EVT VT = N->getValueType(0);
+ auto *Op0C = dyn_cast<ConstantSDNode>(Op0);
+ if (Op1.getOpcode() == ISD::ZERO_EXTEND && Op1.hasOneUse() && Op0C &&
+ !Op0C->isZero() && Op1.getOperand(0).getOpcode() == X86ISD::SETCC &&
+ Op1.getOperand(0).hasOneUse()) {
+ SDValue SetCC = Op1.getOperand(0);
+ X86::CondCode CC = (X86::CondCode)SetCC.getConstantOperandVal(0);
+ X86::CondCode NewCC = X86::GetOppositeBranchCondition(CC);
+ uint64_t NewImm = Op0C->getZExtValue() - 1;
+ SDLoc DL(Op1);
+ SDValue NewSetCC = getSETCC(NewCC, SetCC.getOperand(1), DL, DAG);
+ NewSetCC = DAG.getNode(ISD::ZERO_EXTEND, DL, VT, NewSetCC);
+ return DAG.getNode(X86ISD::ADD, DL, DAG.getVTList(VT, VT), NewSetCC,
+ DAG.getConstant(NewImm, DL, VT));
+ }
+
+ return SDValue();
+}
+
static SDValue combineSub(SDNode *N, SelectionDAG &DAG,
TargetLowering::DAGCombinerInfo &DCI,
const X86Subtarget &Subtarget) {
@@ -55540,7 +55567,10 @@
if (SDValue V = combineXorSubCTLZ(N, DAG, Subtarget))
return V;
- return combineAddOrSubToADCOrSBB(N, DAG);
+ if (SDValue V = combineAddOrSubToADCOrSBB(N, DAG))
+ return V;
+
+ return combineSubSetcc(N, DAG);
}
static SDValue combineVectorCompare(SDNode *N, SelectionDAG &DAG,
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D144449.499044.patch
Type: text/x-patch
Size: 3297 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230221/d655b53f/attachment.bin>
More information about the llvm-commits
mailing list