On Tue, Oct 13, 2026 at 11:06 AM Richard Biener
<[email protected]> wrote:
>
> On Tue, Oct 13, 2026 at 10:45 AM Vineet Gupta <[email protected]> wrote:
> >
> > With -ffuse-ops-with-volatile-access general_operand accepts volatile
> > MEMs during combine. For "int a = x; int b = y; return a < b;" with
> > volatile x and y, combine first merges the load of y into the compare
> > and then the load of x, giving (compare (mem/v x) (mem/v y)). The
>
> Why does this pass recog when it later needs reloading?
For some unknown (historical ?) reasons, compare with two memory
operands, is allowed in i386.md. The compiler should not create
invalid instructions that burden LRA unnecessarily, so I'm testing a
patch that simply rejects them. This is a simple defensive target
patch, but it will paper over real problems, addressed in Vineet's
patch.
Uros.
diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc
index a81993c29c5..4125467f10a 100644
--- a/gcc/config/i386/i386-expand.cc
+++ b/gcc/config/i386/i386-expand.cc
@@ -2636,6 +2636,9 @@ ix86_expand_branch (enum rtx_code code, rtx op0, rtx op1,
rtx label)
|| (!uns && !x86_64_general_operand (hi[1], submode)))
hi[1] = force_reg (submode, hi[1]);
+ if (MEM_P (lo[0]) && MEM_P (lo[1]))
+ lo[0] = force_reg (submode, lo[0]);
+
emit_insn (gen_cmp_1 (submode, lo[0], lo[1]));
tmp = gen_rtx_SCRATCH (submode);
@@ -29228,6 +29231,9 @@ ix86_gen_ccmp_next (rtx_insn **prep_seq, rtx_insn
**gen_seq, rtx prev,
return NULL_RTX;
}
+ if (MEM_P (op0) && MEM_P (op1))
+ op0 = force_reg (op_mode, op0);
+
*prep_seq = end_sequence ();
target = gen_rtx_REG (cc_mode, FLAGS_REG);
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index d5b90291fc9..89e6a1a7483 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -1575,7 +1575,8 @@ (define_insn "@ccmp<mode>"
(unspec:CC
[(match_operand:SI 4 "const_0_to_15_operand")]
UNSPEC_APX_DFV)))]
- "TARGET_APX_CCMP"
+ "TARGET_APX_CCMP
+ && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
"@
ctest%C1{<imodesuffix>}\t%G4 %2, %2
ccmp%C1{<imodesuffix>}\t%G4 {%3, %2|%2, %3}
@@ -1625,7 +1626,8 @@ (define_insn "*cmp<mode>_1"
[(set (reg FLAGS_REG)
(compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
(match_operand:SWI 1 "<general_operand>" "<r><i>,<r><m>")))]
- "ix86_match_ccmode (insn, CCmode)"
+ "ix86_match_ccmode (insn, CCmode)
+ && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
"cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
[(set_attr "type" "icmp")
(set_attr "mode" "<MODE>")])
@@ -1636,7 +1638,8 @@ (define_insn "*cmp<mode>_minus_1"
(minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
(match_operand:SWI 1 "<general_operand>" "<r><i>,<r><m>"))
(const_int 0)))]
- "ix86_match_ccmode (insn, CCGOCmode)"
+ "ix86_match_ccmode (insn, CCGOCmode)
+ && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
"cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
[(set_attr "type" "icmp")
(set_attr "mode" "<MODE>")])