Hi all,

GMIR currently provides two opcodes for intrinsics:

```
1219 // Intrinsic without side effects.
1220 def G_INTRINSIC : GenericInstruction {
1221 let OutOperandList = (outs);
1222 let InOperandList = (ins unknown:$intrin, variable_ops);
1223 let hasSideEffects = false;
1224
1225 // Conservatively assume this is convergent. If there turnes out to
1226 // be a need, there should be separate convergent intrinsic opcodes.
1227 let isConvergent = 1;
1228 }
1229
1230 // Intrinsic with side effects.
1231 def G_INTRINSIC_W_SIDE_EFFECTS : GenericInstruction {
1232 let OutOperandList = (outs);
1233 let InOperandList = (ins unknown:$intrin, variable_ops);
1234 let hasSideEffects = true;
1235 let mayLoad = true;
1236 let mayStore = true;
1237
1238 // Conservatively assume this is convergent. If there turnes out to
1239 // be a need, there should be separate convergent intrinsic opcodes.
1240 let isConvergent = true;
1241 }
```

I am working on distinguishing between intrinsics based on whether they are convergent. But I don’t fully understand why there should be separate opcodes for that. Each intrinsic already declares whether it is convergent or not. Then, rather than a new generic opcode, why not have an additional MICD that describes the intrinsic? This can be used to decide if a particular occurrence is convergent.

Was this already considered as an option? Am I missing something there?

If we go with separate generic opcodes, we may have something like this:

G_INTRINSIC

G_INTRINSIC_W_SIDE_EFFECTS

G_INTRINSIC_NOTCONVERGENT

G_INTRINSIC_NOTCONVERGENT_W_SIDE_EFFECTS

This recognizes the fact that intrinsics are already assumed to be convergent by default.

Alternatively, we could have:

G_INTRINSIC

G_INTRINSIC_W_SIDE_EFFECTS

G_INTRINSIC_CONVERGENT

G_INTRINSIC_CONVERGENT_W_SIDE_EFFECTS

This would mean that we remove the `isConvergent`

property from the existing opcodes and then conservatively update all existing occurrences to G_INTRINSIC_CONVERGENT.

But where does this end? Will another property further multiply the number of opcodes?

Also separately, there are other opcodes like G_INTRINSIC_TRUNC, which correspond to @llvm intrinsic functions. They are not really intrinsics, right? So a hypothetical `MachineInstr::isIntrinsic()`

should return `false`

for such opcodes?

Sameer.