Skip to content

Commit 6966918

Browse files
committed
i386: Disable string insn from non-default AS for Pmode != word_mode [PR111657]
0x67 prefix is applied before segment register. That is in rep movsq %gs:(%esi), (%edi) the address is %gs + %esi. In case Pmode != word_mode (x32 with a default -maddress-mode=short) instructions should not allow segment override prefixes. Also, remove explicit addr32 prefix from asm templates because address mode can be determined from explicit instruction operands. Also note that Pmode != word_mode only with TARGET_64BIT, so the check in ix86_print_operand is not needed. PR target/111657 gcc/ChangeLog: * config/i386/i386-expand.cc (alg_usable_p): For Pmode != word_mode reject rep_prefix_{1,4,8}_byte algorithms with src_as in the non-default address space. * config/i386/i386-protos.h (ix86_check_movs): New prototype. * config/i386/i386.cc (ix86_check_movs): New function. (ix86_print_operand) [case '^']: Remove excess check for TARGET_64BIT. * config/i386/i386.md (strmov): For Pmode != word_mode expand with gen_strmov_single only when operands[3] (source) is in the default address space. (*strmovdi_rex_1) Use ix86_check_movs. Remove %^ from asm template. (*strmovsi_1): Ditto. (*strmovhi_1): DItto. (*strmovqi_1): Ditto. (*rep_movdi_rex64): Ditto. (*rep_movsi): Ditto. (*rep_movqi): Ditto. gcc/testsuite/ChangeLog: * gcc.target/i386/pr111657-1.c: Check that segment override is not generated for "rep movsq" for x32 target.
1 parent 7c2e60f commit 6966918

File tree

5 files changed

+44
-25
lines changed

5 files changed

+44
-25
lines changed

gcc/config/i386/i386-expand.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8933,7 +8933,8 @@ alg_usable_p (enum stringop_alg alg, bool memset,
89338933
if (fixed_regs[CX_REG]
89348934
|| fixed_regs[DI_REG]
89358935
|| (memset ? fixed_regs[AX_REG] : fixed_regs[SI_REG])
8936-
|| !ADDR_SPACE_GENERIC_P (dst_as))
8936+
|| !ADDR_SPACE_GENERIC_P (dst_as)
8937+
|| !(ADDR_SPACE_GENERIC_P (src_as) || Pmode == word_mode))
89378938
return false;
89388939
}
89398940
return true;

gcc/config/i386/i386-protos.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ extern void ix86_expand_v2di_ashiftrt (rtx[]);
186186
extern rtx ix86_replace_reg_with_reg (rtx, rtx, rtx);
187187
extern rtx ix86_find_base_term (rtx);
188188
extern bool ix86_check_movabs (rtx, int);
189+
extern bool ix86_check_movs (rtx, int);
189190
extern bool ix86_check_no_addr_space (rtx);
190191
extern void ix86_split_idivmod (machine_mode, rtx[], bool);
191192
extern bool ix86_hardreg_mov_ok (rtx, rtx);

gcc/config/i386/i386.cc

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5180,6 +5180,27 @@ ix86_check_movabs (rtx insn, int opnum)
51805180
return volatile_ok || !MEM_VOLATILE_P (mem);
51815181
}
51825182

5183+
/* Return true if XVECEXP idx of INSN satisfies MOVS arguments. */
5184+
bool
5185+
ix86_check_movs (rtx insn, int idx)
5186+
{
5187+
rtx pat = PATTERN (insn);
5188+
gcc_assert (GET_CODE (pat) == PARALLEL);
5189+
5190+
rtx set = XVECEXP (pat, 0, idx);
5191+
gcc_assert (GET_CODE (set) == SET);
5192+
5193+
rtx dst = SET_DEST (set);
5194+
gcc_assert (MEM_P (dst));
5195+
5196+
rtx src = SET_SRC (set);
5197+
gcc_assert (MEM_P (src));
5198+
5199+
return (ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (dst))
5200+
&& (ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (src))
5201+
|| Pmode == word_mode));
5202+
}
5203+
51835204
/* Return false if INSN contains a MEM with a non-default address space. */
51845205
bool
51855206
ix86_check_no_addr_space (rtx insn)
@@ -14296,7 +14317,7 @@ ix86_print_operand (FILE *file, rtx x, int code)
1429614317
return;
1429714318

