Skip to content

Commit 656d66f

Browse files
committed
[X86] Use custom isel for (X86sbb_flag 0, 0) so we can use 32-bit SBB for i8/i16.
We were using MOV32r0 and an extract_subreg as an input. By using custom isel we can move the extract_subreg to after the SBB instead of on the input.
1 parent e1cbfec commit 656d66f

File tree

3 files changed

+54
-21
lines changed

3 files changed

+54
-21
lines changed

llvm/lib/Target/X86/X86ISelDAGToDAG.cpp

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5343,12 +5343,11 @@ void X86DAGToDAGISel::Select(SDNode *Node) {
53435343
// We have to do this manually because tblgen will put the eflags copy in
53445344
// the wrong place if we use an extract_subreg in the pattern.
53455345
MVT VT = Node->getSimpleValueType(0);
5346-
SDValue Chain = CurDAG->getEntryNode();
53475346

53485347
// Copy flags to the EFLAGS register and glue it to next node.
5349-
SDValue EFLAGS = CurDAG->getCopyToReg(Chain, dl, X86::EFLAGS,
5350-
Node->getOperand(1), SDValue());
5351-
Chain = EFLAGS;
5348+
SDValue EFLAGS =
5349+
CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, X86::EFLAGS,
5350+
Node->getOperand(1), SDValue());
53525351

53535352
// Create a 64-bit instruction if the result is 64-bits otherwise use the
53545353
// 32-bit version.
@@ -5367,6 +5366,56 @@ void X86DAGToDAGISel::Select(SDNode *Node) {
53675366
CurDAG->RemoveDeadNode(Node);
53685367
return;
53695368
}
5369+
case X86ISD::SBB: {
5370+
if (isNullConstant(Node->getOperand(0)) &&
5371+
isNullConstant(Node->getOperand(1))) {
5372+
MVT VT = Node->getSimpleValueType(0);
5373+
5374+
// Create zero.
5375+
SDVTList VTs = CurDAG->getVTList(MVT::i32, MVT::i32);
5376+
SDValue Zero =
5377+
SDValue(CurDAG->getMachineNode(X86::MOV32r0, dl, VTs, None), 0);
5378+
if (VT == MVT::i64) {
5379+
Zero = SDValue(
5380+
CurDAG->getMachineNode(
5381+
TargetOpcode::SUBREG_TO_REG, dl, MVT::i64,
5382+
CurDAG->getTargetConstant(0, dl, MVT::i64), Zero,
5383+
CurDAG->getTargetConstant(X86::sub_32bit, dl, MVT::i32)),
5384+
0);
5385+
}
5386+
5387+
// Copy flags to the EFLAGS register and glue it to next node.
5388+
SDValue EFLAGS =
5389+
CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, X86::EFLAGS,
5390+
Node->getOperand(2), SDValue());
5391+
5392+
// Create a 64-bit instruction if the result is 64-bits otherwise use the
5393+
// 32-bit version.
5394+
unsigned Opc = VT == MVT::i64 ? X86::SBB64rr : X86::SBB32rr;
5395+
MVT SBBVT = VT == MVT::i64 ? MVT::i64 : MVT::i32;
5396+
VTs = CurDAG->getVTList(SBBVT, MVT::i32);
5397+
SDValue Result =
5398+
SDValue(CurDAG->getMachineNode(Opc, dl, VTs, {Zero, Zero, EFLAGS,
5399+
EFLAGS.getValue(1)}),
5400+
0);
5401+
5402+
// Replace the flag use.
5403+
ReplaceUses(SDValue(Node, 1), Result.getValue(1));
5404+
5405+
// Replace the result use.
5406+
if (!SDValue(Node, 0).use_empty()) {
5407+
// For less than 32-bits we need to extract from the 32-bit node.
5408+
if (VT == MVT::i8 || VT == MVT::i16) {
5409+
int SubIndex = VT == MVT::i16 ? X86::sub_16bit : X86::sub_8bit;
5410+
Result = CurDAG->getTargetExtractSubreg(SubIndex, dl, VT, Result);
5411+
}
5412+
ReplaceUses(SDValue(Node, 0), Result);
5413+
}
5414+
5415+
CurDAG->RemoveDeadNode(Node);
5416+
return;
5417+
}
5418+
}
53705419
}
53715420

53725421
SelectCode(Node);

llvm/lib/Target/X86/X86InstrCompiler.td

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -334,22 +334,6 @@ def SETB_C32r : I<0, Pseudo, (outs GR32:$dst), (ins), "", []>;
334334
def SETB_C64r : I<0, Pseudo, (outs GR64:$dst), (ins), "", []>;
335335
} // isCodeGenOnly
336336

337-
338-
// Patterns to give priority when both inputs are zero so that we don't use
339-
// an immediate for the RHS.
340-
// TODO: Should we use a 32-bit sbb for 8/16 to push the extract_subreg out?
341-
def : Pat<(X86sbb_flag (i8 0), (i8 0), EFLAGS),
342-
(SBB8rr (EXTRACT_SUBREG (MOV32r0), sub_8bit),
343-
(EXTRACT_SUBREG (MOV32r0), sub_8bit))>;
344-
def : Pat<(X86sbb_flag (i16 0), (i16 0), EFLAGS),
345-
(SBB16rr (EXTRACT_SUBREG (MOV32r0), sub_16bit),
346-
(EXTRACT_SUBREG (MOV32r0), sub_16bit))>;
347-
def : Pat<(X86sbb_flag (i32 0), (i32 0), EFLAGS),
348-
(SBB32rr (MOV32r0), (MOV32r0))>;
349-
def : Pat<(X86sbb_flag (i64 0), (i64 0), EFLAGS),
350-
(SBB64rr (SUBREG_TO_REG (i64 0), (MOV32r0), sub_32bit),
351-
(SUBREG_TO_REG (i64 0), (MOV32r0), sub_32bit))>;
352-
353337
//===----------------------------------------------------------------------===//
354338
// String Pseudo Instructions
355339
//

llvm/test/CodeGen/X86/shl-crash-on-legalize.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ define i32 @PR29058(i8 %x, i32 %y) {
1717
; CHECK-NEXT: cmovnel %esi, %eax
1818
; CHECK-NEXT: xorl %edx, %edx
1919
; CHECK-NEXT: cmpb $1, %dil
20-
; CHECK-NEXT: sbbb %dl, %dl
20+
; CHECK-NEXT: sbbl %edx, %edx
2121
; CHECK-NEXT: orb %dl, %cl
2222
; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx
2323
; CHECK-NEXT: shll %cl, %eax

0 commit comments

Comments
 (0)