Skip to content
Snippets Groups Projects
  • Jakub Jelinek's avatar
    b1f6cb2c
    aarch64, builtins: Include PR registers in FUNCTION_ARG_REGNO_P etc. [PR109254] · b1f6cb2c
    Jakub Jelinek authored
    The following testcase is miscompiled on aarch64-linux in the regname pass,
    because while the function takes arguments in the p0 register,
    FUNCTION_ARG_REGNO_P doesn't reflect that, so DF doesn't know the register is
    used in register passing. It sees 2 chains with p1 register and wants to
    replace the second one and as DF doesn't know p0 is live at the start of the
    function, it will happily use p0 register even when it is used in subsequent
    instructions.
    
    The following patch fixes that.  FUNCTION_ARG_REGNO_P returns non-zero
    for p0-p3 (unconditionally, seems for the floating/vector registers it
    doesn't conditionalize them on TARGET_FLOAT either, but if you want,
    I can conditionalize p0-p3 on TARGET_SVE), similarly
    targetm.calls.function_value_regno_p returns true for p0-p3 registers
    if TARGET_SVE (again for consistency, that function conditionalizes
    the float/vector on TARGET_FLOAT).
    
    Now, that change broke bootstrap in libobjc and some
    __builtin_apply_args/__builtin_apply/__builtin_return tests.  The
    aarch64_get_reg_raw_mode hook already documents that SVE scalable arg/return
    passing is fundamentally incompatible with those builtins, but unlike
    the floating/vector regs where it forces a fixed vector mode, I think
    there is no fixed mode which could be used for p0-p3.  So, I have tweaked
    the generic code so that it uses VOIDmode return from that hook to signal
    that a register shouldn't be touched by
    __builtin_apply_args/__builtin_apply/__builtin_return
    despite being mentioned in FUNCTION_ARG_REGNO_P or
    targetm.calls.function_value_regno_p.
    
    gcc/
    2023-04-01  Jakub Jelinek  <jakub@redhat.com>
    
    	PR target/109254
    	* builtins.cc (apply_args_size): If targetm.calls.get_raw_arg_mode
    	returns VOIDmode, handle it like if the register isn't used for
    	passing arguments at all.
    	(apply_result_size): If targetm.calls.get_raw_result_mode returns
    	VOIDmode, handle it like if the register isn't used for returning
    	results at all.
    	* target.def (get_raw_result_mode, get_raw_arg_mode): Document what it
    	means to return VOIDmode.
    	* doc/tm.texi: Regenerated.
    	* config/aarch64/aarch64.cc (aarch64_function_value_regno_p): Return
    	TARGET_SVE for P0_REGNUM.
    	(aarch64_function_arg_regno_p): Also return true for p0-p3.
    	(aarch64_get_reg_raw_mode): Return VOIDmode for PR_REGNUM_P regs.
    
    gcc/testsuite/
    2023-04-01  Jakub Jelinek  <jakub@redhat.com>
    	    Richard Sandiford  <richard.sandiford@arm.com>
    
    	PR target/109254
    	* gcc.target/aarch64/sve/pr109254.c: New test.
    b1f6cb2c
    History
    aarch64, builtins: Include PR registers in FUNCTION_ARG_REGNO_P etc. [PR109254]
    Jakub Jelinek authored
    The following testcase is miscompiled on aarch64-linux in the regname pass,
    because while the function takes arguments in the p0 register,
    FUNCTION_ARG_REGNO_P doesn't reflect that, so DF doesn't know the register is
    used in register passing. It sees 2 chains with p1 register and wants to
    replace the second one and as DF doesn't know p0 is live at the start of the
    function, it will happily use p0 register even when it is used in subsequent
    instructions.
    
    The following patch fixes that.  FUNCTION_ARG_REGNO_P returns non-zero
    for p0-p3 (unconditionally, seems for the floating/vector registers it
    doesn't conditionalize them on TARGET_FLOAT either, but if you want,
    I can conditionalize p0-p3 on TARGET_SVE), similarly
    targetm.calls.function_value_regno_p returns true for p0-p3 registers
    if TARGET_SVE (again for consistency, that function conditionalizes
    the float/vector on TARGET_FLOAT).
    
    Now, that change broke bootstrap in libobjc and some
    __builtin_apply_args/__builtin_apply/__builtin_return tests.  The
    aarch64_get_reg_raw_mode hook already documents that SVE scalable arg/return
    passing is fundamentally incompatible with those builtins, but unlike
    the floating/vector regs where it forces a fixed vector mode, I think
    there is no fixed mode which could be used for p0-p3.  So, I have tweaked
    the generic code so that it uses VOIDmode return from that hook to signal
    that a register shouldn't be touched by
    __builtin_apply_args/__builtin_apply/__builtin_return
    despite being mentioned in FUNCTION_ARG_REGNO_P or
    targetm.calls.function_value_regno_p.
    
    gcc/
    2023-04-01  Jakub Jelinek  <jakub@redhat.com>
    
    	PR target/109254
    	* builtins.cc (apply_args_size): If targetm.calls.get_raw_arg_mode
    	returns VOIDmode, handle it like if the register isn't used for
    	passing arguments at all.
    	(apply_result_size): If targetm.calls.get_raw_result_mode returns
    	VOIDmode, handle it like if the register isn't used for returning
    	results at all.
    	* target.def (get_raw_result_mode, get_raw_arg_mode): Document what it
    	means to return VOIDmode.
    	* doc/tm.texi: Regenerated.
    	* config/aarch64/aarch64.cc (aarch64_function_value_regno_p): Return
    	TARGET_SVE for P0_REGNUM.
    	(aarch64_function_arg_regno_p): Also return true for p0-p3.
    	(aarch64_get_reg_raw_mode): Return VOIDmode for PR_REGNUM_P regs.
    
    gcc/testsuite/
    2023-04-01  Jakub Jelinek  <jakub@redhat.com>
    	    Richard Sandiford  <richard.sandiford@arm.com>
    
    	PR target/109254
    	* gcc.target/aarch64/sve/pr109254.c: New test.
gcc NaN GiB