i386: Fix mode of ZERO_EXTRACT RTXes, remove ext_register_operand predicate.
authorUros Bizjak <ubizjak@gmail.com>
Thu, 18 Jun 2020 18:12:48 +0000 (20:12 +0200)
committerUros Bizjak <ubizjak@gmail.com>
Thu, 18 Jun 2020 18:12:48 +0000 (20:12 +0200)
The mode of ZERO_EXTRACT RTX should match the mode of its LOC register
operand.  The mode should be HI, SI or DImode to enable combine to synthesize
extractions from HImode and DImode operands, in addition to existing SImode.
Further, these changes tighten allowed modes for extv, extzv and insv
named patterns and finally enable removal of ext_register_operand
special predicate.

2020-18-06  Uroš Bizjak  <ubizjak@gmail.com>

gcc/ChangeLog:

* config/i386/i386.md (*cmpqi_ext<mode>_1): Use SWI248 mode
iterator instead of SImode for ZERO_EXTRACT RTX.  Use SWI248
mode iterator for the first operand of ZERO_EXTRACT RTX.
Change ext_register_operand predicate to register_operand.
Rename from *cmpqi_ext_1.
(*cmpqi_ext<mode>_2): Ditto.  Rename from *cmpqi_ext_2.
(*cmpqi_ext<mode>_3): Ditto.  Rename from *cmpqi_ext_3.
(*cmpqi_ext<mode>_4): Ditto.  Rename from *cmpqi_ext_4.
(cmpi_ext_3): Use HImode instead of SImode for ZERO_EXTRACT RTX.
(*extv<mode>): Use SWI24 mode iterator for the first operand
of ZERO_EXTRACT RTX.  Change ext_register_operand predicate
to register_operand.
(*extzv<mode>): Use SWI248 mode iterator for the first operand
of ZERO_EXTRACT RTX.  Change ext_register_operand predicate
to register_operand.
(*extzvqi): Use SWI248 mode iterator instead of SImode for
ZERO_EXTRACT RTX.  Use SWI248 mode iterator for the first operand
of ZERO_EXTRACT RTX.  Change ext_register_operand predicate to
register_operand.
(*extzvqi_mem_rex64 and corresponding peephole2):  Use SWI248 mode
iterator instead of SImode for ZERO_EXTRACT RTX.  Use SWI248
mode iterator for the first operand of ZERO_EXTRACT RTX.
Change ext_register_operand predicate to register_operand.
(@insv<mode>_1): Use SWI248 mode iterator for the first operand
of ZERO_EXTRACT RTX.  Change ext_register_operand predicate to
register_operand.
(*insvqi_1): Use SWI248 mode iterator instead of SImode
for ZERO_EXTRACT RTX.  Use SWI248 mode iterator for the
first operand of ZERO_EXTRACT RTX.  Change ext_register_operand
predicate to register_operand.
(*insvqi_2): Ditto.
(*insvqi_3): Ditto.
(*insvqi_1_mem_rex64 and corresponding peephole2):  Use SWI248 mode
iterator instead of SImode for ZERO_EXTRACT RTX.  Use SWI248
mode iterator for the first operand of ZERO_EXTRACT RTX.
Change ext_register_operand predicate to register_operand.
(addqi_ext_1): New expander.
(*addqi_ext<mode>_1): Use SWI248 mode iterator instead of SImode
for ZERO_EXTRACT RTX.  Use SWI248 mode iterator for the first
operand of ZERO_EXTRACT RTX.  Change ext_register_operand predicate
to register_operand.  Rename from *addqi_ext_1.
(*addqi_ext<mode>_2): Ditto. Rename from *addqi_ext_2.
(divmodqi4): Use HImode instead of SImode for ZERO_EXTRACT RTX.
(udivmodqi4): Ditto.
(testqi_ext_1): Use HImode instead of SImode for ZERO_EXTRACT RTX.
(*testqi_ext<mode>_1): Use SWI248 mode iterator instead of SImode
for ZERO_EXTRACT RTX.  Use SWI248 mode iterator for the first
operand of ZERO_EXTRACT RTX.  Change ext_register_operand predicate
to register_operand.  Rename from *testqi_ext_1.
(*testqi_ext<mode>_2): Ditto.  Rename from *testqi_ext_2.
(andqi_ext_1): New expander.
(*andqi_ext<mode>_1): Use SWI248 mode iterator instead of SImode
for ZERO_EXTRACT RTX.  Use SWI248 mode iterator for the first
operand of ZERO_EXTRACT RTX.  Change ext_register_operand predicate
to register_operand.  Rename from andqi_ext_1.
(*andqi_ext<mode>_1_cc): Ditto.  Rename from *andqi_ext_1_cc.
(*andqi_ext<mode>_2): Ditto.  Rename from *andqi_ext_2.
(*<code>qi_ext<mode>_1): Ditto.  Rename from *<code>qi_ext_1.
(*<code>qi_ext<mode>_2): Ditto.  Rename from *<code>qi_ext_2.
(xorqi_ext_1_cc): Use HImode instead of SImode for ZERO_EXTRACT RTX.
(*xorqi_ext<mode>_1_cc):  Use SWI248 mode iterator instead of SImode
for ZERO_EXTRACT RTX.  Use SWI248 mode iterator for the first
operand of ZERO_EXTRACT RTX.  Change ext_register_operand predicate
to register_operand.  Rename from *xorqi_ext_1_cc.
* config/i386/i386-expand.c (ix86_split_idivmod): Emit ZERO_EXTRACT
in mode, matching its first operand.
(promote_duplicated_reg): Update for renamed insv<mode>_1.
* config/i386/predicates.md (ext_register_operand): Remove predicate.

gcc/testsuite/ChangeLog:

* gcc.target/i386/pr78904-1a.c: New test.
* gcc.target/i386/pr78904-1b.c: Ditto.
* gcc.target/i386/pr78904-2a.c: Ditto.
* gcc.target/i386/pr78904-2b.c: Ditto.
* gcc.target/i386/pr78904-3a.c: Ditto.
* gcc.target/i386/pr78904-3b.c: Ditto.
* gcc.target/i386/pr78904-4a.c: Ditto.
* gcc.target/i386/pr78904-4b.c: Ditto.
* gcc.target/i386/pr78904-5a.c: Ditto.
* gcc.target/i386/pr78904-5b.c: Ditto.
* gcc.target/i386/pr78904-6a.c: Ditto.
* gcc.target/i386/pr78904-6b.c: Ditto.
* gcc.target/i386/pr78967-1a.c: Ditto.
* gcc.target/i386/pr78967-1b.c: Ditto.
* gcc.target/i386/pr78967-2a.c: Ditto.
* gcc.target/i386/pr78967-2b.c: Ditto.

