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

via cfe-commits cfe-commits at lists.llvm.org
Tue Dec 3 12:45:45 PST 2024


================
@@ -2694,19 +2694,49 @@ 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: {
+
+    auto SelectionControl = SPIRV::SelectionControl::None;
+    auto LastOp = I.getOperand(I.getNumExplicitOperands() - 1);
----------------
joaosaffran wrote:

@Keenuts @s-perron, I am trying to implement this suggestion from @llvm-beanz, but I am facing an issue.

This is the current definition for `OpSelectMerge`:
```C++
  def int_spv_loop_merge : Intrinsic<[], [llvm_vararg_ty]>;
```
The suggested solution, requires me to change into this:
 
```C++
  def int_spv_selection_merge : Intrinsic<[], [llvm_i32_ty,llvm_vararg_ty], [ImmArg<ArgIndex<0>>]>;
```
The problem I am facing is, the current first parameter of `OpSelectMerge` is a basic block address, and there is a bunch of places that do similar to the following:
 
```C++
  // Otherwise, we need to check: was there an OpSelectionMerge before this
  // branch? If we removed the OpBranchConditional, we must also remove the
  // OpSelectionMerge. This is not valid for OpLoopMerge:
  IntrinsicInst *II =
      dyn_cast<IntrinsicInst>(BB->getTerminator()->getPrevNode());
  if (!II || II->getIntrinsicID() != Intrinsic::spv_selection_merge)
    return;
  Constant *C = cast<Constant>(II->getOperand(0));
  II->eraseFromParent();
  if (!C->isConstantUsed())
    C->destroyConstant();
}
```

My question is, should I go through the code and replace everywhere that is reading the first operand to read the second? Or there is a better way to pass this value to op instruct selector?

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


More information about the cfe-commits mailing list