[llvm] [TableGen][GISel] Create untyped registers during instruction selection (PR #121270)

Sergei Barannikov via llvm-commits llvm-commits at lists.llvm.org
Mon Jan 6 04:05:31 PST 2025


================
@@ -3708,10 +3708,10 @@ const TargetRegisterClass *
 SIRegisterInfo::getConstrainedRegClassForOperand(const MachineOperand &MO,
                                          const MachineRegisterInfo &MRI) const {
   const RegClassOrRegBank &RCOrRB = MRI.getRegClassOrRegBank(MO.getReg());
-  if (const RegisterBank *RB = dyn_cast<const RegisterBank *>(RCOrRB))
+  if (const auto *RB = dyn_cast_or_null<const RegisterBank *>(RCOrRB))
----------------
s-barannikov wrote:

This is due to a peculiar property (bug?) of PointerUnion and not strictly related to this change.

When creating a generic virtual register without bank/class using `createGenericVirtualRegister()` (this is what instruction selector currently does), the union's active member [is set to `RegisterBank`](https://github.com/llvm/llvm-project/blob/1849244685bc42b07b1b14e3f62e15c535e74c39/llvm/lib/CodeGen/MachineRegisterInfo.cpp#L198) for some reason. The first `dyn_cast` returns nullptr even though its argument is effectively a nullptr. The second `dyn_cast` also returns nullptr because the union doesn't hold TargetRegisterClass.

When using `createIncompleteVirtualRegister()`, the active member is set to `RegisterClass` (the union is default constructed). The first `dyn_cast` returns nullptr because the union doesn't hold RegisterBank, as expected. The second `dyn_cast`, however, asserts, because the argument is a null pointer.

That is, depending on which union member is active, `dyn_cast` either allows or disallows null pointer argument.


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


More information about the llvm-commits mailing list