19 files changed:
gcc/config/i386/i386-expand.c
gcc/config/i386/i386.md
gcc/config/i386/predicates.md
gcc/testsuite/gcc.target/i386/pr78904-1a.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr78904-1b.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr78904-2a.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr78904-2b.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr78904-3a.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr78904-3b.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr78904-4a.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr78904-4b.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr78904-5a.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr78904-5b.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr78904-6a.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr78904-6b.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr78967-1a.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr78967-1b.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr78967-2a.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr78967-2b.c [new file with mode: 0644]

index d7077980f9b048e6850afba621ab66dfcd1bef7c..d81dd73f034d179ee1aa993bd01e4ad01e9506fb 100644 (file)
@@ -1179,9 +1179,8 @@ ix86_split_idivmod (machine_mode mode, rtx operands[],
   JUMP_LABEL (insn) = qimode_label;
 
   /* Generate original signed/unsigned divimod.  */
-  div = gen_divmod4_1 (operands[0], operands[1],
-                      operands[2], operands[3]);
-  emit_insn (div);
+  emit_insn (gen_divmod4_1 (operands[0], operands[1],
+                           operands[2], operands[3]));
 
   /* Branch to the end.  */
   emit_jump_insn (gen_jump (end_label));
@@ -1215,18 +1214,10 @@ ix86_split_idivmod (machine_mode mode, rtx operands[],
     }
 
   /* Extract remainder from AH.  */
-  tmp1 = gen_rtx_ZERO_EXTRACT (GET_MODE (operands[1]),
-                              tmp0, GEN_INT (8), GEN_INT (8));
-  if (REG_P (operands[1]))
-    insn = emit_move_insn (operands[1], tmp1);
-  else
-    {
-      /* Need a new scratch register since the old one has result
-        of 8bit divide.  */
-      scratch = gen_reg_rtx (GET_MODE (operands[1]));
-      emit_move_insn (scratch, tmp1);
-      insn = emit_move_insn (operands[1], scratch);
-    }
+  scratch = gen_lowpart (GET_MODE (operands[1]), scratch);
+  tmp1 = gen_rtx_ZERO_EXTRACT (GET_MODE (operands[1]), scratch,
+                              GEN_INT (8), GEN_INT (8));
+  insn = emit_move_insn (operands[1], tmp1);
   set_unique_reg_note (insn, REG_EQUAL, mod);
 
   /* Zero extend quotient from AL.  */
@@ -7060,10 +7051,7 @@ promote_duplicated_reg (machine_mode mode, rtx val)
       rtx reg = convert_modes (mode, QImode, val, true);
 
       if (!TARGET_PARTIAL_REG_STALL)
-       if (mode == SImode)
-         emit_insn (gen_insvsi_1 (reg, reg));
-       else
-         emit_insn (gen_insvdi_1 (reg, reg));
+       emit_insn (gen_insv_1 (mode, reg, reg));
       else
        {
          tmp = expand_simple_binop (mode, ASHIFT, reg, GEN_INT (8),
index 4d455584f09424e602459e5ced1890e5e1ab9f26..d0ecd9eb6cf2ca46d834be8fbadba0a866a0b2b9 100644 (file)
   [(set_attr "type" "icmp")
    (set_attr "mode" "<MODE>")])
 
-(define_insn "*cmpqi_ext_1"
+(define_insn "*cmpqi_ext<mode>_1"
   [(set (reg FLAGS_REG)
        (compare
          (match_operand:QI 0 "nonimmediate_operand" "QBc,m")
          (subreg:QI
-           (zero_extract:SI
-             (match_operand 1 "ext_register_operand" "Q,Q")
+           (zero_extract:SWI248
+             (match_operand:SWI248 1 "register_operand" "Q,Q")
              (const_int 8)
              (const_int 8)) 0)))]
   "ix86_match_ccmode (insn, CCmode)"
    (set_attr "type" "icmp")
    (set_attr "mode" "QI")])
 
-(define_insn "*cmpqi_ext_2"
+(define_insn "*cmpqi_ext<mode>_2"
   [(set (reg FLAGS_REG)
        (compare
          (subreg:QI
-           (zero_extract:SI
-             (match_operand 0 "ext_register_operand" "Q")
+           (zero_extract:SWI248
+             (match_operand:SWI248 0 "register_operand" "Q")
              (const_int 8)
              (const_int 8)) 0)
          (match_operand:QI 1 "const0_operand")))]
   [(set (reg:CC FLAGS_REG)
        (compare:CC
          (subreg:QI
-           (zero_extract:SI
-             (match_operand 0 "ext_register_operand")
+           (zero_extract:HI
+             (match_operand:HI 0 "register_operand")
              (const_int 8)
              (const_int 8)) 0)
          (match_operand:QI 1 "const_int_operand")))])
 
-(define_insn "*cmpqi_ext_3"
+(define_insn "*cmpqi_ext<mode>_3"
   [(set (reg FLAGS_REG)
        (compare
          (subreg:QI
-           (zero_extract:SI
-             (match_operand 0 "ext_register_operand" "Q,Q")
+           (zero_extract:SWI248
+             (match_operand:SWI248 0 "register_operand" "Q,Q")
              (const_int 8)
              (const_int 8)) 0)
          (match_operand:QI 1 "general_operand" "QnBc,m")))]
    (set_attr "type" "icmp")
    (set_attr "mode" "QI")])
 
-(define_insn "*cmpqi_ext_4"
+(define_insn "*cmpqi_ext<mode>_4"
   [(set (reg FLAGS_REG)
        (compare
          (subreg:QI
-           (zero_extract:SI
-             (match_operand 0 "ext_register_operand" "Q")
+           (zero_extract:SWI248
+             (match_operand:SWI248 0 "register_operand" "Q")
              (const_int 8)
              (const_int 8)) 0)
          (subreg:QI
-           (zero_extract:SI
-             (match_operand 1 "ext_register_operand" "Q")
+           (zero_extract:SWI248
+             (match_operand:SWI248 1 "register_operand" "Q")
              (const_int 8)
              (const_int 8)) 0)))]
   "ix86_match_ccmode (insn, CCmode)"
 
 (define_insn "*extv<mode>"
   [(set (match_operand:SWI24 0 "register_operand" "=R")
-       (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
+       (sign_extract:SWI24 (match_operand:SWI24 1 "register_operand" "Q")
                            (const_int 8)
                            (const_int 8)))]
   ""
 (define_insn "*extzvqi_mem_rex64"
   [(set (match_operand:QI 0 "norex_memory_operand" "=Bn")
        (subreg:QI
-         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
-                          (const_int 8)
-                          (const_int 8)) 0))]
+         (zero_extract:SWI248
+           (match_operand:SWI248 1 "register_operand" "Q")
+           (const_int 8)
+           (const_int 8)) 0))]
   "TARGET_64BIT && reload_completed"
   "mov{b}\t{%h1, %0|%0, %h1}"
   [(set_attr "type" "imov")
 
 (define_insn "*extzv<mode>"
   [(set (match_operand:SWI248 0 "register_operand" "=R")
-       (zero_extract:SWI248 (match_operand 1 "ext_register_operand" "Q")
+       (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand" "Q")
                             (const_int 8)
                             (const_int 8)))]
   ""
 (define_insn "*extzvqi"
   [(set (match_operand:QI 0 "nonimmediate_operand" "=QBc,?R,m")
        (subreg:QI
-         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
-                          (const_int 8)
-                          (const_int 8)) 0))]
+         (zero_extract:SWI248
+           (match_operand:SWI248 1 "register_operand" "Q,Q,Q")
+           (const_int 8)
+           (const_int 8)) 0))]
   ""
 {
   switch (get_attr_type (insn))
 (define_peephole2
   [(set (match_operand:QI 0 "register_operand")
        (subreg:QI
-         (zero_extract:SI (match_operand 1 "ext_register_operand")
-                          (const_int 8)
-                          (const_int 8)) 0))
+         (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand")
+                              (const_int 8)
+                              (const_int 8)) 0))
    (set (match_operand:QI 2 "norex_memory_operand") (match_dup 0))]
   "TARGET_64BIT
    && peep2_reg_dead_p (2, operands[0])"
   [(set (match_dup 2)
        (subreg:QI
-         (zero_extract:SI (match_dup 1)
-                          (const_int 8)
-                          (const_int 8)) 0))])
+         (zero_extract:SWI248 (match_dup 1)
+                              (const_int 8)
+                              (const_int 8)) 0))])
 
 (define_expand "insv<mode>"
   [(set (zero_extract:SWI248 (match_operand:SWI248 0 "register_operand")
   else
     dst = operands[0];
 
-  emit_insn (gen_insv<mode>_1 (dst, operands[3]));
+  emit_insn (gen_insv_1 (<MODE>mode, dst, operands[3]));
 
   /* Fix up the destination if needed.  */
   if (dst != operands[0])
 })
 
 (define_insn "*insvqi_1_mem_rex64"
-  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
-                        (const_int 8)
-                        (const_int 8))
-       (subreg:SI
+  [(set (zero_extract:SWI248
+         (match_operand:SWI248 0 "register_operand" "+Q")
+         (const_int 8)
+         (const_int 8))
+       (subreg:SWI248
          (match_operand:QI 1 "norex_memory_operand" "Bn") 0))]
   "TARGET_64BIT && reload_completed"
   "mov{b}\t{%1, %h0|%h0, %1}"
   [(set_attr "type" "imov")
    (set_attr "mode" "QI")])
 
-(define_insn "insv<mode>_1"
-  [(set (zero_extract:SWI248 (match_operand 0 "ext_register_operand" "+Q,Q")
-                            (const_int 8)
-                            (const_int 8))
+(define_insn "@insv<mode>_1"
+  [(set (zero_extract:SWI248
+         (match_operand:SWI248 0 "register_operand" "+Q,Q")
+         (const_int 8)
+         (const_int 8))
        (match_operand:SWI248 1 "general_operand" "QnBc,m"))]
   ""
 {
    (set_attr "mode" "QI")])
 
 (define_insn "*insvqi_1"
-  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
-                        (const_int 8)
-                        (const_int 8))
-       (subreg:SI
+  [(set (zero_extract:SWI248
+         (match_operand:SWI248 0 "register_operand" "+Q,Q")
+         (const_int 8)
+         (const_int 8))
+       (subreg:SWI248
          (match_operand:QI 1 "general_operand" "QnBc,m") 0))]
   ""
   "mov{b}\t{%1, %h0|%h0, %1}"
 (define_peephole2
   [(set (match_operand:QI 0 "register_operand")
        (match_operand:QI 1 "norex_memory_operand"))
-   (set (zero_extract:SI (match_operand 2 "ext_register_operand")
-                        (const_int 8)
-                        (const_int 8))
-       (subreg:SI (match_dup 0) 0))]
+   (set (zero_extract:SWI248 (match_operand:SWI248 2 "register_operand")
+                            (const_int 8)
+                            (const_int 8))
+       (subreg:SWI248 (match_dup 0) 0))]
   "TARGET_64BIT
    && peep2_reg_dead_p (2, operands[0])"
-  [(set (zero_extract:SI (match_dup 2)
-                        (const_int 8)
-                        (const_int 8))
-          (subreg:SI (match_dup 1) 0))])
+  [(set (zero_extract:SWI248 (match_dup 2)
+                            (const_int 8)
+                            (const_int 8))
+          (subreg:SWI248 (match_dup 1) 0))])
 
 (define_code_iterator any_extract [sign_extract zero_extract])
 
 (define_insn "*insvqi_2"
-  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
-                        (const_int 8)
-                        (const_int 8))
-       (any_extract:SI (match_operand 1 "ext_register_operand" "Q")
-                       (const_int 8)
-                       (const_int 8)))]
+  [(set (zero_extract:SWI248
+         (match_operand:SWI248 0 "register_operand" "+Q")
+         (const_int 8)
+         (const_int 8))
+       (any_extract:SWI248
+         (match_operand:SWI248 1 "register_operand" "Q")
+         (const_int 8)
+         (const_int 8)))]
   ""
   "mov{b}\t{%h1, %h0|%h0, %h1}"
   [(set_attr "type" "imov")
    (set_attr "mode" "QI")])
 
 (define_insn "*insvqi_3"
-  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
-                        (const_int 8)
-                        (const_int 8))
-       (any_shiftrt:SI (match_operand:SI 1 "register_operand" "Q")
-                       (const_int 8)))]
+  [(set (zero_extract:SWI248
+         (match_operand:SWI248 0 "register_operand" "+Q")
+         (const_int 8)
+         (const_int 8))
+       (any_shiftrt:SWI248
+         (match_operand:SWI248 1 "register_operand" "Q")
+         (const_int 8)))]
   ""
   "mov{b}\t{%h1, %h0|%h0, %h1}"
   [(set_attr "type" "imov")
        (const_string "*")))
    (set_attr "mode" "<MODE>")])
 
-(define_insn "addqi_ext_1"
-  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
-                        (const_int 8)
-                        (const_int 8))
-       (subreg:SI
+(define_expand "addqi_ext_1"
+  [(parallel
+     [(set (zero_extract:HI (match_operand:HI 0 "register_operand")
+                           (const_int 8)
+                           (const_int 8))
+          (subreg:HI
+            (plus:QI
+              (subreg:QI
+                (zero_extract:HI (match_operand:HI 1 "register_operand")
+                                 (const_int 8)
+                                 (const_int 8)) 0)
+              (match_operand:QI 2 "const_int_operand")) 0))
+      (clobber (reg:CC FLAGS_REG))])])
+
+(define_insn "*addqi_ext<mode>_1"
+  [(set (zero_extract:SWI248
+         (match_operand:SWI248 0 "register_operand" "+Q,Q")
+         (const_int 8)
+         (const_int 8))
+       (subreg:SWI248
          (plus:QI
            (subreg:QI
-             (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
-                              (const_int 8)
-                              (const_int 8)) 0)
+             (zero_extract:SWI248
+               (match_operand:SWI248 1 "register_operand" "0,0")
+               (const_int 8)
+               (const_int 8)) 0)
            (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
    (clobber (reg:CC FLAGS_REG))]
   "/* FIXME: without this LRA can't reload this pattern, see PR82524.  */
        (const_string "alu")))
    (set_attr "mode" "QI")])
 
-(define_insn "*addqi_ext_2"
-  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
-                        (const_int 8)
-                        (const_int 8))
-       (subreg:SI
+(define_insn "*addqi_ext<mode>_2"
+  [(set (zero_extract:SWI248
+         (match_operand:SWI248 0 "register_operand" "+Q")
+         (const_int 8)
+         (const_int 8))
+       (subreg:SWI248
          (plus:QI
            (subreg:QI
-             (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
-                              (const_int 8)
-                              (const_int 8)) 0)
+             (zero_extract:SWI248
+               (match_operand:SWI248 1 "register_operand" "%0")
+               (const_int 8)
+               (const_int 8)) 0)
            (subreg:QI
-             (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
-                              (const_int 8)
-                              (const_int 8)) 0)) 0))
+             (zero_extract:SWI248
+               (match_operand:SWI248 2 "register_operand" "Q")
+               (const_int 8)
+               (const_int 8)) 0)) 0))
   (clobber (reg:CC FLAGS_REG))]
   "/* FIXME: without this LRA can't reload this pattern, see PR82524.  */
    rtx_equal_p (operands[0], operands[1])
   emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
 
   /* Extract remainder from AH.  */
