[llvm] [RISCV] Add hasSideEffects = true to ReadFRM (PR #139864)

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Fri May 16 23:36:55 PDT 2025


topperc wrote:

> > > > > > Does implementing `RISCVTargetLowering::getRoundingControlRegisters()` fix this?
> > > > > 
> > > > > 
> > > > > No. As far as I understand, this is used in case of inline asm.
> > > > 
> > > > 
> > > > It's used to add FRM as an implicit def to calls.
> > > > ```
> > > >   // Add rounding control registers as implicit def for function call.
> > > >   if (II.isCall() && MF->getFunction().hasFnAttribute(Attribute::StrictFP)) {
> > > >     ArrayRef<MCPhysReg> RCRegs = TLI->getRoundingControlRegisters();
> > > >     for (MCPhysReg Reg : RCRegs)
> > > >       UsedRegs.push_back(Reg);
> > > >   } 
> > > > ```
> > > > 
> > > > 
> > > >     
> > > >       
> > > >     
> > > > 
> > > >       
> > > >     
> > > > 
> > > >     
> > > >   
> > > > I've tested locally that it does fix your test case.
> > > 
> > > 
> > > Oops I missed that if, sorry, but yes I also implemented `RISCVTargetLowering::getRoundingControlRegisters()` and machine-cse still reordered things.
> > 
> > 
> > Do you have a test case that shows machine-cse reordering things?
> 
> Sure, the test in the precommit have this (#139921).
> 
> This is the behavior without the patch:
> 
> ```
> # *** IR Dump After Verify generated machine code (machineverifier) ***:
> # Machine code for function test_get_rounding_sideeffect: IsSSA, TracksLiveness
> 
> bb.0.entry:
>   successors: %bb.1(0x30000000), %bb.2(0x50000000); %bb.1(37.50%), %bb.2(62.50%)
> 
>   ADJCALLSTACKDOWN 0, 0, implicit-def dead $x2, implicit $x2
>   %3:gpr = ADDI $x0, 1
>   $x10 = COPY %3:gpr
>   PseudoCALL target-flags(riscv-call) @fesetround, <regmask $vlenb $x0 $x1 $x8 $x9 $x18 $x19 $x20 $x21 $x22 $x23 $x24 $x25 $x26 $x27 $f8_f $f9_f $f18_f $f19_f $f20_f $f21_f $f22_f $f23_f $f24_f $f25_f $f26_f $f27_f $f8_h $f9_h $f18_h $f19_h $f20_h $f21_h and 40 more...>, implicit-def dead $x1, implicit $x10, implicit-def $x2, implicit-def $x10
>   ADJCALLSTACKUP 0, 0, implicit-def dead $x2, implicit $x2
>   %5:gpr = ReadFRM implicit $frm
>   %6:gpr = SLLIW killed %5:gpr, 2
>   %7:gpr = LUI 66
>   %8:gpr = ADDIW killed %7:gpr, 769
>   %9:gpr = SRL killed %8:gpr, killed %6:gpr
>   %10:gpr = ANDI killed %9:gpr, 7
>   %11:gpr = COPY $x0
>   %2:gpr = COPY %11:gpr
>   BNE killed %10:gpr, $x0, %bb.2
>   PseudoBR %bb.1
> 
> bb.1.if.end:
> ; predecessors: %bb.0
>   successors: %bb.2(0x80000000); %bb.2(100.00%)
> 
>   ADJCALLSTACKDOWN 0, 0, implicit-def dead $x2, implicit $x2
>   %12:gpr = COPY $x0
>   $x10 = COPY %12:gpr
>   PseudoCALL target-flags(riscv-call) @fesetround, <regmask $vlenb $x0 $x1 $x8 $x9 $x18 $x19 $x20 $x21 $x22 $x23 $x24 $x25 $x26 $x27 $f8_f $f9_f $f18_f $f19_f $f20_f $f21_f $f22_f $f23_f $f24_f $f25_f $f26_f $f27_f $f8_h $f9_h $f18_h $f19_h $f20_h $f21_h and 40 more...>, implicit-def dead $x1, implicit $x10, implicit-def $x2, implicit-def $x10
>   ADJCALLSTACKUP 0, 0, implicit-def dead $x2, implicit $x2
>   %14:gpr = ReadFRM implicit $frm
>   %15:gpr = SLLIW killed %14:gpr, 2
>   %16:gpr = LUI 66
>   %17:gpr = ADDIW killed %16:gpr, 769
>   %18:gpr = SRL killed %17:gpr, killed %15:gpr
>   %19:gpr = ANDI killed %18:gpr, 7
>   %20:gpr = ADDI killed %19:gpr, -1
>   %0:gpr = SLTIU killed %20:gpr, 1
> 
> bb.2.return:
> ; predecessors: %bb.0, %bb.1
> 
>   %1:gpr = PHI %2:gpr, %bb.0, %0:gpr, %bb.1
>   $x10 = COPY %1:gpr
>   PseudoRET implicit $x10
> 
> # End machine code for function test_get_rounding_sideeffect.
> ```
> 
> ```
> # *** IR Dump After Machine Common Subexpression Elimination (machine-cse) ***:
> # Machine code for function test_get_rounding_sideeffect: IsSSA, TracksLiveness
> 
> bb.0.entry:
>   successors: %bb.1(0x30000000), %bb.2(0x50000000); %bb.1(37.50%), %bb.2(62.50%)
> 
>   ADJCALLSTACKDOWN 0, 0, implicit-def dead $x2, implicit $x2
>   %3:gpr = ADDI $x0, 1
>   $x10 = COPY %3:gpr
>   PseudoCALL target-flags(riscv-call) @fesetround, <regmask $vlenb $x0 $x1 $x8 $x9 $x18 $x19 $x20 $x21 $x22 $x23 $x24 $x25 $x26 $x27 $f8_f $f9_f $f18_f $f19_f $f20_f $f21_f $f22_f $f23_f $f24_f $f25_f $f26_f $f27_f $f8_h $f9_h $f18_h $f19_h $f20_h $f21_h and 40 more...>, implicit-def dead $x1, implicit $x10, implicit-def $x2, implicit-def $x10
>   ADJCALLSTACKUP 0, 0, implicit-def dead $x2, implicit $x2
>   %5:gpr = ReadFRM implicit $frm
>   %6:gpr = SLLIW %5:gpr, 2
>   %7:gpr = LUI 66
>   %8:gpr = ADDIW %7:gpr, 769
>   %9:gpr = SRL %8:gpr, %6:gpr
>   %10:gpr = ANDI %9:gpr, 7
>   %11:gpr = COPY $x0
>   %2:gpr = COPY %11:gpr
>   BNE %10:gpr, $x0, %bb.2
>   PseudoBR %bb.1
> 
> bb.1.if.end:
> ; predecessors: %bb.0
>   successors: %bb.2(0x80000000); %bb.2(100.00%)
> 
>   ADJCALLSTACKDOWN 0, 0, implicit-def dead $x2, implicit $x2
>   %12:gpr = COPY $x0
>   $x10 = COPY %12:gpr
>   PseudoCALL target-flags(riscv-call) @fesetround, <regmask $vlenb $x0 $x1 $x8 $x9 $x18 $x19 $x20 $x21 $x22 $x23 $x24 $x25 $x26 $x27 $f8_f $f9_f $f18_f $f19_f $f20_f $f21_f $f22_f $f23_f $f24_f $f25_f $f26_f $f27_f $f8_h $f9_h $f18_h $f19_h $f20_h $f21_h and 40 more...>, implicit-def dead $x1, implicit $x10, implicit-def $x2, implicit-def $x10
>   ADJCALLSTACKUP 0, 0, implicit-def dead $x2, implicit $x2
>   %20:gpr = ADDI %10:gpr, -1
>   %0:gpr = SLTIU killed %20:gpr, 1
> 
> bb.2.return:
> ; predecessors: %bb.0, %bb.1
> 
>   %1:gpr = PHI %2:gpr, %bb.0, %0:gpr, %bb.1
>   $x10 = COPY %1:gpr
>   PseudoRET implicit $x10
> 
> # End machine code for function test_get_rounding_sideeffect.
> ```

The `strictfp` attribute is missing from the `fesetround` calls so the code I pasted from InstrEmitter.cpp that uses `getRoundingControlRegisters` doesn't fire.

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


More information about the llvm-commits mailing list