[clang] [llvm] [HLSL] Adding Flatten and Branch if attributes (PR #116331)

Nathan Gauër via llvm-commits llvm-commits at lists.llvm.org
Mon Dec 16 05:01:31 PST 2024


================
@@ -2776,19 +2776,35 @@ bool SPIRVInstructionSelector::selectIntrinsic(Register ResVReg,
     }
     return MIB.constrainAllUses(TII, TRI, RBI);
   }
-  case Intrinsic::spv_loop_merge:
-  case Intrinsic::spv_selection_merge: {
-    const auto Opcode = IID == Intrinsic::spv_selection_merge
-                            ? SPIRV::OpSelectionMerge
-                            : SPIRV::OpLoopMerge;
-    auto MIB = BuildMI(BB, I, I.getDebugLoc(), TII.get(Opcode));
+  case Intrinsic::spv_loop_merge: {
+    auto MIB = BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpLoopMerge));
     for (unsigned i = 1; i < I.getNumExplicitOperands(); ++i) {
       assert(I.getOperand(i).isMBB());
       MIB.addMBB(I.getOperand(i).getMBB());
     }
     MIB.addImm(SPIRV::SelectionControl::None);
     return MIB.constrainAllUses(TII, TRI, RBI);
   }
+  case Intrinsic::spv_selection_merge: {
+
+    int64_t SelectionControl = SPIRV::SelectionControl::None;
+    auto LastOp = I.getOperand(I.getNumOperands() - 1);
+
+    auto BranchHint = LastOp.getImm();
+    if (BranchHint == 2)
+      SelectionControl = SPIRV::SelectionControl::Flatten;
+    else if (BranchHint == 1)
+      SelectionControl = SPIRV::SelectionControl::DontFlatten;
+
+    auto MIB =
+        BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpSelectionMerge));
+    for (unsigned i = 1; i < I.getNumExplicitOperands() - 1; ++i) {
+      assert(I.getOperand(i).isMBB());
+      MIB.addMBB(I.getOperand(i).getMBB());
+    }
+    MIB.addImm(SelectionControl);
+    return MIB.constrainAllUses(TII, TRI, RBI);
+  }
----------------
Keenuts wrote:

Why do you need to loop through the operands given the instruction is not variadic?
(Sadly the Flatten/DontFlatten immediate values don't match the FE values so cannot static cast into the enum :/ )

```suggestion
namespace {
SPIRV::SelectionControl GetSelectionOperandForImm(int Imm) {
    if (Imm == 2)
        return SPIRV::SelectionControl::Flatten;
    if (Imm == 1)
        return SPIRV::SelectionControl::DontFlatten;
    if (Imm == 0)
        return SPIRV::SelectionControl::None;
    llvm::unreachable("Invalid immediate")
}

[...]
  case Intrinsic::spv_selection_merge: {
    auto MIB = BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpSelectionMerge));
    assert(I.getOperand(1).isMBB());
    MIB.addMBB(I.getOperand(1).getMBB());
    MIB.addImm(GetSelectionOperandForImmediate(I.getOperand(2).getImm());
    return MIB.constrainAllUses(TII, TRI, RBI);
  }
```



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


More information about the llvm-commits mailing list