-  tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
-  tmp1 = lowpart_subreg (QImode, tmp1, SImode);
+  tmp1 = gen_rtx_ZERO_EXTRACT (HImode, tmp0, GEN_INT (8), GEN_INT (8));
+  tmp1 = lowpart_subreg (QImode, tmp1, HImode);
   rtx_insn *insn = emit_move_insn (operands[3], tmp1);
 
   mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
   emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
 
   /* Extract remainder from AH.  */
-  tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
-  tmp1 = lowpart_subreg (QImode, tmp1, SImode);
+  tmp1 = gen_rtx_ZERO_EXTRACT (HImode, tmp0, GEN_INT (8), GEN_INT (8));
+  tmp1 = lowpart_subreg (QImode, tmp1, HImode);
   rtx_insn *insn = emit_move_insn (operands[3], tmp1);
 
   mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
        (compare:CCNO
          (and:QI
            (subreg:QI
-             (zero_extract:SI (match_operand 0 "ext_register_operand")
-                              (const_int 8)
-                              (const_int 8)) 0)
-             (match_operand 1 "const_int_operand"))
+             (zero_extract:HI
+               (match_operand:HI 0 "register_operand")
+               (const_int 8)
+               (const_int 8)) 0)
+             (match_operand:QI 1 "const_int_operand"))
          (const_int 0)))])
 
