Skip to content

Commit aefd257

Browse files
authored
[DAG][X86] expandABD - add branchless abds/abdu expansion for 0/-1 comparison result cases (#92780)
If the comparison results are allbits masks, we can expand as `abd(lhs, rhs) -> sub(cmpgt(lhs, rhs), xor(sub(lhs, rhs), cmpgt(lhs, rhs)))`, replacing a sub+sub+select pattern with the simpler sub+xor+sub pattern. This allows us to remove a lot of X86 specific legalization code, and will be useful in future generic expansion for the legalization work in #92576 Alive2: https://alive2.llvm.org/ce/z/sj863C
1 parent e37da2c commit aefd257

File tree

8 files changed

+741
-902
lines changed

8 files changed

+741
-902
lines changed

llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9228,11 +9228,21 @@ SDValue TargetLowering::expandABD(SDNode *N, SelectionDAG &DAG) const {
92289228
DAG.getNode(ISD::USUBSAT, dl, VT, LHS, RHS),
92299229
DAG.getNode(ISD::USUBSAT, dl, VT, RHS, LHS));
92309230

9231-
// abds(lhs, rhs) -> select(sgt(lhs,rhs), sub(lhs,rhs), sub(rhs,lhs))
9232-
// abdu(lhs, rhs) -> select(ugt(lhs,rhs), sub(lhs,rhs), sub(rhs,lhs))
92339231
EVT CCVT = getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), VT);
92349232
ISD::CondCode CC = IsSigned ? ISD::CondCode::SETGT : ISD::CondCode::SETUGT;
92359233
SDValue Cmp = DAG.getSetCC(dl, CCVT, LHS, RHS, CC);
9234+
9235+
// Branchless expansion iff cmp result is allbits:
9236+
// abds(lhs, rhs) -> sub(sgt(lhs, rhs), xor(sgt(lhs, rhs), sub(lhs, rhs)))
9237+
// abdu(lhs, rhs) -> sub(ugt(lhs, rhs), xor(ugt(lhs, rhs), sub(lhs, rhs)))
9238+
if (CCVT == VT && getBooleanContents(VT) == ZeroOrNegativeOneBooleanContent) {
9239+
SDValue Diff = DAG.getNode(ISD::SUB, dl, VT, LHS, RHS);
9240+
SDValue Xor = DAG.getNode(ISD::XOR, dl, VT, Diff, Cmp);
9241+
return DAG.getNode(ISD::SUB, dl, VT, Cmp, Xor);
9242+
}
9243+
9244+
// abds(lhs, rhs) -> select(sgt(lhs,rhs), sub(lhs,rhs), sub(rhs,lhs))
9245+
// abdu(lhs, rhs) -> select(ugt(lhs,rhs), sub(lhs,rhs), sub(rhs,lhs))
92369246
return DAG.getSelect(dl, VT, Cmp, DAG.getNode(ISD::SUB, dl, VT, LHS, RHS),
92379247
DAG.getNode(ISD::SUB, dl, VT, RHS, LHS));
92389248
}

llvm/lib/Target/X86/X86ISelLowering.cpp

Lines changed: 5 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1108,13 +1108,6 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
11081108
setOperationAction(ISD::UMIN, VT, VT == MVT::v16i8 ? Legal : Custom);
11091109
}
11101110

1111-
setOperationAction(ISD::ABDU, MVT::v16i8, Custom);
1112-
setOperationAction(ISD::ABDS, MVT::v16i8, Custom);
1113-
setOperationAction(ISD::ABDU, MVT::v8i16, Custom);
1114-
setOperationAction(ISD::ABDS, MVT::v8i16, Custom);
1115-
setOperationAction(ISD::ABDU, MVT::v4i32, Custom);
1116-
setOperationAction(ISD::ABDS, MVT::v4i32, Custom);
1117-
11181111
setOperationAction(ISD::UADDSAT, MVT::v16i8, Legal);
11191112
setOperationAction(ISD::SADDSAT, MVT::v16i8, Legal);
11201113
setOperationAction(ISD::USUBSAT, MVT::v16i8, Legal);
@@ -1132,9 +1125,11 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
11321125
setOperationAction(ISD::INSERT_VECTOR_ELT, MVT::v4f32, Custom);
11331126

11341127
for (auto VT : { MVT::v16i8, MVT::v8i16, MVT::v4i32, MVT::v2i64 }) {
1135-
setOperationAction(ISD::SETCC, VT, Custom);
1136-
setOperationAction(ISD::CTPOP, VT, Custom);
1137-
setOperationAction(ISD::ABS, VT, Custom);
1128+
setOperationAction(ISD::SETCC, VT, Custom);
1129+
setOperationAction(ISD::CTPOP, VT, Custom);
1130+
setOperationAction(ISD::ABS, VT, Custom);
1131+
setOperationAction(ISD::ABDS, VT, Custom);
1132+
setOperationAction(ISD::ABDU, VT, Custom);
11381133

11391134
// The condition codes aren't legal in SSE/AVX and under AVX512 we use
11401135
// setcc all the way to isel and prefer SETGT in some isel patterns.
@@ -1336,11 +1331,6 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
13361331
setOperationAction(ISD::UMIN, MVT::v8i16, Legal);
13371332
setOperationAction(ISD::UMIN, MVT::v4i32, Legal);
13381333

1339-
for (auto VT : {MVT::v16i8, MVT::v8i16, MVT::v4i32, MVT::v2i64}) {
1340-
setOperationAction(ISD::ABDS, VT, Custom);
1341-
setOperationAction(ISD::ABDU, VT, Custom);
1342-
}
1343-
13441334
setOperationAction(ISD::UADDSAT, MVT::v4i32, Custom);
13451335
setOperationAction(ISD::SADDSAT, MVT::v2i64, Custom);
13461336
setOperationAction(ISD::SSUBSAT, MVT::v2i64, Custom);
@@ -28421,18 +28411,6 @@ static SDValue LowerABD(SDValue Op, const X86Subtarget &Subtarget,
2842128411
}
2842228412
}
2842328413

28424-
// TODO: Move to TargetLowering expandABD().
28425-
if (!Subtarget.hasSSE41() &&
28426-
((IsSigned && VT == MVT::v16i8) || VT == MVT::v4i32)) {
28427-
SDValue LHS = DAG.getFreeze(Op.getOperand(0));
28428-
SDValue RHS = DAG.getFreeze(Op.getOperand(1));
28429-
ISD::CondCode CC = IsSigned ? ISD::CondCode::SETGT : ISD::CondCode::SETUGT;
28430-
SDValue Cmp = DAG.getSetCC(dl, VT, LHS, RHS, CC);
28431-
SDValue Diff0 = DAG.getNode(ISD::SUB, dl, VT, LHS, RHS);
28432-
SDValue Diff1 = DAG.getNode(ISD::SUB, dl, VT, RHS, LHS);
28433-
return getBitSelect(dl, VT, Diff0, Diff1, Cmp, DAG);
28434-
}
28435-
2843628414
// Default to expand.
2843728415
return SDValue();
2843828416
}

0 commit comments

Comments
 (0)