[gcc r16-6562] [PATCH 1/2] ia64: Fix zero_call_used_regs for PRs [PR121535]
Jeff Law
law@gcc.gnu.org
Wed Jan 7 16:02:44 GMT 2026
https://gcc.gnu.org/g:cdbe47a9f1c92842a240cbbbd0aa6590e84e2cb9
commit r16-6562-gcdbe47a9f1c92842a240cbbbd0aa6590e84e2cb9
Author: Tomas Glozar <tglozar@gmail.com>
Date: Wed Jan 7 09:02:15 2026 -0700
[PATCH 1/2] ia64: Fix zero_call_used_regs for PRs [PR121535]
ia64 uses default_zero_call_used_regs(), which uses emit_move_insn()
to zero out registers. ia64 predicate registers use BImode, which is not
supported by emit_move_insn().
Implement ia64_zero_call_used_regs() to zero PRs by manually emitting
a CCImode move. default_zero_call_used_regs() is then called to handle
the remaining registers.
PR target/121535
gcc/ChangeLog:
* config/ia64/ia64.cc (TARGET_ZERO_CALL_USED_REGS): Override
function with target-specific one.
(struct gcc_target): Move to end of file.
(ia64_zero_call_used_regs): Add target-specific function.
gcc/testsuite/ChangeLog:
* gcc.target/ia64/pr121535.c: New test.
Signed-off-by: Tomas Glozar <tglozar@gmail.com>
Diff:
---
gcc/config/ia64/ia64.cc | 55 ++++++++++++++++++++++++++++++--
gcc/testsuite/gcc.target/ia64/pr121535.c | 7 ++++
2 files changed, 60 insertions(+), 2 deletions(-)
diff --git a/gcc/config/ia64/ia64.cc b/gcc/config/ia64/ia64.cc
index 3dc94dd1d68b..055af3e8617c 100644
--- a/gcc/config/ia64/ia64.cc
+++ b/gcc/config/ia64/ia64.cc
@@ -578,6 +578,9 @@ static const scoped_attribute_specs *const ia64_attribute_table[] =
#undef TARGET_FUNCTION_VALUE_REGNO_P
#define TARGET_FUNCTION_VALUE_REGNO_P ia64_function_value_regno_p
+#undef TARGET_ZERO_CALL_USED_REGS
+#define TARGET_ZERO_CALL_USED_REGS ia64_zero_call_used_regs
+
#undef TARGET_STRUCT_VALUE_RTX
#define TARGET_STRUCT_VALUE_RTX ia64_struct_value_rtx
#undef TARGET_RETURN_IN_MEMORY
@@ -688,8 +691,6 @@ static const scoped_attribute_specs *const ia64_attribute_table[] =
#undef TARGET_DOCUMENTATION_NAME
#define TARGET_DOCUMENTATION_NAME "IA-64"
-
-struct gcc_target targetm = TARGET_INITIALIZER;
/* Returns TRUE iff the target attribute indicated by ATTR_ID takes a plain
identifier as an argument, so the front end shouldn't look it up. */
@@ -5330,6 +5331,54 @@ ia64_function_value_regno_p (const unsigned int regno)
|| (regno >= FR_RET_FIRST && regno <= FR_RET_LAST));
}
+/* TARGET_ZERO_CALL_USED_REGS. */
+/* Generate a sequence of instructions that zero registers specified by
+ NEED_ZEROED_HARDREGS. Return the ZEROED_HARDREGS that are actually
+ zeroed. */
+static HARD_REG_SET
+ia64_zero_call_used_regs (HARD_REG_SET need_zeroed_hardregs)
+{
+ HARD_REG_SET nonpredicate, failed;
+
+ CLEAR_HARD_REG_SET (nonpredicate);
+ CLEAR_HARD_REG_SET (failed);
+
+ /* Mark all non-predicate registers. */
+ for (int regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno)
+ if (TEST_HARD_REG_BIT (need_zeroed_hardregs, regno)
+ && !PR_REGNO_P (regno))
+ SET_HARD_REG_BIT (nonpredicate, regno);
+
+ /* Let the generic helper emit zeroing for the remaining hard regs.
+ It returns the subset it actually managed to zero. */
+ if (!hard_reg_set_empty_p (nonpredicate))
+ failed = default_zero_call_used_regs (nonpredicate);
+
+ /* Finally, emit zeroing of predicate registers. */
+ for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
+ if (TEST_HARD_REG_BIT (need_zeroed_hardregs, regno)
+ && PR_REGNO_P (regno))
+ {
+ rtx_insn *last_insn = get_last_insn ();
+ /* Prepare PR0 register, which is hardwired to 1 */
+ rtx zero = gen_rtx_REG (CCImode, PR_REG (0));
+ rtx regno_rtx = gen_rtx_REG (CCImode, regno);
+ enum insn_code code = optab_handler (mov_optab, CCImode);
+
+ gcc_assert (code != CODE_FOR_nothing);
+
+ rtx_insn *insn = emit_insn (GEN_FCN (code) (regno_rtx, zero));
+
+ if (!valid_insn_p (insn))
+ {
+ SET_HARD_REG_BIT (failed, regno);
+ delete_insns_since (last_insn);
+ }
+ }
+
+ return failed;
+}
+
/* This is called from dwarf2out.cc via TARGET_ASM_OUTPUT_DWARF_DTPREL.
We need to emit DTP-relative relocations. */
@@ -11960,4 +12009,6 @@ ia64_can_change_mode_class (machine_mode from, machine_mode to,
return true;
}
+struct gcc_target targetm = TARGET_INITIALIZER;
+
#include "gt-ia64.h"
diff --git a/gcc/testsuite/gcc.target/ia64/pr121535.c b/gcc/testsuite/gcc.target/ia64/pr121535.c
new file mode 100644
index 000000000000..134120c019a0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/ia64/pr121535.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+__attribute__ ((zero_call_used_regs("used"))) int f(int x)
+{
+ if (x == 1)
+ return 0;
+ return 1;
+}
More information about the Gcc-cvs
mailing list