-(define_insn "*testqi_ext_1"
+(define_insn "*testqi_ext<mode>_1"
   [(set (reg FLAGS_REG)
        (compare
          (and:QI
            (subreg:QI
-             (zero_extract:SI (match_operand 0 "ext_register_operand" "Q,Q")
-                              (const_int 8)
-                              (const_int 8)) 0)
+             (zero_extract:SWI248
+               (match_operand:SWI248 0 "register_operand" "Q,Q")
+               (const_int 8)
+               (const_int 8)) 0)
            (match_operand:QI 1 "general_operand" "QnBc,m"))
          (const_int 0)))]
   "ix86_match_ccmode (insn, CCNOmode)"
    (set_attr "type" "test")
    (set_attr "mode" "QI")])
 
-(define_insn "*testqi_ext_2"
+(define_insn "*testqi_ext<mode>_2"
   [(set (reg FLAGS_REG)
        (compare
          (and:QI
            (subreg:QI
-             (zero_extract:SI (match_operand 0 "ext_register_operand" "Q")
-                              (const_int 8)
-                              (const_int 8)) 0)
+             (zero_extract:SWI248
+               (match_operand:SWI248 0 "register_operand" "Q")
+               (const_int 8)
+               (const_int 8)) 0)
            (subreg:QI
-             (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
-                              (const_int 8)
-                              (const_int 8)) 0))
+             (zero_extract:SWI248
+               (match_operand:SWI248 1 "register_operand" "Q")
+               (const_int 8)
+               (const_int 8)) 0))
          (const_int 0)))]
   "ix86_match_ccmode (insn, CCNOmode)"
   "test{b}\t{%h1, %h0|%h0, %h1}"
   [(set_attr "type" "alu")
    (set_attr "mode" "<MODE>")])
 
