aboutsummaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2024-11-29 10:17:07 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2024-11-29 10:18:32 +0100
commitf7bbdf7e4acf9c90f51d24db9a3c911c49169ab6 (patch)
treee3fcf8d20d639da2f16b93d0305752860d7c09a4 /gcc/config
parent48b72743b0e29871171593fe34856da62d954750 (diff)
downloadgcc-f7bbdf7e4acf9c90f51d24db9a3c911c49169ab6.zip
gcc-f7bbdf7e4acf9c90f51d24db9a3c911c49169ab6.tar.gz
gcc-f7bbdf7e4acf9c90f51d24db9a3c911c49169ab6.tar.bz2
__builtin_prefetch fixes [PR117608]
The r15-4833-ge9ab41b79933 patch had among tons of config/i386 specific changes also important change to the generic code, allowing also 2 as valid value of the second argument of __builtin_prefetch: - /* Argument 1 must be either zero or one. */ - if (INTVAL (op1) != 0 && INTVAL (op1) != 1) + /* Argument 1 must be 0, 1 or 2. */ + if (INTVAL (op1) < 0 || INTVAL (op1) > 2) But the patch failed to document that change in __builtin_prefetch documentation, and more importantly didn't adjust any of the other backends to deal with it (my understanding is the expected behavior is that 2 will be silently handled as 0 unless backends have some more specific way). Some of the backends would ICE on it, in some cases gcc_assert failures/gcc_unreachable, in other cases crash later (e.g. accessing arrays with that value as index and due to accessing garbage after the array crashing at final.cc time), others treated 2 silently as 0, others treated 2 silently as 1. And even in the i386 backend there were bugs which caused ICEs. The patch added some if (write == 0) and write 2 handling into a (badly indented, maybe that is the reason, if (write == 1) body), rather than into the else side, so it would be always false. The new *prefetch_rst2 define_insn only accepts parameters 2 1 (i.e. read-shared with moderate degree of locality), so in order not to ICE the patch uses it only for __builtin_prefetch (ptr, 2, 1); or __builtin_ia32_prefetch (ptr, 2, 1, 0); and not for other values of the parameter. If that isn't what we want and we want it to be used also for all or some of __builtin_prefetch (ptr, 2, {0,2,3}); and corresponding __builtin_ia32_prefetch, maybe the define_insn could match other values. And there was another problem that -mno-mmx -mno-sse -mmovrs compilation would ICE on most of the prefetches, so I had to add the FAIL; cases. 2024-11-29 Jakub Jelinek <jakub@redhat.com> PR target/117608 * doc/extend.texi (__builtin_prefetch): Document that second argument may be also 2 and its meaning. * config/i386/i386.md (prefetch): Remove unreachable code. Clear write set operands[1] to const0_rtx if !TARGET_MOVRS or of locality is not 1. Formatting fixes. * config/i386/i386-expand.cc (ix86_expand_builtin): Use IN_RANGE. Call gen_prefetch even for TARGET_MOVRS. * config/alpha/alpha.md (prefetch): Treat read_or_write 2 like 0. * config/mips/mips.md (prefetch): Likewise. * config/arc/arc.md (prefetch_1, prefetch_2, prefetch_3): Likewise. * config/riscv/riscv.md (prefetch): Likewise. * config/loongarch/loongarch.md (prefetch): Likewise. * config/sparc/sparc.md (prefetch): Likewise. Use IN_RANGE. * config/ia64/ia64.md (prefetch): Likewise. * config/pa/pa.md (prefetch): Likewise. * config/aarch64/aarch64.md (prefetch): Likewise. * config/rs6000/rs6000.md (prefetch): Likewise. * gcc.dg/builtin-prefetch-1.c (good): Add tests with second argument 2. * gcc.target/i386/pr117608-1.c: New test. * gcc.target/i386/pr117608-2.c: New test.
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/aarch64/aarch64.md2
-rw-r--r--gcc/config/alpha/alpha.md2
-rw-r--r--gcc/config/arc/arc.md14
-rw-r--r--gcc/config/i386/i386-expand.cc10
-rw-r--r--gcc/config/i386/i386.md37
-rw-r--r--gcc/config/ia64/ia64.md6
-rw-r--r--gcc/config/loongarch/loongarch.md3
-rw-r--r--gcc/config/mips/mips.md2
-rw-r--r--gcc/config/pa/pa.md2
-rw-r--r--gcc/config/riscv/riscv.md3
-rw-r--r--gcc/config/rs6000/rs6000.md4
-rw-r--r--gcc/config/sparc/sparc.md12
12 files changed, 49 insertions, 48 deletions
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 711e9ad..87ba186 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -1020,7 +1020,7 @@
the address into a DImode MEM so that aarch64_print_operand knows
how to print it. */
operands[0] = gen_rtx_MEM (DImode, operands[0]);
- return pftype[INTVAL(operands[1])][locality];
+ return pftype[INTVAL (operands[1]) & 1][locality];
}
[(set_attr "type" "load_4")]
)
diff --git a/gcc/config/alpha/alpha.md b/gcc/config/alpha/alpha.md
index e57a9d3..22ea4db 100644
--- a/gcc/config/alpha/alpha.md
+++ b/gcc/config/alpha/alpha.md
@@ -5171,7 +5171,7 @@
}
};
- bool write = INTVAL (operands[1]) != 0;
+ bool write = (INTVAL (operands[1]) & 1) != 0;
bool lru = INTVAL (operands[2]) != 0;
return alt[write][lru];
diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md
index 9004b60..1fb7cf5 100644
--- a/gcc/config/arc/arc.md
+++ b/gcc/config/arc/arc.md
@@ -5439,9 +5439,9 @@ archs4x, archs4xd"
(match_operand:SI 2 "const_int_operand" "n"))]
"TARGET_HS"
{
- if (INTVAL (operands[1]))
+ if ((INTVAL (operands[1]) & 1) != 0)
return "prefetchw [%0]";
- else
+ else
return "prefetch [%0]";
}
[(set_attr "type" "load")
@@ -5454,9 +5454,9 @@ archs4x, archs4xd"
(match_operand:SI 3 "const_int_operand" "n,n,n"))]
"TARGET_HS"
{
- if (INTVAL (operands[2]))
+ if ((INTVAL (operands[2]) & 1) != 0)
return "prefetchw\\t[%0, %1]";
- else
+ else
return "prefetch\\t[%0, %1]";
}
[(set_attr "type" "load")
@@ -5468,10 +5468,10 @@ archs4x, archs4xd"
(match_operand:SI 2 "const_int_operand" "n"))]
"TARGET_HS"
{
- operands[0] = gen_rtx_MEM (SImode, operands[0]);
- if (INTVAL (operands[1]))
+ operands[0] = gen_rtx_MEM (SImode, operands[0]);
+ if ((INTVAL (operands[1]) & 1) != 0)
return "prefetchw%U0\\t%0";
- else
+ else
return "prefetch%U0\\t%0";
}
[(set_attr "type" "load")
diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc
index 2eb6197..6d25477 100644
--- a/gcc/config/i386/i386-expand.cc
+++ b/gcc/config/i386/i386-expand.cc
@@ -14222,7 +14222,7 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget,
if (INTVAL (op3) == 1)
{
- if (INTVAL (op2) < 2 || INTVAL (op2) > 3)
+ if (!IN_RANGE (INTVAL (op2), 2, 3))
{
error ("invalid third argument");
return const0_rtx;
@@ -14252,14 +14252,16 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget,
op0 = copy_addr_to_reg (op0);
}
- if (INTVAL (op2) < 0 || INTVAL (op2) > 3)
+ if (!IN_RANGE (INTVAL (op2), 0, 3))
{
warning (0, "invalid third argument to %<__builtin_ia32_prefetch%>; using zero");
op2 = const0_rtx;
}
- if (TARGET_3DNOW || TARGET_PREFETCH_SSE
- || TARGET_PRFCHW)
+ if (TARGET_3DNOW
+ || TARGET_PREFETCH_SSE
+ || TARGET_PRFCHW
+ || TARGET_MOVRS)
emit_insn (gen_prefetch (op0, op1, op2));
else if (!MEM_P (op0) && side_effects_p (op0))
/* Don't do anything with direct references to volatile memory,
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 8eb9cb6..ffbb107 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -28595,8 +28595,7 @@
[(prefetch (match_operand 0 "address_operand")
(match_operand:SI 1 "const_int_operand")
(match_operand:SI 2 "const_int_operand"))]
- "TARGET_3DNOW || TARGET_PREFETCH_SSE || TARGET_PRFCHW
- || TARGET_MOVRS"
+ "TARGET_3DNOW || TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_MOVRS"
{
int write = INTVAL (operands[1]);
int locality = INTVAL (operands[2]);
@@ -28609,7 +28608,7 @@
SSE prefetch is not available (K6 machines). Otherwise use SSE
prefetch as it allows specifying of locality. */
- if (write == 1)
+ if (write == 1)
{
if (TARGET_PRFCHW)
operands[2] = GEN_INT (3);
@@ -28617,33 +28616,29 @@
operands[2] = GEN_INT (3);
else if (TARGET_PREFETCH_SSE)
operands[1] = const0_rtx;
- else if (write == 0)
- {
- gcc_assert (TARGET_3DNOW);
- operands[2] = GEN_INT (3);
- }
+ else if (TARGET_3DNOW)
+ operands[2] = GEN_INT (3);
else
{
- if (TARGET_MOVRS)
- ;
- else if (TARGET_PREFETCH_SSE)
- operands[1] = const0_rtx;
- else
- {
- gcc_assert (TARGET_3DNOW);
- operands[1] = const0_rtx;
- operands[2] = GEN_INT (3);
- }
+ gcc_assert (TARGET_MOVRS);
+ FAIL;
}
}
else
{
- if (TARGET_PREFETCH_SSE)
+ if (!TARGET_MOVRS || locality != 1)
+ {
+ operands[1] = const0_rtx;
+ write = 0;
+ }
+ if (TARGET_PREFETCH_SSE || write == 2)
;
+ else if (TARGET_3DNOW)
+ operands[2] = GEN_INT (3);
else
{
- gcc_assert (TARGET_3DNOW);
- operands[2] = GEN_INT (3);
+ gcc_assert (TARGET_MOVRS);
+ FAIL;
}
}
})
diff --git a/gcc/config/ia64/ia64.md b/gcc/config/ia64/ia64.md
index d485acc..c533a9c 100644
--- a/gcc/config/ia64/ia64.md
+++ b/gcc/config/ia64/ia64.md
@@ -5041,9 +5041,9 @@
int i = (INTVAL (operands[1]));
int j = (INTVAL (operands[2]));
- gcc_assert (i == 0 || i == 1);
- gcc_assert (j >= 0 && j <= 3);
- return alt[i][j];
+ gcc_assert (IN_RANGE (i, 0, 2));
+ gcc_assert (IN_RANGE (j, 0, 3));
+ return alt[i & 1][j];
}
[(set_attr "itanium_class" "lfetch")])
diff --git a/gcc/config/loongarch/loongarch.md b/gcc/config/loongarch/loongarch.md
index bd08250..a65cc1d 100644
--- a/gcc/config/loongarch/loongarch.md
+++ b/gcc/config/loongarch/loongarch.md
@@ -4091,7 +4091,8 @@
{
switch (INTVAL (operands[1]))
{
- case 0: return "preld\t0,%a0";
+ case 0:
+ case 2: return "preld\t0,%a0";
case 1: return "preld\t8,%a0";
default: gcc_unreachable ();
}
diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index f147667..dff7ded 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -7395,6 +7395,8 @@
else
return "lw\t$0,%a0";
}
+ if (operands[1] == const2_rtx)
+ operands[1] = const0_rtx;
/* Loongson ext2 implementation pref instructions. */
if (TARGET_LOONGSON_EXT2)
{
diff --git a/gcc/config/pa/pa.md b/gcc/config/pa/pa.md
index c4441d8..61447c0 100644
--- a/gcc/config/pa/pa.md
+++ b/gcc/config/pa/pa.md
@@ -10354,7 +10354,7 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
"ldd 0(%0),%%r0"
}
};
- int read_or_write = INTVAL (operands[1]) == 0 ? 0 : 1;
+ int read_or_write = INTVAL (operands[1]) & 1;
int locality = INTVAL (operands[2]) == 0 ? 0 : 1;
return instr [locality][read_or_write];
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index eb5cd6f..f7a6db3 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -4219,7 +4219,8 @@
{
switch (INTVAL (operands[1]))
{
- case 0: return TARGET_ZIHINTNTL ? "%L2prefetch.r\t%a0" : "prefetch.r\t%a0";
+ case 0:
+ case 2: return TARGET_ZIHINTNTL ? "%L2prefetch.r\t%a0" : "prefetch.r\t%a0";
case 1: return TARGET_ZIHINTNTL ? "%L2prefetch.w\t%a0" : "prefetch.w\t%a0";
default: gcc_unreachable ();
}
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 95be36d..edccd78 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -14353,14 +14353,14 @@
if (REG_P (operands[0]))
{
- if (INTVAL (operands[1]) == 0)
+ if (INTVAL (operands[1]) != 1)
return inst_select ? "dcbt 0,%0" : "dcbt 0,%0,16";
else
return inst_select ? "dcbtst 0,%0" : "dcbtst 0,%0,16";
}
else
{
- if (INTVAL (operands[1]) == 0)
+ if (INTVAL (operands[1]) != 1)
return inst_select ? "dcbt %a0" : "dcbt %a0,16";
else
return inst_select ? "dcbtst %a0" : "dcbtst %a0,16";
diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md
index 0de9a7b..5fd18b3 100644
--- a/gcc/config/sparc/sparc.md
+++ b/gcc/config/sparc/sparc.md
@@ -7832,9 +7832,9 @@
int read_or_write = INTVAL (operands[1]);
int locality = INTVAL (operands[2]);
- gcc_assert (read_or_write == 0 || read_or_write == 1);
- gcc_assert (locality >= 0 && locality < 4);
- return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
+ gcc_assert (IN_RANGE (read_or_write, 0, 2));
+ gcc_assert (IN_RANGE (locality, 0, 3));
+ return prefetch_instr [read_or_write & 1][locality == 0 ? 0 : 1];
}
[(set_attr "type" "load")
(set_attr "subtype" "prefetch")])
@@ -7858,9 +7858,9 @@
int read_or_write = INTVAL (operands[1]);
int locality = INTVAL (operands[2]);
- gcc_assert (read_or_write == 0 || read_or_write == 1);
- gcc_assert (locality >= 0 && locality < 4);
- return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
+ gcc_assert (IN_RANGE (read_or_write, 0, 2));
+ gcc_assert (IN_RANGE (locality, 0, 3));
+ return prefetch_instr [read_or_write & 1][locality == 0 ? 0 : 1];
}
[(set_attr "type" "load")
(set_attr "subtype" "prefetch")])