Skip to content

Commit

Permalink
[X86] combineCarryThroughADD - recognise X86ISD::ADD(AND(X,1),-1) pat…
Browse files Browse the repository at this point in the history
…tern can be folded to X86ISD::BT

As mentioned on D122482, if we've generated a masked overflow test see if we can fold it to X86ISD::BT to feed a X86ISD::ADC/SBB

Differential Revision: https://reviews.llvm.org/D122572
  • Loading branch information
RKSimon committed Mar 31, 2022
1 parent 2f1261a commit 481b185
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 13 deletions.
20 changes: 19 additions & 1 deletion llvm/lib/Target/X86/X86ISelLowering.cpp
Expand Up @@ -44714,12 +44714,15 @@ static bool checkBoolTestAndOrSetCCCombine(SDValue Cond, X86::CondCode &CC0,
static SDValue combineCarryThroughADD(SDValue EFLAGS, SelectionDAG &DAG) {
if (EFLAGS.getOpcode() == X86ISD::ADD) {
if (isAllOnesConstant(EFLAGS.getOperand(1))) {
bool FoundAndLSB = false;
SDValue Carry = EFLAGS.getOperand(0);
while (Carry.getOpcode() == ISD::TRUNCATE ||
Carry.getOpcode() == ISD::ZERO_EXTEND ||
(Carry.getOpcode() == ISD::AND &&
isOneConstant(Carry.getOperand(1))))
isOneConstant(Carry.getOperand(1)))) {
FoundAndLSB |= Carry.getOpcode() == ISD::AND;
Carry = Carry.getOperand(0);
}
if (Carry.getOpcode() == X86ISD::SETCC ||
Carry.getOpcode() == X86ISD::SETCC_CARRY) {
// TODO: Merge this code with equivalent in combineAddOrSubToADCOrSBB?
Expand Down Expand Up @@ -44750,6 +44753,21 @@ static SDValue combineCarryThroughADD(SDValue EFLAGS, SelectionDAG &DAG) {
CarryOp1.getOpcode() == X86ISD::ADD &&
isOneConstant(CarryOp1.getOperand(1)))
return CarryOp1;
} else if (FoundAndLSB) {
SDLoc DL(Carry);
SDValue BitNo = DAG.getConstant(0, DL, Carry.getValueType());
if (Carry.getOpcode() == ISD::SRL) {
BitNo = Carry.getOperand(1);
Carry = Carry.getOperand(0);
}
if (Carry.getScalarValueSizeInBits() < 32)
Carry = DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i32, Carry);
EVT CarryVT = Carry.getValueType();
if (DAG.getTargetLoweringInfo().isTypeLegal(CarryVT)) {
if (CarryVT != BitNo.getValueType())
BitNo = DAG.getNode(ISD::ANY_EXTEND, DL, CarryVT, BitNo);
return DAG.getNode(X86ISD::BT, DL, MVT::i32, Carry, BitNo);
}
}
}
}
Expand Down
3 changes: 1 addition & 2 deletions llvm/test/CodeGen/X86/addcarry.ll
Expand Up @@ -640,8 +640,7 @@ define { i64, i1 } @addcarry_fake_carry(i64 %a, i64 %b, i1 %carryin) {
; CHECK-LABEL: addcarry_fake_carry:
; CHECK: # %bb.0:
; CHECK-NEXT: movq %rdi, %rax
; CHECK-NEXT: andb $1, %dl
; CHECK-NEXT: addb $-1, %dl
; CHECK-NEXT: btl $0, %edx
; CHECK-NEXT: adcq %rsi, %rax
; CHECK-NEXT: setb %dl
; CHECK-NEXT: retq
Expand Down
10 changes: 2 additions & 8 deletions llvm/test/CodeGen/X86/combine-adc.ll
Expand Up @@ -67,24 +67,18 @@ define i32 @PR40483_add2(i32*, i32) nounwind {
ret i32 %10
}

; FIXME: Fail to convert add+lshr+and to BT
define i32 @adc_merge_constants(i32 %a0) nounwind {
; X86-LABEL: adc_merge_constants:
; X86: # %bb.0:
; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
; X86-NEXT: shrl $11, %ecx
; X86-NEXT: andb $1, %cl
; X86-NEXT: xorl %eax, %eax
; X86-NEXT: addb $-1, %cl
; X86-NEXT: btl $11, {{[0-9]+}}(%esp)
; X86-NEXT: adcl $54, %eax
; X86-NEXT: retl
;
; X64-LABEL: adc_merge_constants:
; X64: # %bb.0:
; X64-NEXT: shrl $11, %edi
; X64-NEXT: andb $1, %dil
; X64-NEXT: xorl %eax, %eax
; X64-NEXT: addb $-1, %dil
; X64-NEXT: btl $11, %edi
; X64-NEXT: adcl $54, %eax
; X64-NEXT: retq
%bit = lshr i32 %a0, 11
Expand Down
3 changes: 1 addition & 2 deletions llvm/test/CodeGen/X86/subcarry.ll
Expand Up @@ -349,8 +349,7 @@ define { i64, i1 } @subcarry_fake_carry(i64 %a, i64 %b, i1 %carryin) {
; CHECK-LABEL: subcarry_fake_carry:
; CHECK: # %bb.0:
; CHECK-NEXT: movq %rdi, %rax
; CHECK-NEXT: andb $1, %dl
; CHECK-NEXT: addb $-1, %dl
; CHECK-NEXT: btl $0, %edx
; CHECK-NEXT: sbbq %rsi, %rax
; CHECK-NEXT: setb %dl
; CHECK-NEXT: retq
Expand Down

0 comments on commit 481b185

Please sign in to comment.