-(define_insn "andqi_ext_1"
-  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
-                        (const_int 8)
-                        (const_int 8))
-       (subreg:SI
+(define_expand "andqi_ext_1"
+  [(parallel
+     [(set (zero_extract:HI (match_operand:HI 0 "register_operand")
+                           (const_int 8)
+                           (const_int 8))
+          (subreg:HI
+            (and:QI
+              (subreg:QI
+                (zero_extract:HI (match_operand:HI 1 "register_operand")
+                                 (const_int 8)
+                                 (const_int 8)) 0)
+              (match_operand:QI 2 "const_int_operand")) 0))
+      (clobber (reg:CC FLAGS_REG))])])
+
+(define_insn "*andqi_ext<mode>_1"
+  [(set (zero_extract:SWI248
+         (match_operand:SWI248 0 "register_operand" "+Q,Q")
+         (const_int 8)
+         (const_int 8))
+       (subreg:SWI248
          (and:QI
            (subreg:QI
-             (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
-                              (const_int 8)
-                              (const_int 8)) 0)
+             (zero_extract:SWI248
+               (match_operand:SWI248 1 "register_operand" "0,0")
+               (const_int 8)
+               (const_int 8)) 0)
            (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
    (clobber (reg:CC FLAGS_REG))]
   "/* FIXME: without this LRA can't reload this pattern, see PR82524.  */
 
 ;; Generated by peephole translating test to and.  This shows up
 ;; often in fp comparisons.
-(define_insn "*andqi_ext_1_cc"
+(define_insn "*andqi_ext<mode>_1_cc"
   [(set (reg FLAGS_REG)
        (compare
          (and:QI
            (subreg:QI
-             (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
-                              (const_int 8)
-                              (const_int 8)) 0)
+             (zero_extract:SWI248
+               (match_operand:SWI248 1 "register_operand" "0,0")
+               (const_int 8)
+               (const_int 8)) 0)
            (match_operand:QI 2 "general_operand" "QnBc,m"))
          (const_int 0)))
-   (set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
-                        (const_int 8)
-                        (const_int 8))
-       (subreg:SI
+   (set (zero_extract:SWI248
+         (match_operand:SWI248 0 "register_operand" "+Q,Q")
+         (const_int 8)
+         (const_int 8))
+       (subreg:SWI248
          (and:QI
            (subreg:QI
-             (zero_extract:SI (match_dup 1)
-                              (const_int 8)
-                              (const_int 8)) 0)
+             (zero_extract:SWI248
+               (match_dup 1)
+               (const_int 8)
+               (const_int 8)) 0)
            (match_dup 2)) 0))]
   "ix86_match_ccmode (insn, CCNOmode)
    /* FIXME: without this LRA can't reload this pattern, see PR82524.  */
    (set_attr "type" "alu")
    (set_attr "mode" "QI")])
 
-(define_insn "*andqi_ext_2"
-  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
-                        (const_int 8)
-                        (const_int 8))
-       (subreg:SI
+(define_insn "*andqi_ext<mode>_2"
+  [(set (zero_extract:SWI248
+         (match_operand:SWI248 0 "register_operand" "+Q")
+         (const_int 8)
+         (const_int 8))
+       (subreg:SWI248
          (and:QI
            (subreg:QI
-             (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
-                              (const_int 8)
-                              (const_int 8)) 0)
+             (zero_extract:SWI248
+               (match_operand:SWI248 1 "register_operand" "%0")
+               (const_int 8)
+               (const_int 8)) 0)
            (subreg:QI
-             (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
-                              (const_int 8)
-                              (const_int 8)) 0)) 0))
+             (zero_extract:SWI248
+               (match_operand:SWI248 2 "register_operand" "Q")
+               (const_int 8)
+               (const_int 8)) 0)) 0))
    (clobber (reg:CC FLAGS_REG))]
   "/* FIXME: without this LRA can't reload this pattern, see PR82524.  */
    rtx_equal_p (operands[0], operands[1])
   [(set_attr "type" "alu")
    (set_attr "mode" "<MODE>")])
 
-(define_insn "*<code>qi_ext_1"
-  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
-                        (const_int 8)
-                        (const_int 8))
-       (subreg:SI
+(define_insn "*<code>qi_ext<mode>_1"
+  [(set (zero_extract:SWI248
+         (match_operand:SWI248 0 "register_operand" "+Q,Q")
+         (const_int 8)
+         (const_int 8))
+       (subreg:SWI248
          (any_or:QI
            (subreg:QI
-             (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
-                              (const_int 8)
-                              (const_int 8)) 0)
+             (zero_extract:SWI248
+               (match_operand:SWI248 1 "register_operand" "0,0")
+               (const_int 8)
+               (const_int 8)) 0)
            (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
    (clobber (reg:CC FLAGS_REG))]
   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
    (set_attr "type" "alu")
    (set_attr "mode" "QI")])
 
-(define_insn "*<code>qi_ext_2"
-  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
-                        (const_int 8)
-                        (const_int 8))
-       (subreg:SI
+(define_insn "*<code>qi_ext<mode>_2"
+  [(set (zero_extract:SWI248
+         (match_operand:SWI248 0 "register_operand" "+Q")
+         (const_int 8)
+         (const_int 8))
+       (subreg:SWI248
          (any_or:QI
            (subreg:QI
-             (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
-                              (const_int 8)
-                              (const_int 8)) 0)
+             (zero_extract:SWI248
+               (match_operand:SWI248 1 "register_operand" "%0")
+               (const_int 8)
+               (const_int 8)) 0)
            (subreg:QI
-             (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
-                              (const_int 8)
-                              (const_int 8)) 0)) 0))
+             (zero_extract:SWI248
+               (match_operand:SWI248 2 "register_operand" "Q")
+               (const_int 8)
+               (const_int 8)) 0)) 0))
    (clobber (reg:CC FLAGS_REG))]
   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
    /* FIXME: without this LRA can't reload this pattern, see PR82524.  */
 })
 
 (define_expand "xorqi_ext_1_cc"
-  [(parallel [
-     (set (reg:CCNO FLAGS_REG)
-         (compare:CCNO
-           (xor:QI
-             (subreg:QI
-               (zero_extract:SI (match_operand 1 "ext_register_operand")
-                                (const_int 8)
-                                (const_int 8)) 0)
-             (match_operand 2 "const_int_operand"))
-           (const_int 0)))
-     (set (zero_extract:SI (match_operand 0 "ext_register_operand")
-                          (const_int 8)
-                          (const_int 8))
-         (subreg:SI
-           (xor:QI
-             (subreg:QI
-               (zero_extract:SI (match_dup 1)
-                                (const_int 8)
-                                (const_int 8)) 0)
-           (match_dup 2)) 0))])])
-
-(define_insn "*xorqi_ext_1_cc"
+  [(parallel
+     [(set (reg:CCNO FLAGS_REG)
+          (compare:CCNO
+            (xor:QI
+              (subreg:QI
+                (zero_extract:HI (match_operand:HI 1 "register_operand")
+                                 (const_int 8)
+                                 (const_int 8)) 0)
+              (match_operand:QI 2 "const_int_operand"))
+            (const_int 0)))
+      (set (zero_extract:HI (match_operand:HI 0 "register_operand")
+                           (const_int 8)
+                           (const_int 8))
+          (subreg:HI
+            (xor:QI
+              (subreg:QI
+                (zero_extract:HI (match_dup 1)
+                                 (const_int 8)
+                                 (const_int 8)) 0)
+            (match_dup 2)) 0))])])
+
+(define_insn "*xorqi_ext<mode>_1_cc"
   [(set (reg FLAGS_REG)
        (compare
          (xor:QI
            (subreg:QI
-             (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
-                              (const_int 8)
-                              (const_int 8)) 0)
+             (zero_extract:SWI248
+               (match_operand:SWI248 1 "register_operand" "0,0")
+               (const_int 8)
+               (const_int 8)) 0)
            (match_operand:QI 2 "general_operand" "QnBc,m"))
          (const_int 0)))
-   (set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
-                        (const_int 8)
-                        (const_int 8))
-       (subreg:SI
+   (set (zero_extract:SWI248
+         (match_operand:SWI248 0 "register_operand" "+Q,Q")
+         (const_int 8)
+         (const_int 8))
+       (subreg:SWI248
          (xor:QI
            (subreg:QI
-             (zero_extract:SI (match_dup 1)
-                              (const_int 8)
-                              (const_int 8)) 0)
+             (zero_extract:SWI248
+               (match_dup 1)
+               (const_int 8)
+               (const_int 8)) 0)
          (match_dup 2)) 0))]
   "ix86_match_ccmode (insn, CCNOmode)
    /* FIXME: without this LRA can't reload this pattern, see PR82524.  */
        (match_operator 1 "compare_operator"
          [(and:QI
             (subreg:QI
-              (zero_extract:SI (match_operand 2 "QIreg_operand")
-                               (const_int 8)
-                               (const_int 8)) 0)
+              (zero_extract:SWI248 (match_operand:SWI248 2 "QIreg_operand")
+                                   (const_int 8)
+                                   (const_int 8)) 0)
             (match_operand 3 "const_int_operand"))
           (const_int 0)]))]
   "! TARGET_PARTIAL_REG_STALL
           (match_op_dup 1
             [(and:QI
                (subreg:QI
-                 (zero_extract:SI (match_dup 2)
-                                  (const_int 8)
-                                  (const_int 8)) 0)
+                 (zero_extract:SWI248 (match_dup 2)
+                                      (const_int 8)
+                                      (const_int 8)) 0)
                (match_dup 3))
              (const_int 0)]))
