https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112560
--- Comment #13 from Uroš Bizjak <ubizjak at gmail dot com> --- (In reply to Segher Boessenkool from comment #12) > You cannot use a :CC value as argument of an unspec, as explained before. > > The result of a comparison is expressed as a comparison, in RTL. This patch > allows malformed RTL in more places than before, not progress at all. During our discussion we determined that this form with UNSPEC is actually a copy operation, so it is not an use [1] of CC register, because "use" is in the form of cc-compared-to-0. [1] https://gcc.gnu.org/pipermail/gcc-patches/2024-March/647426.html Now, let's see the part my patch fixes. The original change that introduced the functionality (See Comment #1) updates the "use" of the CC register. It assumes exclusively cc-compared-to-0 use, but there are several patterns in various target .md files that use naked CC register. The "???" comment suggests that the transformation tripped on this and thus the "verify the zero_rtx" was bolted on. The zero_rtx is inherent part of the regular CC reg "use", so this addition _mostly_ weeded out invalid access with naked CC reg. If the CC reg is used as the source of copy operation ("move"), with or without UNSPEC, then the unpatched compiler will blindly use: SUBST (XEXP (*cc_use_loc, 0), newpat_dest); which *assumes* the certain form of the changed expression. Failed assumption will lead to memory corruption, and this is what my patch prevents. Patched compiler will find the sole use of the naked CC reg (due to find_single_use) in the RTX, and update its mode at the right place. If the new mode is not recognized by the insn pattern, then the combination is rejected. In any case, we are trading silent memory corruption with failed combine attempt. In my rule book, this is "progress" with bold, capital letters.