]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
i386: Merge duplicate preferred_for_speed attributes on QImode NDD patterns
authorHongyu Wang <hongyu.wang@intel.com>
Tue, 28 Jul 2026 03:41:37 +0000 (11:41 +0800)
committerHongyu Wang <hongyu.wang@intel.com>
Wed, 29 Jul 2026 02:02:21 +0000 (10:02 +0800)
Several QImode integer patterns has two separate attr "preferred_for_speed"
set, one gating the NDD memory-form alternatives with
TARGET_ENABLE_NDD_MEM, and the existing one is for !TARGET_PARTIAL_REG_STALL.
The later one will make genattrtab regenerates the cond based on
!PARTIAL_REG_STALL only and overrides the TARGET_ENABLE_NDD_MEM, so the NDD
memory alternatives were always preferred for speed regardless of the
X86_TUNE_ENABLE_NDD_MEM enabled or disabled.

Combine both conditions into a single preferred_for_speed cond per
pattern. For *ashlqi3_1 alternative 5 belongs to both sets, so it is
gated on TARGET_ENABLE_NDD_MEM && !TARGET_PARTIAL_REG_STALL.

gcc/ChangeLog:

* config/i386/i386.md (*addqi_1<nf_name>): Merge the two
preferred_for_speed attributes into one.
(*andqi_1<nf_name>): Likewise.
(*andqi_2_maybe_si): Likewise.
(*<code>qi_1<nf_name>): Likewise.
(*notxorqi_1): Likewise.
(*one_cmplqi2_1): Likewise.
(*ashlqi3_1<nf_name>): Likewise.

gcc/testsuite/ChangeLog:

* gcc.target/i386/apx-ndd-mem-tune.c: New test.

gcc/config/i386/i386.md
gcc/testsuite/gcc.target/i386/apx-ndd-mem-tune.c [new file with mode: 0644]

