Skip to content

Commit d1d7fc9

Browse files
committed
[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
1 parent ce5379f commit d1d7fc9

File tree

2 files changed

+37
-3
lines changed

2 files changed

+37
-3
lines changed

llvm/lib/Target/X86/X86ISelLowering.cpp

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40939,8 +40939,7 @@ static SDValue combineSelect(SDNode *N, SelectionDAG &DAG,
4093940939
// (x > 0) ? x : 0 -> (x >= 0) ? x : 0
4094040940
// (x < -1) ? x : -1 -> (x <= -1) ? x : -1
4094140941
// This allows use of COND_S / COND_NS (see TranslateX86CC) which eliminates
40942-
// the need for an extra compare
40943-
// against zero. e.g.
40942+
// the need for an extra compare against zero. e.g.
4094440943
// (a - b) > 0 : (a - b) ? 0 -> (a - b) >= 0 : (a - b) ? 0
4094540944
// subl %esi, %edi
4094640945
// testl %edi, %edi
@@ -40950,17 +40949,28 @@ static SDValue combineSelect(SDNode *N, SelectionDAG &DAG,
4095040949
// xorl %eax, %eax
4095140950
// subl %esi, $edi
4095240951
// cmovsl %eax, %edi
40952+
//
40953+
// We can also canonicalize
40954+
// (x s> 1) ? x : 1 -> (x s>= 1) ? x : 1 -> (x s> 0) ? x : 1
40955+
// (x u> 1) ? x : 1 -> (x u>= 1) ? x : 1 -> (x != 0) ? x : 1
40956+
// This allows the use of a test instruction for the compare.
4095340957
if (N->getOpcode() == ISD::SELECT && Cond.getOpcode() == ISD::SETCC &&
4095440958
Cond.hasOneUse() &&
4095540959
LHS == Cond.getOperand(0) && RHS == Cond.getOperand(1)) {
4095640960
ISD::CondCode CC = cast<CondCodeSDNode>(Cond.getOperand(2))->get();
40957-
if ((CC == ISD::SETGT && isNullConstant(RHS)) ||
40961+
if ((CC == ISD::SETGT && (isNullConstant(RHS) || isOneConstant(RHS))) ||
4095840962
(CC == ISD::SETLT && isAllOnesConstant(RHS))) {
4095940963
ISD::CondCode NewCC = CC == ISD::SETGT ? ISD::SETGE : ISD::SETLE;
4096040964
Cond = DAG.getSetCC(SDLoc(Cond), Cond.getValueType(),
4096140965
Cond.getOperand(0), Cond.getOperand(1), NewCC);
4096240966
return DAG.getSelect(DL, VT, Cond, LHS, RHS);
4096340967
}
40968+
if (CC == ISD::SETUGT && isOneConstant(RHS)) {
40969+
ISD::CondCode NewCC = ISD::SETUGE;
40970+
Cond = DAG.getSetCC(SDLoc(Cond), Cond.getValueType(),
40971+
Cond.getOperand(0), Cond.getOperand(1), NewCC);
40972+
return DAG.getSelect(DL, VT, Cond, LHS, RHS);
40973+
}
4096440974
}
4096540975

4096640976
// Match VSELECTs into subs with unsigned saturation.

llvm/test/CodeGen/X86/cmov.ll

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,3 +235,27 @@ define i32 @pr47049_2(i32 %0) {
235235
%3 = select i1 %2, i32 %0, i32 -1
236236
ret i32 %3
237237
}
238+
239+
define i32 @pr47049_3(i32 %0) {
240+
; CHECK-LABEL: pr47049_3:
241+
; CHECK: # %bb.0:
242+
; CHECK-NEXT: testl %edi, %edi
243+
; CHECK-NEXT: movl $1, %eax
244+
; CHECK-NEXT: cmovgl %edi, %eax
245+
; CHECK-NEXT: retq
246+
%2 = icmp sgt i32 %0, 1
247+
%3 = select i1 %2, i32 %0, i32 1
248+
ret i32 %3
249+
}
250+
251+
define i32 @pr47049_4(i32 %0) {
252+
; CHECK-LABEL: pr47049_4:
253+
; CHECK: # %bb.0:
254+
; CHECK-NEXT: testl %edi, %edi
255+
; CHECK-NEXT: movl $1, %eax
256+
; CHECK-NEXT: cmovnel %edi, %eax
257+
; CHECK-NEXT: retq
258+
%2 = icmp ugt i32 %0, 1
259+
%3 = select i1 %2, i32 %0, i32 1
260+
ret i32 %3
261+
}

0 commit comments

Comments
 (0)