[PATCH] D142612: [RISCV][NFC] Add test for register coalescing x0

Luke Lau via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Jan 27 09:45:05 PST 2023


luke added a subscriber: qcolombet.
luke added a comment.

@qcolombet Apologies if I'm pinging the wrong person here, I'm looking for some advice on some register coalescer behaviour, let me know if this question is better directed towards someone else. 
On RISC-V we're seeing some unexpected extra COPYs being left around with these `$x0` registers, which is both a reserved and constant physical register.

In both test cases, `%0` is unable to be coalesced due to the fact that it has a "complex interval" with multiple values, i.e. in `f` the intervals look like:

  ********** INTERVALS **********
  %0 [16r,48B:1)[64r,80B:0)[80B,96r:2) 0 at 64r 1 at 16r 2 at 80B-phi  weight:0.000000e+00
  RegMasks:
  ********** MACHINEINSTRS **********
  # Machine code for function f: NoPHIs
  
  0B	bb.0:
  	  successors: %bb.2(0x40000000), %bb.1(0x40000000); %bb.2(50.00%), %bb.1(50.00%)
  
  16B	  %0:gpr = COPY $x0
  32B	  BEQ $x1, $x2, %bb.2
  
  48B	bb.1:
  	; predecessors: %bb.0
  	  successors: %bb.2(0x80000000); %bb.2(100.00%)
  
  64B	  %0:gpr = COPY $x0
  
  80B	bb.2:
  	; predecessors: %bb.0, %bb.1
  
  96B	  PseudoRET implicit %0:gpr

So it can't perform `joinReservedPhysReg` on `%0` because its interval has multiple values.

(Note that test case requires the conditional branch, otherwise the second def of `%0` is marked as killed and it gets split into another virtual register, which coincidentally allows the copies to be coalesced since they will all have simple intervals)

Ideally in test case `f` we'd like to see:

  bb.0:
    ; COPY removed
    BEQ $x1, $x2, %bb.2
  
  bb.1:
    ; COPY removed
  
  bb.2:
    PseudoRET implicit $x0

and in test case `g`:

  bb.0:
    %0 = COPY $x0
    BEQ $x1, $x2, %bb.2
  
  bb.1:
    ; COPY removed
    %0 = ADDI $x0, 1
  
  bb.2:
    PseudoRET implicit %0

Should these copy eliminations be possible to do in the register coalescer, or is it something that should be taken care of by another pass?
I'm mainly asking because in `g` we can't just remove all the copies and coalesce the `$0`s and `%1`s together, we can only remove some of them. And from what I understand from reading `RegisterCoalescer.cpp`, it can currently only join intervals completely.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D142612/new/

https://reviews.llvm.org/D142612



More information about the llvm-commits mailing list