RISC-V combined sCC splitters generate new RTL nodes instead of modifying existing ones.
GCC's RISC-V backend now generates new RTL nodes for combined comparison splitters rather than modifying existing ones, preventing miscompilations.
This commit fixes a miscompilation issue on RISC-V, particularly impacting programs like omnet from spec2017. Previously, the combined comparison code (sCC) splitters would sometimes modify existing Register Transfer Language (RTL) nodes using PUT_MODE or PUT_CODE when splitting instructions. This approach proved problematic if the split was not fully applied, leading to incorrect modifications of the Instruction-Level (IL) representation. The updated strategy involves generating entirely new RTL nodes during the splitting process, ensuring that the original IL remains untouched and preventing unintended side-effects and miscompilations.
In Details
This change in config/riscv/zicond.md is a critical fix for the RISC-V backend's pattern matching and instruction splitting logic, specifically for combined condition code (sCC) operations. The previous implementation, in an effort to recognize more czero sequences, made an ill-advised shortcut by directly modifying existing RTL insn nodes (via PUT_MODE or PUT_CODE) for one of the split operands. This led to functional failures, particularly when a 3-into-2 split occurred, but one of the two resultant insns didn't match. The PUT_CODE change to the IL would persist even if the ov…
For Context
Compilers work by transforming your code through several internal representations. One of these is called Register Transfer Language (RTL), which is a low-level description of instructions. For processors like RISC-V, the compiler often needs to "split" complex instructions into simpler ones. This commit fixes a serious bug in the RISC-V part of GCC related to how it handles these splits, especially when dealing with instructions that combine multiple comparison checks. Previously, the compiler would sometimes try to be clever and directly modify existing parts of the RTL when splitting an instruction. This was problematic because if the split wasn't fully completed or if other parts of the compiler looked at the modified instruction before the split was finalized, it could lead to incorrect machine code. This caused programs to misbehave or entirely fail, as seen with some complex benchmarks. The fix is to always create new RTL components instead of altering existing ones during a sp…