On Thu, Jun 18, 2026 at 10:12:04PM +0530, Surya Kumari Jangala wrote:
> Hi,
>
> So looks like register allocator does not consider VSX registers when
> -mno-vsx is true.
> The above comment (and the other comments below) can be ignored.
>
> This patch looks good to me. I cannot approve it though.
To be pedantic, note that 'VSX' registers means vector registers vr0
.. vr63.
The traditional floating point registers (i.e. vr0 .. vr31, or fp0
.. fp31) are still available for allocation for scalar modes:
* 32/64-bit integers (but not 8/16/128-bit integers)
* 32/64-bit binary floating point
* 128-bit IBM double double floating point (i.e. __ibm128)
* 32/64/128-bit decimal floating point.
The traditional Altivec registers (vr32 .. vr63, or v0 .. v31) are
available for allocation by the vector types that existed in the
Altivec system before VSX was created:
* 128-bit vectors of 8/16/32-bit integers
* 128-bit vectors of 32-bit binary floating point.
However the types added with VSX and later cannot be allocated:
* 128-bit vectors of 64/128-bit integers
* 128-bit vectors of 64-bit binary floating point
* 128-bit IEEE binary floating point
Without all 64 VSX registers being available, the 'wa' constraint will
not match any register type (i.e. it matches the 'NO_REGS' register
class which has no entries).
The 'v' constraint will match the 'ALTIVEC_REGS' register class.
The 'd' and 'f' constraints will match the 'FLOAT_REGS' register class.
To see a summary of what registers are allocated with different
options, there is the -mdebug=reg option that summarizes the register
allocations.
For example, using the Advance Toolchain AT18 compiler with
-mcpu=power10 -mno-vsx -mdebug=reg:
The first part of the -mdebug=reg output documents the various switches
that are eneabled and disable (note, the lines are somewhat long).
after subtarget = 0xb7a47a266027: -maltivec,
-mno-block-ops-unaligned-vsx, -mno-block-ops-vector-pair, \
-mcmpb, -mno-crypto,
-mno-direct-move, -mno-dlmzb, \
-mno-efficient-unaligned-vsx,
-mno-float128, -mno-float128-hardware, \
-mfprnd, -mpower10,
-mno-power11, -mhard-dfp, -mno-htm, -misel, \
-mmfcrf, -mno-mfpgpr,
-mno-mma, -mmodulo, -mno-mulhw, -mno-multiple, \
-mpcrel, -mno-pcrel-opt,
-mpopcntb, -mpopcntd, -mno-power8-fusion, \
-mno-power8-fusion-sign,
-mno-power8-vector, -mno-power9-minmax, \
-mpower9-misc,
-mno-power9-vector, -mpower10-fusion, \
-mpowerpc-gfxopt,
-mpowerpc-gpopt, -mprefixed, -mno-quad-memory, \
-mquad-memory-atomic,
-mrecip-precision, -msave-toc-indirect, \
-mno-string, -mupdate,
-mno-vsx, -m64, -m32, -mno-eabi, -mlittle, \
-mbig, -mno-relocatable,
-mno-strict-align, -mno-soft-float, \
-mno-string
Then it goes through the GPR registers, documenting what modes can be
allocated to these registers:
gr2: CC, CCUNS, CCFP, CCEQ, BI, QI, HI, SI, DI, TI/2, PTI/2, QQ, HQ, SQ,
DQ, TQ/2, UQQ, UHQ, USQ, UDQ, UTQ/2, HA, SA, DA, TA/2, UHA, USA,
UDA, UTA/2, SF, DF, KF/2, TF/2, IF/2, SD, DD, TD/2, CQI, CHI, CSI,
CDI/2, CPTI/4, CTI/4, SC, DC/2, KC/4, TC/4, IC/4, V2SI, V16QI/2,
V8HI/2, V4SI/2, V2DI/2, V1TI/2, V32QI/4, V16HI/4, V8SI/4, V4DI/4,
V2TI/4, V2SF, V4SF/2, V2DF/2, V2KF/4, V2TF/4, V2IF/4, V8SF/4, V4DF/4,
call-used, reg-class = BASE_REGS, regno = 2
Then the traditional floating point registers:
fp2: SI, DI, SF, DF, KF/2, TF/2, IF/2, SD, DD, TD/2, CSI, CDI/2, SC, DC/2,
KC/4, TC/4, IC/4, call-used, reg-class = FLOAT_REGS, regno = 34
Then the traditional Altivec registes:
vs2: V16QI, V8HI, V4SI, V1TI, V4SF, reg-class = ALTIVEC_REGS, regno = 66
Then the jump registers:
lr: CC, CCUNS, CCFP, CCEQ, BI, QI, HI, SI, DI, QQ, HQ, SQ, DQ, UQQ, UHQ,
USQ, UDQ, HA, SA, DA, UHA, USA, UDA, SF, DF, SD, DD, CQI, CHI, CSI,
CDI/2, SC, DC/2, V2SI, V2SF, call-used, reg-class = LINK_REGS, regno =
96
ctr: CC, CCUNS, CCFP, CCEQ, BI, QI, HI, SI, DI, QQ, HQ, SQ, DQ, UQQ, UHQ,
USQ, UDQ, HA, SA, DA, UHA, USA, UDA, SF, DF, SD, DD, CQI, CHI, CSI,
CDI/2, SC, DC/2, V2SI, V2SF, call-used, reg-class = CTR_REGS, regno = 97
Then the condition code registers:
cr2: CC, CCUNS, CCFP, CCEQ, reg-class = CR_REGS, regno = 102
The constraints that change based on the switches are documented:
d reg_class = FLOAT_REGS
v reg_class = ALTIVEC_REGS
wa reg_class = NO_REGS
we reg_class = NO_REGS
wr reg_class = GENERAL_REGS
wx reg_class = FLOAT_REGS
wA reg_class = BASE_REGS
Then a section of the modes, given the 3 major register types (GPR,
FPR, Altivec/VMX), what kind of address mode is allowed ('v' means the
mode can go in the register group, 'i' in reg+reg indexed addressing,
'o' is reg+offfset address, '++' updates the index register for auto
increment, 'm' means the mode takes multiple registers, there is also
other information for reload handler, and for vectors what type of
vector addrssing is allowed):
Mode: SI Gpr: v io++ Fpr: v i VMX: Any: v io++
Mode: V16QI Gpr: vm Fpr: VMX: v i & Any: vmi & Reload=sl
vector: arith=altivec mem=altivec
Then it goes through the modes listing what modes can be tied with
other modes:
Tieable modes SI: QI HI DI TI V2SI V2SF V32QI V16HI V8SI V4DI V2TI V8SF V4DF
--
Michael Meissner, IBM
PO Box 98, Ayer, Massachusetts, USA, 01432
email: [email protected]