index 230fcb576d02b7c8134fa6bcf1938a0c402940ab..0bfe52c08fa63d235a22dba97d16a6c61726dfda 100644 (file)
     }
 }
   [(set_attr "isa" "*,*,*,*,*,*,apx_ndd,apx_ndd,apx_ndd")
-   (set (attr "preferred_for_speed")
-     (cond [(eq_attr "alternative" "7,8")
-             (symbol_ref "TARGET_ENABLE_NDD_MEM")]
-          (symbol_ref "true")))
    (set (attr "type")
      (cond [(eq_attr "alternative" "5")
               (const_string "lea")
    ;; Potential partial reg stall on alternatives 3 and 4.
    (set (attr "preferred_for_speed")
      (cond [(eq_attr "alternative" "3,4")
-             (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
+             (symbol_ref "!TARGET_PARTIAL_REG_STALL")
+           (eq_attr "alternative" "7,8")
+             (symbol_ref "TARGET_ENABLE_NDD_MEM")]
           (symbol_ref "true")))])
 
 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
    #"
   [(set_attr "type" "alu,alu,alu,alu,alu,alu,msklog")
    (set_attr "isa" "*,*,*,apx_ndd,apx_ndd,apx_ndd,*")
-   (set (attr "preferred_for_speed")
-     (cond [(eq_attr "alternative" "4,5")
-             (symbol_ref "TARGET_ENABLE_NDD_MEM")]
-          (symbol_ref "true")))
    (set_attr "has_nf" "1")
    (set (attr "mode")
        (cond [(eq_attr "alternative" "2")
    ;; Potential partial reg stall on alternative 2.
    (set (attr "preferred_for_speed")
      (cond [(eq_attr "alternative" "2")
-             (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
+             (symbol_ref "!TARGET_PARTIAL_REG_STALL")
+           (eq_attr "alternative" "4,5")
+             (symbol_ref "TARGET_ENABLE_NDD_MEM")]
           (symbol_ref "true")))])
 
 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
 }
   [(set_attr "type" "alu")
    (set_attr "isa" "*,*,*,apx_ndd,apx_ndd,apx_ndd")
-   (set (attr "preferred_for_speed")
-     (cond [(eq_attr "alternative" "4,5")
-             (symbol_ref "TARGET_ENABLE_NDD_MEM")]
-          (symbol_ref "true")))
    (set (attr "mode")
      (cond [(eq_attr "alternative" "3,4,5")
              (const_string "QI")
    ;; Potential partial reg stall on alternative 2.
    (set (attr "preferred_for_speed")
      (cond [(eq_attr "alternative" "2")
-             (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
+             (symbol_ref "!TARGET_PARTIAL_REG_STALL")
+           (eq_attr "alternative" "4,5")
+             (symbol_ref "TARGET_ENABLE_NDD_MEM")]
           (symbol_ref "true")))])
 
 (define_insn "*and<mode>_2"
    <nf_prefix><logic>{b}\t{%2, %1, %0|%0, %1, %2}
    #"
   [(set_attr "isa" "*,*,*,apx_ndd,apx_ndd,apx_ndd,avx512f")
-   (set (attr "preferred_for_speed")
-     (cond [(eq_attr "alternative" "4,5")
-             (symbol_ref "TARGET_ENABLE_NDD_MEM")]
-          (symbol_ref "true")))
    (set_attr "type" "alu,alu,alu,alu,alu,alu,msklog")
    (set_attr "has_nf" "1")
    (set (attr "mode")
    ;; Potential partial reg stall on alternative 2.
    (set (attr "preferred_for_speed")
      (cond [(eq_attr "alternative" "2")
-             (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
+             (symbol_ref "!TARGET_PARTIAL_REG_STALL")
+           (eq_attr "alternative" "4,5")
+             (symbol_ref "TARGET_ENABLE_NDD_MEM")]
           (symbol_ref "true")))])
 
 (define_insn_and_split "*notxorqi_1"
     }
 }
   [(set_attr "isa" "*,*,*,apx_ndd,apx_ndd,apx_ndd,avx512f")
-   (set (attr "preferred_for_speed")
-     (cond [(eq_attr "alternative" "4,5")
-             (symbol_ref "TARGET_ENABLE_NDD_MEM")]
-          (symbol_ref "true")))
    (set_attr "type" "alu,alu,alu,alu,alu,alu,msklog")
    (set (attr "mode")
        (cond [(eq_attr "alternative" "2")
    ;; Potential partial reg stall on alternative 2.
    (set (attr "preferred_for_speed")
      (cond [(eq_attr "alternative" "2")
-             (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
+             (symbol_ref "!TARGET_PARTIAL_REG_STALL")
+           (eq_attr "alternative" "4,5")
+             (symbol_ref "TARGET_ENABLE_NDD_MEM")]
           (symbol_ref "true")))])
 
 ;; convert (sign_extend:WIDE (any_logic:NARROW (memory, immediate)))
    not{b}\t{%1, %0|%0, %1}
    #"
   [(set_attr "isa" "*,*,apx_ndd,apx_ndd,avx512f")
-   (set (attr "preferred_for_speed")
-     (cond [(eq_attr "alternative" "3")
-             (symbol_ref "TARGET_ENABLE_NDD_MEM")]
-          (symbol_ref "true")))
    (set_attr "type" "negnot,negnot,negnot,negnot,msklog")
    (set (attr "mode")
        (cond [(eq_attr "alternative" "1")
    ;; Potential partial reg stall on alternative 1.
    (set (attr "preferred_for_speed")
      (cond [(eq_attr "alternative" "1")
-             (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
+             (symbol_ref "!TARGET_PARTIAL_REG_STALL")
+           (eq_attr "alternative" "3")
+             (symbol_ref "TARGET_ENABLE_NDD_MEM")]
           (symbol_ref "true")))])
 
 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
     }
 }
   [(set_attr "isa" "*,*,*,avx512dq,apx_ndd,apx_ndd")
-   (set (attr "preferred_for_speed")
-     (cond [(eq_attr "alternative" "5")
-             (symbol_ref "TARGET_ENABLE_NDD_MEM")]
-          (symbol_ref "true")))
    (set (attr "type")
      (cond [(eq_attr "alternative" "2")
              (const_string "lea")
        (const_string "*")))
    (set_attr "has_nf" "1")
    (set_attr "mode" "QI,SI,SI,QI,QI,QI")
-   ;; Potential partial reg stall on alternative 1.
+   ;; Potential partial reg stall on alternatives 1, 4 and 5.
    (set (attr "preferred_for_speed")
-     (cond [(eq_attr "alternative" "1,4,5")
+     (cond [(eq_attr "alternative" "5")
+             (symbol_ref "TARGET_ENABLE_NDD_MEM && !TARGET_PARTIAL_REG_STALL")
+           (eq_attr "alternative" "1,4")
              (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
           (symbol_ref "true")))])
 
diff --git a/gcc/testsuite/gcc.target/i386/apx-ndd-mem-tune.c b/gcc/testsuite/gcc.target/i386/apx-ndd-mem-tune.c
new file mode 100644 (file)
index 0000000..5726390
--- /dev/null
@@ -0,0 +1,53 @@
+/* Verify that the memory form of NDD instructions is guarded by the
+   X86_TUNE_ENABLE_NDD_MEM tune properly. The duplicated preferred_for_speed
+   attr will be true when partial_reg_stall enabled for qi patterns, and
+   override the ENABLE_NDD_MEM set at first, so there should be only one attr
+   remaining by combining the two conditions together. */
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-mapxf -march=x86-64 -O2 -mtune-ctrl=partial_reg_stall" } */
+
+unsigned char gc;
+
+unsigned char
+add_qi (unsigned char *p, unsigned char b)
+{
+  unsigned char r = *p + b;
+  gc = r;
+  return r;
+}
+
+unsigned char
+and_qi (unsigned char *p, unsigned char b)
+{
+  unsigned char r = *p & b;
+  gc = r;
+  return r;
+}
+
+unsigned char
+xor_qi (unsigned char *p, unsigned char b)
+{
+  unsigned char r = *p ^ b;
+  gc = r;
+  return r;
+}
+
+unsigned char
+not_qi (unsigned char *p)
+{
+  unsigned char r = ~*p;
+  gc = r;
+  return r;
+}
+
+unsigned char
+shl_qi (unsigned char *p, unsigned char c)
+{
+  unsigned char r = (unsigned char) (*p << c);
+  gc = r;
+  return r;
+}
+
+/* None of the QImode ops above should use the NDD memory-source form
+   when partial_reg_stall && !enable_ndd_mem.  */
+/* { dg-final { scan-assembler-not {b[ \t]+%[a-z0-9]+, \(%[a-z0-9]+\),} } } */