1429814319
case '^':
14299-
if (TARGET_64BIT && Pmode != word_mode)
14320+
if (Pmode != word_mode)
1430014321
fputs ("addr32 ", file);
1430114322
return;
1430214323

gcc/config/i386/i386.md

Lines changed: 17 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -25599,7 +25599,9 @@
2559925599
* since string insns cannot override the destination segment. */
2560025600
if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
2560125601
&& !(fixed_regs[SI_REG] || fixed_regs[DI_REG])
25602-
&& ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[1])))
25602+
&& ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[1]))
25603+
&& (ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[3]))
25604+
|| Pmode == word_mode))
2560325605
{
2560425606
emit_insn (gen_strmov_singleop (operands[0], operands[1],
2560525607
operands[2], operands[3],
@@ -25634,15 +25636,14 @@
2563425636
(const_int 8)))]
2563525637
"TARGET_64BIT
2563625638
&& !(fixed_regs[SI_REG] || fixed_regs[DI_REG])
25637-
&& ADDR_SPACE_GENERIC_P
25638-
(MEM_ADDR_SPACE (SET_DEST (XVECEXP (PATTERN (insn), 0, 0))))"
25639+
&& ix86_check_movs (insn, 0)"
2563925640
{
2564025641
rtx exp = XVECEXP (PATTERN (insn), 0, 0);
2564125642

2564225643
operands[0] = SET_DEST (exp);
2564325644
operands[1] = SET_SRC (exp);
2564425645

25645-
return "%^movsq\t{%1, %0|%0, %1}";
25646+
return "movsq\t{%1, %0|%0, %1}";
2564625647
}
2564725648
[(set_attr "type" "str")
2564825649
(set_attr "memory" "both")
@@ -25658,15 +25659,14 @@
2565825659
(plus:P (match_dup 3)
2565925660
(const_int 4)))]
2566025661
"!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
25661-
&& ADDR_SPACE_GENERIC_P
25662-
(MEM_ADDR_SPACE (SET_DEST (XVECEXP (PATTERN (insn), 0, 0))))"
25662+
&& ix86_check_movs (insn, 0)"
2566325663
{
2566425664
rtx exp = XVECEXP (PATTERN (insn), 0, 0);
2566525665

2566625666
operands[0] = SET_DEST (exp);
2566725667
operands[1] = SET_SRC (exp);
2566825668

25669-
return "%^movs{l|d}\t{%1, %0|%0, %1}";
25669+
return "movs{l|d}\t{%1, %0|%0, %1}";
2567025670
}
2567125671
[(set_attr "type" "str")
2567225672
(set_attr "memory" "both")
@@ -25682,15 +25682,14 @@
2568225682
(plus:P (match_dup 3)
2568325683
(const_int 2)))]
2568425684
"!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
25685-
&& ADDR_SPACE_GENERIC_P
25686-
(MEM_ADDR_SPACE (SET_DEST (XVECEXP (PATTERN (insn), 0, 0))))"
25685+
&& ix86_check_movs (insn, 0)"
2568725686
{
2568825687
rtx exp = XVECEXP (PATTERN (insn), 0, 0);
2568925688

2569025689
operands[0] = SET_DEST (exp);
2569125690
operands[1] = SET_SRC (exp);
2569225691

25693-
return "%^movsw\t{%1, %0|%0, %1}";
25692+
return "movsw\t{%1, %0|%0, %1}";
2569425693
}
2569525694
[(set_attr "type" "str")
2569625695
(set_attr "memory" "both")
@@ -25706,15 +25705,14 @@
2570625705
(plus:P (match_dup 3)
2570725706
(const_int 1)))]
2570825707
"!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
25709-
&& ADDR_SPACE_GENERIC_P
25710-
(MEM_ADDR_SPACE (SET_DEST (XVECEXP (PATTERN (insn), 0, 0))))"
25708+
&& ix86_check_movs (insn, 0)"
2571125709
{
2571225710
rtx exp = XVECEXP (PATTERN (insn), 0, 0);
2571325711

2571425712
operands[0] = SET_DEST (exp);
2571525713
operands[1] = SET_SRC (exp);
2571625714

25717-
return "%^movsb\t{%1, %0|%0, %1}";
25715+
return "movsb\t{%1, %0|%0, %1}";
2571825716
}
2571925717
[(set_attr "type" "str")
2572025718
(set_attr "memory" "both")
@@ -25754,15 +25752,14 @@
2575425752
(use (match_dup 5))]
2575525753
"TARGET_64BIT
2575625754
&& !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
25757-
&& ADDR_SPACE_GENERIC_P
25758-
(MEM_ADDR_SPACE (SET_DEST (XVECEXP (PATTERN (insn), 0, 3))))"
25755+
&& ix86_check_movs (insn, 3)"
2575925756
{
2576025757
rtx exp = XVECEXP (PATTERN (insn), 0, 3);
2576125758

2576225759
operands[0] = SET_DEST (exp);
2576325760
operands[1] = SET_SRC (exp);
2576425761

25765-
return "%^rep{%;} movsq\t{%1, %0|%0, %1}";
25762+
return "rep{%;} movsq\t{%1, %0|%0, %1}";
2576625763
}
2576725764
[(set_attr "type" "str")
2576825765
(set_attr "prefix_rep" "1")
@@ -25782,15 +25779,14 @@
2578225779
(mem:BLK (match_dup 4)))
2578325780
(use (match_dup 5))]
2578425781
"!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
25785-
&& ADDR_SPACE_GENERIC_P
25786-
(MEM_ADDR_SPACE (SET_DEST (XVECEXP (PATTERN (insn), 0, 3))))"
25782+
&& ix86_check_movs (insn, 3)"
2578725783
{
2578825784
rtx exp = XVECEXP (PATTERN (insn), 0, 3);
2578925785

2579025786
operands[0] = SET_DEST (exp);
2579125787
operands[1] = SET_SRC (exp);
2579225788

25793-
return "%^rep{%;} movs{l|d}\t{%1, %0|%0, %1}";
25789+
return "rep{%;} movs{l|d}\t{%1, %0|%0, %1}";
2579425790
}
2579525791
[(set_attr "type" "str")
2579625792
(set_attr "prefix_rep" "1")
@@ -25808,15 +25804,14 @@
2580825804
(mem:BLK (match_dup 4)))
2580925805
(use (match_dup 5))]
2581025806
"!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
25811-
&& ADDR_SPACE_GENERIC_P
25812-
(MEM_ADDR_SPACE (SET_DEST (XVECEXP (PATTERN (insn), 0, 3))))"
25807+
&& ix86_check_movs (insn, 3)"
2581325808
{
2581425809
rtx exp = XVECEXP (PATTERN (insn), 0, 3);
2581525810

2581625811
operands[0] = SET_DEST (exp);
2581725812
operands[1] = SET_SRC (exp);
2581825813

25819-
return "%^rep{%;} movsb\t{%1, %0|%0, %1}";
25814+
return "rep{%;} movsb\t{%1, %0|%0, %1}";
2582025815
}
2582125816
[(set_attr "type" "str")
2582225817
(set_attr "prefix_rep" "1")

gcc/testsuite/gcc.target/i386/pr111657-1.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,5 @@ struct a { uword arr[30]; };
88
__seg_gs struct a m;
99
void bar (struct a *dst) { *dst = m; }
1010

11-
/* { dg-final { scan-assembler "rep\[; \t\]+movs(l|q)\[ \t\]+%gs:" } } */
11+
/* { dg-final { scan-assembler "rep\[; \t\]+movs(l|q)\[ \t\]+%gs:" { target { ! x32 } } } } */
12+
/* { dg-final { scan-assembler-not "rep\[; \t\]+movs(l|q)\[ \t\]+%gs:" { target x32 } } } */

0 commit comments

Comments
 (0)