-      (set (zero_extract:SI (match_dup 2)
-                           (const_int 8)
-                           (const_int 8))
-          (subreg:SI
+      (set (zero_extract:SWI248 (match_dup 2)
+                               (const_int 8)
+                               (const_int 8))
+          (subreg:SWI248
             (and:QI
               (subreg:QI
-                (zero_extract:SI (match_dup 2)
-                                 (const_int 8)
-                                 (const_int 8)) 0)
+                (zero_extract:SWI248 (match_dup 2)
+                                     (const_int 8)
+                                     (const_int 8)) 0)
               (match_dup 3)) 0))])])
 
 ;; Don't do logical operations with memory inputs.
index 8d8bcb1a765b2c8af22c0a087d2a1faffbd9332c..07e69d555c02618c53820931d7c45fe454cbafa0 100644 (file)
   (and (match_code "reg")
        (match_test "REGNO (op) == FLAGS_REG")))
 
-;; Match a DI, SI or HImode register for a zero_extract.
-(define_special_predicate "ext_register_operand"
-  (and (match_operand 0 "register_operand")
-       (ior (and (match_test "TARGET_64BIT")
-                (match_test "GET_MODE (op) == DImode"))
-           (match_test "GET_MODE (op) == SImode")
-           (match_test "GET_MODE (op) == HImode"))))
-
 ;; Match a DI, SI, HI or QImode nonimmediate_operand.
 (define_special_predicate "int_nonimmediate_operand"
   (and (match_operand 0 "nonimmediate_operand")
diff --git a/gcc/testsuite/gcc.target/i386/pr78904-1a.c b/gcc/testsuite/gcc.target/i386/pr78904-1a.c
new file mode 100644 (file)
index 0000000..7746477
--- /dev/null
@@ -0,0 +1,47 @@
+/* PR target/78904 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -masm=att" } */
+/* { dg-final { scan-assembler-not "movzbl" } } */
+/* { dg-final { scan-assembler-not "movb" } } */
+
+struct S1
+{
+  unsigned char pad1;
+  unsigned char val;
+};
+
+struct S1 test_and (struct S1 a, struct S1 b)
+{
+  a.val &= b.val;
+
+  return a;
+}
+
+/* { dg-final { scan-assembler "\[ \t\]andb" } } */
+
+struct S1 test_or (struct S1 a, struct S1 b)
+{
+  a.val |= b.val;
+
+  return a;
+}
+
+/* { dg-final { scan-assembler "\[ \t\]orb" } } */
+
+struct S1 test_xor (struct S1 a, struct S1 b)
+{
+  a.val ^= b.val;
+
+  return a;
+}
+
+/* { dg-final { scan-assembler "\[ \t\]xorb" } } */
+
+struct S1 test_add (struct S1 a, struct S1 b)
+{
+  a.val += b.val;
+
+  return a;
+}
+
+/* { dg-final { scan-assembler "\[ \t\]addb" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr78904-1b.c b/gcc/testsuite/gcc.target/i386/pr78904-1b.c
new file mode 100644 (file)
index 0000000..20b6772
--- /dev/null
@@ -0,0 +1,49 @@
+/* PR target/78904 */
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -masm=att" } */
+/* { dg-final { scan-assembler-not "movzbl" } } */
+/* { dg-final { scan-assembler-not "movb" } } */
+
+struct S1
+{
+  unsigned char pad1;
+  unsigned char val;
+  unsigned short pad2;
+  unsigned int pad3;
+};
+
+struct S1 test_and (struct S1 a, struct S1 b)
+{
+  a.val &= b.val;
+
+  return a;
+}
+
+/* { dg-final { scan-assembler "\[ \t\]andb" } } */
+
+struct S1 test_or (struct S1 a, struct S1 b)
+{
+  a.val |= b.val;
+
+  return a;
+}
+
+/* { dg-final { scan-assembler "\[ \t\]orb" } } */
+
+struct S1 test_xor (struct S1 a, struct S1 b)
+{
+  a.val ^= b.val;
+
+  return a;
+}
+
+/* { dg-final { scan-assembler "\[ \t\]xorb" } } */
+
+struct S1 test_add (struct S1 a, struct S1 b)
+{
+  a.val += b.val;
+
+  return a;
+}
+
+/* { dg-final { scan-assembler "\[ \t\]addb" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr78904-2a.c b/gcc/testsuite/gcc.target/i386/pr78904-2a.c
new file mode 100644 (file)
index 0000000..41eaa25
--- /dev/null
@@ -0,0 +1,48 @@
+/* PR target/78904 */
+/* { dg-do compile } */
+/* { dg-require-effective-target nonpic } */
+/* { dg-options "-O2 -masm=att" } */
+
+struct S1
+{
+  unsigned char pad1;
+  unsigned char val;
+};
+
+extern struct S1 t;
+
+struct S1 test_and (struct S1 a)
+{
+  a.val &= t.val;
+
+  return a;
+}
+
+/* { dg-final { scan-assembler "\[ \t\]andb\[ \t\]+t\[^\n\r]*, %.h" } } */
+
+struct S1 test_or (struct S1 a)
+{
+  a.val |= t.val;
+
+  return a;
+}
+
+/* { dg-final { scan-assembler "\[ \t\]orb\[ \t\]+t\[^\n\r]*, %.h" } } */
+
+struct S1 test_xor (struct S1 a)
+{
+  a.val ^= t.val;
+
+  return a;
+}
+
+/* { dg-final { scan-assembler "\[ \t\]xorb\[ \t\]+t\[^\n\r]*, %.h" } } */
+
+struct S1 test_add (struct S1 a)
+{
+  a.val += t.val;
+
+  return a;
+}
+
+/* { dg-final { scan-assembler "\[ \t\]addb\[ \t\]+t\[^\n\r]*, %.h" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr78904-2b.c b/gcc/testsuite/gcc.target/i386/pr78904-2b.c
new file mode 100644 (file)
index 0000000..23e975a
--- /dev/null
@@ -0,0 +1,50 @@
+/* PR target/78904 */
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-require-effective-target nonpic } */
+/* { dg-options "-O2 -masm=att" } */
+
+struct S1
+{
+  unsigned char pad1;
+  unsigned char val;
+  unsigned short pad2;
+  unsigned int pad3;
+};
+
+extern struct S1 t;
+
+struct S1 test_and (struct S1 a)
+{
+  a.val &= t.val;
+
+  return a;
+}
+
+/* { dg-final { scan-assembler "\[ \t\]andb\[ \t\]+t\[^\n\r]*, %.h" } } */
+
+struct S1 test_or (struct S1 a)
+{
+  a.val |= t.val;
+
+  return a;
+}
+
+/* { dg-final { scan-assembler "\[ \t\]orb\[ \t\]+t\[^\n\r]*, %.h" } } */
+
+struct S1 test_xor (struct S1 a)
+{
+  a.val ^= t.val;
+
+  return a;
+}
+
+/* { dg-final { scan-assembler "\[ \t\]xorb\[ \t\]+t\[^\n\r]*, %.h" } } */
+
+struct S1 test_add (struct S1 a)
+{
+  a.val += t.val;
+
+  return a;
+}
+
+/* { dg-final { scan-assembler "\[ \t\]addb\[ \t\]+t\[^\n\r]*, %.h" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr78904-3a.c b/gcc/testsuite/gcc.target/i386/pr78904-3a.c
new file mode 100644 (file)
index 0000000..2827b38
--- /dev/null
@@ -0,0 +1,42 @@
+/* PR target/78904 */
+/* { dg-do assemble } */
+/* { dg-options "-O2" } */
+
+typedef __SIZE_TYPE__ size_t;
+
+struct S1
+{
+  unsigned char pad1;
+  unsigned char val;
+  unsigned short pad2;
+};
+
+extern struct S1 t[256];
+
+struct S1 test_and (struct S1 a, size_t i)
+{
+  a.val &= t[i].val;
+
+  return a;
+}
+
+struct S1 test_or (struct S1 a, size_t i)
+{
+  a.val |= t[i].val;
+
+  return a;
+}
+
+struct S1 test_xor (struct S1 a, size_t i)
+{
+  a.val ^= t[i].val;
+
+  return a;
+}
+
+struct S1 test_add (struct S1 a, size_t i)
+{
+  a.val += t[i].val;
+
+  return a;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr78904-3b.c b/gcc/testsuite/gcc.target/i386/pr78904-3b.c
new file mode 100644 (file)
index 0000000..0c73cbc
--- /dev/null
@@ -0,0 +1,43 @@
+/* PR target/78904 */
+/* { dg-do assemble { target { ! ia32 } } } */
+/* { dg-options "-O2" } */
+
+typedef __SIZE_TYPE__ size_t;
+
+struct S1
+{
+  unsigned char pad1;
+  unsigned char val;
+  unsigned short pad2;
+  unsigned int pad3;
+};
+
+extern struct S1 t[256];
+
+struct S1 test_and (struct S1 a, size_t i)
+{
+  a.val &= t[i].val;
+
+  return a;
+}
+
+struct S1 test_or (struct S1 a, size_t i)
+{
+  a.val |= t[i].val;
+
+  return a;
+}
+
+struct S1 test_xor (struct S1 a, size_t i)
+{
+  a.val ^= t[i].val;
+
+  return a;
+}
+
+struct S1 test_add (struct S1 a, size_t i)
+{
+  a.val += t[i].val;
+
+  return a;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr78904-4a.c b/gcc/testsuite/gcc.target/i386/pr78904-4a.c
new file mode 100644 (file)
index 0000000..5e6159a
--- /dev/null
@@ -0,0 +1,21 @@
+/* PR target/78904 */
+/* { dg-do compile } */
+/* { dg-require-effective-target nonpic } */
+/* { dg-options "-O2 -masm=att" } */
+
+typedef __SIZE_TYPE__ size_t;
+
+struct S1
+{
+  unsigned char pad1;
+  unsigned char val;
+};
+
+extern unsigned char t[256];
+
+void foo (struct S1 a, size_t i)
+{
+  t[i] = a.val;
+}
+
+/* { dg-final { scan-assembler "\[ \t\]movb\[\t \]+%.h, t" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr78904-4b.c b/gcc/testsuite/gcc.target/i386/pr78904-4b.c
new file mode 100644 (file)
index 0000000..ab7434f
--- /dev/null
@@ -0,0 +1,23 @@
+/* PR target/78904 */
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-require-effective-target nonpic } */
+/* { dg-options "-O2 -masm=att" } */
+
+typedef __SIZE_TYPE__ size_t;
+
+struct S1
+{
+  unsigned char pad1;
+  unsigned char val;
+  unsigned short pad2;
+  unsigned int pad3;
+};
+
+extern unsigned char t[256];
+
+void foo (struct S1 a, size_t i)
+{
+  t[i] = a.val;
+}
+
+/* { dg-final { scan-assembler "\[ \t\]movb\[\t \]+%.h, t" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr78904-5a.c b/gcc/testsuite/gcc.target/i386/pr78904-5a.c
new file mode 100644 (file)
index 0000000..d078d79
--- /dev/null
@@ -0,0 +1,21 @@
+/* PR target/78904 */
+/* { dg-do assemble { target { ! ia32 } } } */
+/* { dg-options "-O2" } */
+
+typedef __SIZE_TYPE__ size_t;
+
+struct S1
+{
+  unsigned char pad1;
+  unsigned char val;
+};
+
+extern unsigned char t[256];
+
+void foo (struct S1 a, size_t i)
+{
+  register size_t _i __asm ("r10") = i;
+
+  asm volatile ("" : "+r" (_i));
+  t[_i] = a.val;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr78904-5b.c b/gcc/testsuite/gcc.target/i386/pr78904-5b.c
new file mode 100644 (file)
index 0000000..9490030
--- /dev/null
@@ -0,0 +1,23 @@
+/* PR target/78904 */
+/* { dg-do assemble { target { ! ia32 } } } */
+/* { dg-options "-O2" } */
+
+typedef __SIZE_TYPE__ size_t;
+
+struct S1
+{
+  unsigned char pad1;
+  unsigned char val;
+  unsigned short pad2;
+  unsigned int pad3;
+};
+
+extern unsigned char t[256];
+
+void foo (struct S1 a, size_t i)
+{
+  register size_t _i __asm ("r10") = i;
+
+  asm volatile ("" : "+r" (_i));
+  t[_i] = a.val;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr78904-6a.c b/gcc/testsuite/gcc.target/i386/pr78904-6a.c
new file mode 100644 (file)
index 0000000..ab296a2
--- /dev/null
@@ -0,0 +1,21 @@
+/* PR target/78904 */
+/* { dg-do compile } */
+/* { dg-require-effective-target nonpic } */
+/* { dg-options "-O2 -masm=att" } */
+
+typedef __SIZE_TYPE__ size_t;
+
+struct S1
+{
+  char pad1;
+  char val;
+};
+
+extern char t[256];
+
+void foo (struct S1 a, size_t i)
+{
+  t[i] = a.val;
+}
+
+/* { dg-final { scan-assembler "\[ \t\]movb\[\t \]*%.h, t" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr78904-6b.c b/gcc/testsuite/gcc.target/i386/pr78904-6b.c
new file mode 100644 (file)
index 0000000..235bfe7
--- /dev/null
@@ -0,0 +1,23 @@
+/* PR target/78904 */
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-require-effective-target nonpic } */
+/* { dg-options "-O2 -masm=att" } */
+
+typedef __SIZE_TYPE__ size_t;
+
+struct S1
+{
+  char pad1;
+  char val;
+  short pad2;
+  int pad3;
+};
+
+extern char t[256];
+
+void foo (struct S1 a, size_t i)
+{
+  t[i] = a.val;
+}
+
+/* { dg-final { scan-assembler "\[ \t\]movb\[\t \]*%.h, t" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr78967-1a.c b/gcc/testsuite/gcc.target/i386/pr78967-1a.c
new file mode 100644 (file)
index 0000000..007c506
--- /dev/null
@@ -0,0 +1,20 @@
+/* PR target/78967 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -masm=att" } */
+/* { dg-additional-options "-mregparm=3" { target ia32 } } */
+/* { dg-final { scan-assembler-not "movzbl" } } */
+
+struct S1
+{
+  unsigned char pad1;
+  unsigned char val;
+};
+
+struct S1 foo (struct S1 a, struct S1 b)
+{
+  a.val = b.val;
+
+  return a;
+}
+
+/* { dg-final { scan-assembler "\[ \t\]movb\[ \t\]+%.h, %.h" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr78967-1b.c b/gcc/testsuite/gcc.target/i386/pr78967-1b.c
new file mode 100644 (file)
index 0000000..7e71443
--- /dev/null
@@ -0,0 +1,21 @@
+/* PR target/78967 */
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -masm=att" } */
+/* { dg-final { scan-assembler-not "movzbl" } } */
+
+struct S1
+{
+  unsigned char pad1;
+  unsigned char val;
+  unsigned short pad2;
+  unsigned int pad3;
+};
+
+struct S1 foo (struct S1 a, struct S1 b)
+{
+  a.val = b.val;
+
+  return a;
+}
+
+/* { dg-final { scan-assembler "\[ \t\]movb\[ \t\]+%.h, %.h" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr78967-2a.c b/gcc/testsuite/gcc.target/i386/pr78967-2a.c
new file mode 100644 (file)
index 0000000..ce61cab
--- /dev/null
@@ -0,0 +1,24 @@
+/* PR target/78967 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -masm=att" } */
+/* { dg-require-effective-target nonpic } */
+/* { dg-final { scan-assembler-not "movzbl" } } */
+
+typedef __SIZE_TYPE__ size_t;
+
+struct S1
+{
+  unsigned char pad1;
+  unsigned char val;
+};
+
+extern unsigned char t[256];
+
+struct S1 foo (struct S1 a, size_t i)
+{
+  a.val = t[i];
+
+  return a;
+}
+
+/* { dg-final { scan-assembler "\[ \t\]movb\[ \t\]+t\[^\n\r]*, %.h" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr78967-2b.c b/gcc/testsuite/gcc.target/i386/pr78967-2b.c
new file mode 100644 (file)
index 0000000..ce38ac4
--- /dev/null
@@ -0,0 +1,26 @@
+/* PR target/78967 */
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -masm=att" } */
+/* { dg-require-effective-target nonpic } */
+/* { dg-final { scan-assembler-not "movzbl" } } */
+
+typedef __SIZE_TYPE__ size_t;
+
+struct S1
+{
+  unsigned char pad1;
+  unsigned char val;
+  unsigned short pad2;
+  unsigned int pad3;
+};
+
+extern unsigned char t[256];
+
+struct S1 foo (struct S1 a, size_t i)
+{
+  a.val = t[i];
+
+  return a;
+}
+
+/* { dg-final { scan-assembler "\[ \t\]movb\[ \t\]+t\[^\n\r]*, %.h" } } */