[llvm] [AMDGPU] Fix uniform fcopysign pattern (PR #218644)

via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 26 18:03:59 PDT 2026


Shoreshen wrote:

> > In the end, the real calculation instruction `%33:vgpr_16 = nofpexcept V_ADD_F16_t16_e64...` will be marked dead.
> 
> I really can't understand why that would happen, based on the MIR that you showed. It sounds like there must be something wrong in the detect-dead-lanes pass?

Hi @jayfoad , for the dead lane detect pass, it will giving each register 2 bit map (def and use), and each bit map's width is the number of lane (2 bit for 32 bit register, since the reg-unit is 16 bit).

Use is going to propagate backward and def is forward. So for the following MIR:
```llvm
bb.2.positive:
; predecessors: %bb.1
  successors: %bb.4(0x80000000); %bb.4(100.00%)

  %33:vgpr_16 = nofpexcept V_ADD_F16_t16_e64 0, %49.lo16:vgpr_32, 0, %49.lo16:vgpr_32, 0, 0, 0, implicit $mode, implicit $exec
  %48:vgpr_16 = IMPLICIT_DEF
  %47:vgpr_32 = REG_SEQUENCE %33:vgpr_16, %subreg.lo16, %48:vgpr_16, %subreg.hi16
  S_BRANCH %bb.4
...
bb.4.exit:
; predecessors: %bb.1, %bb.2

  %53:vgpr_32 = PHI %51:vgpr_32, %bb.1, %47:vgpr_32, %bb.2
  %35:sreg_32 = IMPLICIT_DEF
  %34:vgpr_32 = REG_SEQUENCE %49:vgpr_32, %subreg.lo16, %35:sreg_32, %subreg.hi16
  %38:sreg_32 = IMPLICIT_DEF
  %37:vgpr_32 = REG_SEQUENCE %53:vgpr_32, %subreg.lo16, %38:sreg_32, %subreg.hi16
  %41:vgpr_32 = V_BFI_B32_e64 32767, killed %37:vgpr_32, killed %34:vgpr_32, implicit $exec
  %43:vgpr_32 = V_MOV_B32_e32 0, implicit $exec
  GLOBAL_STORE_SHORT_SADDR_t16 killed %43:vgpr_32, %41.lo16:vgpr_32, %21:sgpr_64, 0, 0, implicit $exec :: (store (s16) into %ir.out, addrspace 1)
  SI_RETURN
```
For use:
1. `%37:vgpr_32` is used in `V_BFI_B32_e64` fully, so both bits are set, it is 0b11=0x3
2. `%53:vgpr_32` is used as `lo16` of `%37:vgpr_32`
4. At this step, the pass thinks that the source should be a 16 bit register, so `%53:vgpr_32` should be fully used.
5. For 16 bit register, the width of bit map is 1, fully used, so use of `%53:vgpr_32` is set to 1.
6. The def of `%53:vgpr_32`  coming from `%47:vgpr_32`, and `%47:vgpr_32` is only defined for `lo16`
7. From the macro, the `lo16` is actually corresponding to bit 2 in 32bit reg, and `hi16` is 0x1:
     <img width="443" height="149" alt="image" src="https://github.com/user-attachments/assets/547c61ae-98da-4d6f-9afa-9bfc552704cc" />
8. So for `%53:vgpr_32`, its use from `%37:vgpr_32` is 0x1, its def from `%47:vgpr_32` is 0x2, no overlap in bitmap. Thus it is not used, and anything defining it will be mark as dead.

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


More information about the llvm-commits mailing list