[llvm] [AMDGPU][SDAG] Support source modifiers as integer on select (PR #147325)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Jul 7 11:52:02 PDT 2025
================
@@ -4830,6 +4830,59 @@ AMDGPUTargetLowering::foldFreeOpFromSelect(TargetLowering::DAGCombinerInfo &DCI,
return SDValue();
}
+static EVT getFloatVT(EVT VT) {
+ return VT = 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 || Mask == 0x8000000000000000u)
+ return DAG.getNode(ISD::FNEG, SL, FVT, BC);
+ break;
+ case ISD::OR:
+ if (Mask == 0x80000000u || Mask == 0x8000000000000000u) {
+ SDValue Neg = DAG.getNode(ISD::FNEG, SDLoc(N), FVT, BC);
+ return DAG.getNode(ISD::FABS, SL, FVT, Neg);
----------------
LU-JOHN wrote:
Thanks for the fix. Do you know why the OR test results do not change after this fix? It seems strange to me that the compiler would generate the same output results with or without this fix. The fix changes the IR's meaning.
https://github.com/llvm/llvm-project/pull/147325
More information about the llvm-commits
mailing list