[llvm] [AMDGPU][SDAG] Support source modifiers as integer on select (PR #147325)

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 8 05:20:56 PDT 2025


================
@@ -4830,6 +4830,62 @@ AMDGPUTargetLowering::foldFreeOpFromSelect(TargetLowering::DAGCombinerInfo &DCI,
   return SDValue();
 }
 
+static EVT getFloatVT(EVT VT) {
+  return VT.isVector() ? MVT::getVectorVT(
+                             MVT::getFloatingPointVT(VT.getScalarSizeInBits()),
+                             VT.getVectorNumElements())
+                       : MVT::getFloatingPointVT(VT.getFixedSizeInBits());
+}
+
+static SDValue getBitwiseToSrcModifierOp(SDValue N,
+                                         TargetLowering::DAGCombinerInfo &DCI) {
+
+  unsigned Opc = N.getNode()->getOpcode();
+  if (Opc != ISD::AND && Opc != ISD::XOR && Opc != ISD::AND)
+    return SDValue();
+
+  SelectionDAG &DAG = DCI.DAG;
+  SDValue LHS = N->getOperand(0);
+  SDValue RHS = N->getOperand(1);
+  ConstantSDNode *CRHS = isConstOrConstSplat(RHS);
+
+  if (!CRHS)
+    return SDValue();
+
+  EVT VT = RHS.getValueType();
+
+  assert((VT == MVT::i32 || VT == MVT::v2i32 || VT == MVT::i64) &&
+         "Expected i32, v2i32 or i64 value type.");
+
+  uint64_t Mask = CRHS->getZExtValue();
+  EVT FVT = getFloatVT(VT);
+  SDLoc SL = SDLoc(N);
+  SDValue BC = DAG.getNode(ISD::BITCAST, SL, FVT, LHS);
+
+  switch (Opc) {
+  case ISD::XOR:
+    if ((Mask == 0x80000000u && VT.getFixedSizeInBits() == 32) ||
+        (Mask == 0x8000000000000000u && VT.getFixedSizeInBits() == 64))
+      return DAG.getNode(ISD::FNEG, SL, FVT, BC);
+    break;
+  case ISD::OR:
+    if ((Mask == 0x80000000u && VT.getFixedSizeInBits() == 32) ||
+        (Mask == 0x8000000000000000u && VT.getFixedSizeInBits() == 64)) {
+      SDValue Abs = DAG.getNode(ISD::FABS, SL, FVT, BC);
+      return DAG.getNode(ISD::FNEG, SL, FVT, Abs);
+    }
+    break;
+  case ISD::AND:
+    if ((Mask == 0x7fffffffu && VT.getFixedSizeInBits() == 32) ||
+        (Mask == 0x7fffffffffffffffu && VT.getFixedSizeInBits() == 64))
+      return DAG.getNode(ISD::FABS, SL, FVT, BC);
+    break;
----------------
arsenm wrote:

The 64-bit case is really a 32-bit operation on the high bits, with passthrough of the low bits

https://github.com/llvm/llvm-project/pull/147325


More information about the llvm-commits mailing list