[llvm] [X86] Select i8 ANDN via i32 promotion (PR #205050)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 15 04:58:10 PDT 2026
================
@@ -51954,6 +51954,52 @@ static SDValue combineAndNotIntoANDNP(SDNode *N, const SDLoc &DL,
return DAG.getNode(X86ISD::ANDNP, DL, VT, X, Y);
}
+static SDValue combineI8AndNotIntoI32AndNot(SDNode *N, const SDLoc &DL,
+ SelectionDAG &DAG,
+ const X86Subtarget &Subtarget) {
+ assert(N->getOpcode() == ISD::AND && "Unexpected opcode combine into ANDN");
+
+ if (!Subtarget.hasBMI() || N->getValueType(0) != MVT::i8)
+ return SDValue();
+
+ // Keep compare and mask-lowering idioms in their existing byte forms.
+ for (SDUse &Use : N->uses()) {
+ if (Use.getResNo() != 0)
+ continue;
+ SDNode *User = Use.getUser();
+ if (User->getOpcode() == ISD::SETCC)
+ return SDValue();
+ if (User->getOpcode() == ISD::BITCAST) {
+ EVT UseVT = User->getValueType(0);
+ if (UseVT.isVector() && UseVT.getScalarType() == MVT::i1)
+ return SDValue();
+ }
+ }
+
+ SDValue X, Y;
+ SDValue N0 = N->getOperand(0);
+ SDValue N1 = N->getOperand(1);
+ if (SDValue Not = IsNOT(N0, DAG)) {
+ X = Not;
+ Y = N1;
+ } else if (SDValue Not = IsNOT(N1, DAG)) {
+ X = Not;
+ Y = N0;
+ } else
+ return SDValue();
+
+ if (X.getValueType() != MVT::i8 || Y.getValueType() != MVT::i8)
+ return SDValue();
----------------
mygitljf wrote:
`Y` cannot differ because it remains a direct operand of the i8 `ISD::AND`.`X` can differ because `IsNOT()` peeks through bitcasts and may expose the underlying value, for example `v8i1`. I'll remove the redundant `Y` check but retain the `X` check.
https://github.com/llvm/llvm-project/pull/205050
More information about the llvm-commits
mailing list