Skip to content

Commit

Permalink
[x86] make helper function to create sbb with zero operands; NFC
Browse files Browse the repository at this point in the history
As noted in D116804, we want to effectively invert that patch
for CPUs (intel) that don't break the false dependency on
sbb %eax, %eax

So we will likely want to create that here in the
X86DAGToDAGISel::Select() case for X86::SETCC_CARRY.
  • Loading branch information
rotateright committed Feb 2, 2022
1 parent 8680d6d commit f523e83
Showing 1 changed file with 34 additions and 29 deletions.
63 changes: 34 additions & 29 deletions llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,38 @@ namespace {
return getI8Imm(InsertIdx ? 0x02 : 0x30, DL);
}

SDValue getSBBZero(SDNode *N) {
SDLoc dl(N);
MVT VT = N->getSimpleValueType(0);

// Create zero.
SDVTList VTs = CurDAG->getVTList(MVT::i32, MVT::i32);
SDValue Zero =
SDValue(CurDAG->getMachineNode(X86::MOV32r0, dl, VTs, None), 0);
if (VT == MVT::i64) {
Zero = SDValue(
CurDAG->getMachineNode(
TargetOpcode::SUBREG_TO_REG, dl, MVT::i64,
CurDAG->getTargetConstant(0, dl, MVT::i64), Zero,
CurDAG->getTargetConstant(X86::sub_32bit, dl, MVT::i32)),
0);
}

// Copy flags to the EFLAGS register and glue it to next node.
SDValue EFLAGS = CurDAG->getCopyToReg(
CurDAG->getEntryNode(), dl, X86::EFLAGS, N->getOperand(2), SDValue());

// Create a 64-bit instruction if the result is 64-bits otherwise use the
// 32-bit version.
unsigned Opc = VT == MVT::i64 ? X86::SBB64rr : X86::SBB32rr;
MVT SBBVT = VT == MVT::i64 ? MVT::i64 : MVT::i32;
VTs = CurDAG->getVTList(SBBVT, MVT::i32);
return SDValue(
CurDAG->getMachineNode(Opc, dl, VTs,
{Zero, Zero, EFLAGS, EFLAGS.getValue(1)}),
0);
}

// Helper to detect unneeded and instructions on shift amounts. Called
// from PatFrags in tablegen.
bool isUnneededShiftMask(SDNode *N, unsigned Width) const {
Expand Down Expand Up @@ -5798,42 +5830,15 @@ void X86DAGToDAGISel::Select(SDNode *Node) {
case X86ISD::SBB: {
if (isNullConstant(Node->getOperand(0)) &&
isNullConstant(Node->getOperand(1))) {
MVT VT = Node->getSimpleValueType(0);

// Create zero.
SDVTList VTs = CurDAG->getVTList(MVT::i32, MVT::i32);
SDValue Zero =
SDValue(CurDAG->getMachineNode(X86::MOV32r0, dl, VTs, None), 0);
if (VT == MVT::i64) {
Zero = SDValue(
CurDAG->getMachineNode(
TargetOpcode::SUBREG_TO_REG, dl, MVT::i64,
CurDAG->getTargetConstant(0, dl, MVT::i64), Zero,
CurDAG->getTargetConstant(X86::sub_32bit, dl, MVT::i32)),
0);
}

// Copy flags to the EFLAGS register and glue it to next node.
SDValue EFLAGS =
CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, X86::EFLAGS,
Node->getOperand(2), SDValue());

// Create a 64-bit instruction if the result is 64-bits otherwise use the
// 32-bit version.
unsigned Opc = VT == MVT::i64 ? X86::SBB64rr : X86::SBB32rr;
MVT SBBVT = VT == MVT::i64 ? MVT::i64 : MVT::i32;
VTs = CurDAG->getVTList(SBBVT, MVT::i32);
SDValue Result =
SDValue(CurDAG->getMachineNode(Opc, dl, VTs, {Zero, Zero, EFLAGS,
EFLAGS.getValue(1)}),
0);
SDValue Result = getSBBZero(Node);

// Replace the flag use.
ReplaceUses(SDValue(Node, 1), Result.getValue(1));

// Replace the result use.
if (!SDValue(Node, 0).use_empty()) {
// For less than 32-bits we need to extract from the 32-bit node.
MVT VT = Node->getSimpleValueType(0);
if (VT == MVT::i8 || VT == MVT::i16) {
int SubIndex = VT == MVT::i16 ? X86::sub_16bit : X86::sub_8bit;
Result = CurDAG->getTargetExtractSubreg(SubIndex, dl, VT, Result);
Expand Down

0 comments on commit f523e83

Please sign in to comment.