https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98683
Bug ID: 98683 Summary: Non-canonical compare produced with the VAX backend Product: gcc Version: 11.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: ma...@linux-mips.org CC: ma...@linux-mips.org Target Milestone: --- Target: vax-*-netbsdelf Due to how operands are presented to the `cbranch*' patterns a non-canonical compare operation might be produced with reload that has an immediate in its first input operand (and a non-immediate second input operand, although forms with two immediate inputs have been also observed). This can be reproduced with the existing 20000422-1.c test case and the `-O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions' options, a set from the usual ones used with regression testing: (jump_insn 549 550 556 99 (set (pc) (if_then_else (ge (const_int 0 [0]) (reg:SI 10 %r10 [orig:188 _138 ] [188])) (label_ref:SI 707) (pc))) ".../gcc/testsuite/gcc.c-torture/execute/20000422-1.c":21:27 521 {*cbranchsi4_ccn} (int_list:REG_BR_PROB 118111604 (nil)) -> 707) which gets split to: (insn 1959 550 1960 99 (set (reg:CCN 16 %psl) (compare:CCN (const_int 0 [0]) (reg:SI 10 %r10 [orig:188 _138 ] [188]))) ".../gcc/testsuite/gcc.c-torture/execute/20000422-1.c":21:27 6 {*cmpsi_ccn} (nil)) (jump_insn 1960 1959 556 99 (set (pc) (if_then_else (ge (reg:CCN 16 %psl) (const_int 0 [0])) (label_ref 707) (pc))) ".../gcc/testsuite/gcc.c-torture/execute/20000422-1.c":21:27 535 {*branch_ccn} (int_list:REG_BR_PROB 118111604 (nil)) -> 707) and ultimately leads to: #(insn 1959 550 1960 (set (reg:CCN 16 %psl) # (compare:CCN (const_int 0 [0]) # (reg:SI 10 %r10 [orig:188 _138 ] [188]))) ".../gcc/testsuite/gcc.c-torture/execute/20000422-1.c":21:27 6 {*cmpsi_ccn} # (nil)) cmpl $0,%r10 # 1959 [c=6] *cmpsi_ccn/1 #(jump_insn 1960 1959 556 (set (pc) # (if_then_else (ge (reg:CCN 16 %psl) # (const_int 0 [0])) # (label_ref 707) # (pc))) ".../gcc/testsuite/gcc.c-torture/execute/20000422-1.c":21:27 535 {*branch_ccn} # (expr_list:REG_DEAD (reg:CCN 16 %psl) # (int_list:REG_BR_PROB 118111604 (nil))) # -> 707) jgeq .L73 # 1960 [c=26] *branch_ccn As observed here this is handled by the backend just fine, however causes the less optimal CMPL instruction to be produced rather than TSTL that has an implicit immediate zero second operand, which could be used if the inputs were swapped. This applies to both integer and FP operations. Currently canonicalization requires that an immediate input operand to to the compare operation has to come as the second one, however there is no such requirement for the `cbranch*' patterns, so the fix would have to be made in the backend, in the relevant splitters, presumably by swapping the operands and using the reverse branch if an immediate is presented as the first input operand. Requiring the first input operand to `cbranch*' to be non-immediate by means of a predicate results in yet worse code being produced as any immediate used is then moved to a register by reload, so this would best be avoided.