diff options
author | Chris Jackson <chris.jackson@amd.com> | 2025-08-07 19:45:09 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-08-07 19:45:09 +0100 |
commit | 9f102a90042fd3757c207112cfe64ee10182ace5 (patch) | |
tree | f1754dad7eee788daf8e29bd24784dc1376d3015 /llvm/lib | |
parent | 4e11f89904dc9b77ef44b01c68742e5b00bfdf21 (diff) | |
download | llvm-9f102a90042fd3757c207112cfe64ee10182ace5.zip llvm-9f102a90042fd3757c207112cfe64ee10182ace5.tar.gz llvm-9f102a90042fd3757c207112cfe64ee10182ace5.tar.bz2 |
[AMDGPU] Recognise bitmask operations as srcmods on select (#152119)
Add to the VOP patterns to recognise when or/xor/and are masking only the most significant bit of i32/v2i32/i64 and replace with the corresponding FP source modifier.
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp b/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp index fb83388..9d6584a 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp @@ -3212,6 +3212,44 @@ bool AMDGPUDAGToDAGISel::SelectVOP3ModsImpl(SDValue In, SDValue &Src, Src = Src.getOperand(0); } + if (Mods != SISrcMods::NONE) + return true; + + // Convert various sign-bit masks on integers to src mods. Currently disabled + // for 16-bit types as the codegen replaces the operand without adding a + // srcmod. This is intentionally finding the cases where we are performing + // float neg and abs on int types, the goal is not to obtain two's complement + // neg or abs. Limit converison to select operands via the nonCanonalizing + // pattern. + // TODO: Add 16-bit support. + if (IsCanonicalizing) + return true; + + unsigned Opc = Src->getOpcode(); + EVT VT = Src.getValueType(); + if ((Opc != ISD::AND && Opc != ISD::OR && Opc != ISD::XOR) || + (VT != MVT::i32 && VT != MVT::i64)) + return true; + + ConstantSDNode *CRHS = dyn_cast<ConstantSDNode>(Src->getOperand(1)); + if (!CRHS) + return true; + + // Recognise (xor a, 0x80000000) as NEG SrcMod. + // Recognise (and a, 0x7fffffff) as ABS SrcMod. + // Recognise (or a, 0x80000000) as NEG+ABS SrcModifiers. + if (Opc == ISD::XOR && CRHS->getAPIntValue().isSignMask()) { + Mods |= SISrcMods::NEG; + Src = Src.getOperand(0); + } else if (Opc == ISD::AND && AllowAbs && + CRHS->getAPIntValue().isMaxSignedValue()) { + Mods |= SISrcMods::ABS; + Src = Src.getOperand(0); + } else if (Opc == ISD::OR && AllowAbs && CRHS->getAPIntValue().isSignMask()) { + Mods |= SISrcMods::ABS | SISrcMods::NEG; + Src = Src.getOperand(0); + } + return true; } |