https://gcc.gnu.org/g:38b9872fb430422e6cfca2ed0f2a0e3b3ab715ac
commit 38b9872fb430422e6cfca2ed0f2a0e3b3ab715ac Author: Andrew Stubbs <[email protected]> Date: Thu Sep 17 11:27:25 2026 +0000 amdgcn: handle xnack in pre-split mov insns This has been a latent bug for a while, apparently. The load instructions must be restartable when xnack is enabled, and therefore must be no-clobber, even when they'll get split later. Backport from mainline: gcc/ChangeLog: * config/gcn/gcn-valu.md (mov<mode>_exec): Add xnack alternatives. (@mov<mode>_sgprbase): Likewise. (cherry picked from commit db655b1fdce54adaf3d983ad73dd02db6cbdedf8) Diff: --- gcc/config/gcn/gcn-valu.md | 80 +++++++++++++++++++++++++--------------------- 1 file changed, 44 insertions(+), 36 deletions(-) diff --git a/gcc/config/gcn/gcn-valu.md b/gcc/config/gcn/gcn-valu.md index c8e906fc8589..2196c5db70f4 100644 --- a/gcc/config/gcn/gcn-valu.md +++ b/gcc/config/gcn/gcn-valu.md @@ -500,13 +500,14 @@ (match_operand:DI 3 "register_operand"))) (clobber (match_scratch:<VnDI> 4))] "!MEM_P (operands[0]) || REG_P (operands[1])" - {@ [cons: =0, 1, 2, 3, =4; attrs: type, length] - [v,vA,U0,e ,X ;vop1 ,4 ] v_mov_b32\t%0, %1 - [v,B ,U0,e ,X ;vop1 ,8 ] v_mov_b32\t%0, %1 - [v,v ,vA,cV,X ;vop2 ,4 ] v_cndmask_b32\t%0, %2, %1, vcc - [v,vA,vA,Sv,X ;vop3a,8 ] v_cndmask_b32\t%0, %2, %1, %3 - [v,m ,U0,e ,&v;* ,16] # - [m,v ,U0,e ,&v;* ,16] # + {@ [cons: =0, 1, 2, 3, =4; attrs: type, length, xnack] + [v ,vA,U0,e ,X ;vop1 ,4 ,* ] v_mov_b32\t%0, %1 + [v ,B ,U0,e ,X ;vop1 ,8 ,* ] v_mov_b32\t%0, %1 + [v ,v ,vA,cV,X ;vop2 ,4 ,* ] v_cndmask_b32\t%0, %2, %1, vcc + [v ,vA,vA,Sv,X ;vop3a,8 ,* ] v_cndmask_b32\t%0, %2, %1, %3 + [v ,m ,U0,e ,&v;* ,16,off] # + [&v,m ,U0,e ,&v;* ,16,on ] # + [m ,v ,U0,e ,&v;* ,16,* ] # }) (define_insn "*mov<mode>" @@ -529,12 +530,13 @@ (match_operand:DI 3 "register_operand"))) (clobber (match_scratch:<VnDI> 4))] "!MEM_P (operands[0]) || REG_P (operands[1])" - {@ [cons: =0, 1, 2, 3, =4; attrs: type, length] - [v,vDB,U0 ,e ,X ;vmult,16] v_mov_b32\t%L0, %L1\;v_mov_b32\t%H0, %H1 - [v,v0 ,vDA0,cV,X ;vmult,16] v_cndmask_b32\t%L0, %L2, %L1, vcc\;v_cndmask_b32\t%H0, %H2, %H1, vcc - [v,v0 ,vDA0,Sv,X ;vmult,16] v_cndmask_b32\t%L0, %L2, %L1, %3\;v_cndmask_b32\t%H0, %H2, %H1, %3 - [v,m ,U0 ,e ,&v;* ,16] # - [m,v ,U0 ,e ,&v;* ,16] # + {@ [cons: =0, 1, 2, 3, =4; attrs: type, length, xnack] + [v ,vDB,U0 ,e ,X ;vmult,16,* ] v_mov_b32\t%L0, %L1\;v_mov_b32\t%H0, %H1 + [v ,v0 ,vDA0,cV,X ;vmult,16,* ] v_cndmask_b32\t%L0, %L2, %L1, vcc\;v_cndmask_b32\t%H0, %H2, %H1, vcc + [v ,v0 ,vDA0,Sv,X ;vmult,16,* ] v_cndmask_b32\t%L0, %L2, %L1, %3\;v_cndmask_b32\t%H0, %H2, %H1, %3 + [v ,m ,U0 ,e ,&v;* ,16,off] # + [&v,m ,U0 ,e ,&v;* ,16,on ] # + [m ,v ,U0 ,e ,&v;* ,16,* ] # }) (define_insn "*mov<mode>_4reg" @@ -556,12 +558,13 @@ (match_operand:DI 3 "register_operand"))) (clobber (match_scratch:<VnDI> 4))] "!MEM_P (operands[0]) || REG_P (operands[1])" - {@ [cons: =0, 1, 2, 3, =4; attrs: type, length] - [v,vDB,U0 ,e ,X ;vmult,32] v_mov_b32\t%L0, %L1\;v_mov_b32\t%H0, %H1\;v_mov_b32\t%J0, %J1\;v_mov_b32\t%K0, %K1 - [v,v0 ,vDA0,cV,X ;vmult,32] v_cndmask_b32\t%L0, %L2, %L1, vcc\;v_cndmask_b32\t%H0, %H2, %H1, vcc\;v_cndmask_b32\t%J0, %J2, %J1, vcc\;v_cndmask_b32\t%K0, %K2, %K1, vcc - [v,v0 ,vDA0,Sv,X ;vmult,32] v_cndmask_b32\t%L0, %L2, %L1, %3\;v_cndmask_b32\t%H0, %H2, %H1, %3\;v_cndmask_b32\t%J0, %J2, %J1, %3\;v_cndmask_b32\t%K0, %K2, %K1, %3 - [v,m ,U0 ,e ,&v;* ,32] # - [m,v ,U0 ,e ,&v;* ,32] # + {@ [cons: =0, 1, 2, 3, =4; attrs: type, length, xnack] + [v ,vDB,U0 ,e ,X ;vmult,32,* ] v_mov_b32\t%L0, %L1\;v_mov_b32\t%H0, %H1\;v_mov_b32\t%J0, %J1\;v_mov_b32\t%K0, %K1 + [v ,v0 ,vDA0,cV,X ;vmult,32,* ] v_cndmask_b32\t%L0, %L2, %L1, vcc\;v_cndmask_b32\t%H0, %H2, %H1, vcc\;v_cndmask_b32\t%J0, %J2, %J1, vcc\;v_cndmask_b32\t%K0, %K2, %K1, vcc + [v ,v0 ,vDA0,Sv,X ;vmult,32,* ] v_cndmask_b32\t%L0, %L2, %L1, %3\;v_cndmask_b32\t%H0, %H2, %H1, %3\;v_cndmask_b32\t%J0, %J2, %J1, %3\;v_cndmask_b32\t%K0, %K2, %K1, %3 + [v ,m ,U0 ,e ,&v;* ,32,off] # + [&v,m ,U0 ,e ,&v;* ,32,on ] # + [m ,v ,U0 ,e ,&v;* ,32,* ] # }) ; A SGPR-base load looks like: @@ -583,13 +586,15 @@ UNSPEC_SGPRBASE)) (clobber (match_operand:<VnDI> 2 "register_operand"))] "lra_in_progress || reload_completed" - {@ [cons: =0, 1, =2; attrs: type, length, cdna] - [v,vA,&v;vop1,4 ,* ] v_mov_b32\t%0, %1 - [v,vB,&v;vop1,8 ,* ] ^ - [v,m ,&v;* ,12,* ] # - [m,v ,&v;* ,12,* ] # - [a,m ,&v;* ,12,cdna2] # - [m,a ,&v;* ,12,cdna2] # + {@ [cons: =0, 1, =2; attrs: type, length, cdna, xnack] + [v ,vA,&v;vop1,4 ,* ,* ] v_mov_b32\t%0, %1 + [v ,vB,&v;vop1,8 ,* ,* ] ^ + [v ,m ,&v;* ,12,* ,off] # + [&v,m ,&v;* ,12,* ,on ] # + [m ,v ,&v;* ,12,* ,* ] # + [a ,m ,&v;* ,12,cdna2,off] # + [&a,m ,&v;* ,12,cdna2,on ] # + [m ,a ,&v;* ,12,cdna2,* ] # }) (define_insn "@mov<mode>_sgprbase" @@ -599,12 +604,14 @@ UNSPEC_SGPRBASE)) (clobber (match_operand:<VnDI> 2 "register_operand"))] "lra_in_progress || reload_completed" - {@ [cons: =0, 1, =2; attrs: type, length, cdna] - [v,vDB,&v;vmult,8 ,* ] v_mov_b32\t%L0, %L1\;v_mov_b32\t%H0, %H1 - [v,m ,&v;* ,12,* ] # - [m,v ,&v;* ,12,* ] # - [a,m ,&v;* ,12,cdna2] # - [m,a ,&v;* ,12,cdna2] # + {@ [cons: =0, 1, =2; attrs: type, length, cdna, xnack] + [v ,vDB,&v;vmult,8 ,* ,* ] v_mov_b32\t%L0, %L1\;v_mov_b32\t%H0, %H1 + [v ,m ,&v;* ,12,* ,off] # + [&v,m ,&v;* ,12,* ,on ] # + [m ,v ,&v;* ,12,* ,* ] # + [a ,m ,&v;* ,12,cdna2,off] # + [&a,m ,&v;* ,12,cdna2,on ] # + [m ,a ,&v;* ,12,cdna2,* ] # }) (define_insn "@mov<mode>_sgprbase" @@ -614,10 +621,11 @@ UNSPEC_SGPRBASE)) (clobber (match_operand:<VnDI> 2 "register_operand"))] "lra_in_progress || reload_completed" - {@ [cons: =0, 1, =2; attrs: type, length] - [v,vDB,&v;vmult,8 ] v_mov_b32\t%L0, %L1\;v_mov_b32\t%H0, %H1\;v_mov_b32\t%J0, %J1\;v_mov_b32\t%K0, %K1 - [v,m ,&v;* ,12] # - [m,v ,&v;* ,12] # + {@ [cons: =0, 1, =2; attrs: type, length, xnack] + [v ,vDB,&v;vmult,8 ,* ] v_mov_b32\t%L0, %L1\;v_mov_b32\t%H0, %H1\;v_mov_b32\t%J0, %J1\;v_mov_b32\t%K0, %K1 + [v ,m ,&v;* ,12,off] # + [&v,m ,&v;* ,12,on ] # + [m ,v ,&v;* ,12,* ] # }) ; Expand scalar addresses into gather/scatter patterns
