From 624e274ca3a4405a55662fa72d1163120df0e03d Mon Sep 17 00:00:00 2001 From: Roger Sayle Date: Mon, 11 Dec 2023 17:30:20 +0000 Subject: [PATCH] PR rtl-optimization/112380: Defend against CLOBBERs in combine.cc This patch addresses PR rtl-optimization/112380, an ICE-on-valid regression where a (clobber (const_int 0)) encounters a sanity checking gcc_assert (at line 7554) in simplify-rtx.cc. These CLOBBERs are used internally by GCC's combine pass much like error_mark_node is used by various language front-ends. The solutions are either to handle/accept these CLOBBERs through-out (or in more places in) the middle-end's RTL optimizers, including functions in simplify-rtx.cc that are used by passes other than combine, and/or attempt to prevent these CLOBBERs escaping from try_combine into the RTX/RTL stream. The benefit of the second approach is that it actually allows for better optimization: when try_combine fails to simplify an expression instead of substituting a CLOBBER to avoid the instruction pattern being recognized, noticing the CLOBBER often allows combine to attempt alternate simplifications/transformations looking for those that can be recognized. This first alternative is the minimal fix to address the CLOBBER encountered in the bugzilla PR. 2023-12-11 Roger Sayle gcc/ChangeLog PR rtl-optimization/112380 * combine.cc (expand_field_assignment): Check if gen_lowpart returned a CLOBBER, and avoid calling gen_simplify_binary with it if so. gcc/testsuite/ChangeLog PR rtl-optimization/112380 * gcc.dg/pr112380.c: New test case. --- gcc/combine.cc | 9 ++++++--- gcc/testsuite/gcc.dg/pr112380.c | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr112380.c diff --git a/gcc/combine.cc b/gcc/combine.cc index 6344cd3c9f2..f2c64a9a979 100644 --- a/gcc/combine.cc +++ b/gcc/combine.cc @@ -7466,6 +7466,11 @@ expand_field_assignment (const_rtx x) if (!targetm.scalar_mode_supported_p (compute_mode)) break; + /* gen_lowpart_for_combine returns CLOBBER on failure. */ + rtx lowpart = gen_lowpart (compute_mode, SET_SRC (x)); + if (GET_CODE (lowpart) == CLOBBER) + break; + /* Now compute the equivalent expression. Make a copy of INNER for the SET_DEST in case it is a MEM into which we will substitute; we don't want shared RTL in that case. */ @@ -7480,9 +7485,7 @@ expand_field_assignment (const_rtx x) inner); masked = simplify_gen_binary (ASHIFT, compute_mode, simplify_gen_binary ( - AND, compute_mode, - gen_lowpart (compute_mode, SET_SRC (x)), - mask), + AND, compute_mode, lowpart, mask), pos); x = gen_rtx_SET (copy_rtx (inner), diff --git a/gcc/testsuite/gcc.dg/pr112380.c b/gcc/testsuite/gcc.dg/pr112380.c new file mode 100644 index 00000000000..7dd7a85d363 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr112380.c @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +enum { TGSI_FILE_NULL }; +struct ureg_src { + unsigned File : 4; + unsigned : 2; + unsigned : 2; + unsigned : 2; + unsigned : 1; + unsigned IndirectFile : 4; + unsigned IndirectSwizzle : 2; + int : 16; + int : 6; + int : 16; + int : 16; + unsigned : 10; +} __trans_tmp_1; + +int ureg_src_indirect_addr_1, ntt_emit_texture_instr_sampler_handle_src; + +void ureg_scalar(struct ureg_src); + +void ntt_emit_texture_instr() { + struct ureg_src sampler; + if (ntt_emit_texture_instr_sampler_handle_src) + sampler = __trans_tmp_1; + struct ureg_src reg = sampler; + reg.File != TGSI_FILE_NULL; + reg.IndirectFile = reg.IndirectSwizzle = ureg_src_indirect_addr_1; + sampler = reg; + ureg_scalar(reg); +}