]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
PR rtl-optimization/112380: Defend against CLOBBERs in combine.cc
authorRoger Sayle <roger@nextmovesoftware.com>
Mon, 11 Dec 2023 17:30:20 +0000 (17:30 +0000)
committerRoger Sayle <roger@nextmovesoftware.com>
Mon, 11 Dec 2023 17:32:35 +0000 (17:32 +0000)
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  <roger@nextmovesoftware.com>

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
gcc/testsuite/gcc.dg/pr112380.c [new file with mode: 0644]

index 6344cd3c9f249ab7834ef600787cde34d08d974c..f2c64a9a979f2597410a36d848dc7a4ec0b7ef89 100644 (file)
@@ -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 (file)
index 0000000..7dd7a85
--- /dev/null
@@ -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);
+}