aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKito Cheng <kito.cheng@sifive.com>2021-10-07 16:17:13 +0800
committerKito Cheng <kito.cheng@sifive.com>2021-10-11 14:14:08 +0800
commit4e5bc4e4506a7ae7bb88fc925a425652a1da6b2d (patch)
tree2ae6d751a4b8f3b36611fcf41f899f7406cd29d6
parent6d97315a4e1acb992580e84065c66d09d1342a77 (diff)
downloadgcc-4e5bc4e4506a7ae7bb88fc925a425652a1da6b2d.zip
gcc-4e5bc4e4506a7ae7bb88fc925a425652a1da6b2d.tar.gz
gcc-4e5bc4e4506a7ae7bb88fc925a425652a1da6b2d.tar.bz2
[PR/target 100316] Allow constant address for __builtin___clear_cache.
__builtin___clear_cache was able to accept constant address for the argument, but it seems no longer accept recently, and it even not accept constant address which is hold in variable when optimization is enable: ``` void foo3(){ void *yy = (void*)0x1000; __builtin___clear_cache(yy, yy); } ``` So this patch make BEGIN and END accept VOIDmode, like cselib_lookup_mem did per Jim Wilson's suggestion. ``` static cselib_val * cselib_lookup_mem (rtx x, int create) { ... addr_mode = GET_MODE (XEXP (x, 0)); if (addr_mode == VOIDmode) addr_mode = Pmode; ``` Changes v2 -> v3: - Use gcc_assert rather than error, maybe_emit_call_builtin___clear_cache is internal use only, and we already checked the type in other place. Changes v1 -> v2: - Check is CONST_INT intead of cehck mode, no new testcase, since constant value with other type like CONST_DOUBLE will catched by front-end. e.g. Code: ```c void foo(){ __builtin___clear_cache(1.11, 0); } ``` Error message: ``` clearcache-double.c: In function 'foo': clearcache-double.c:2:27: error: incompatible type for argument 1 of '__builtin___clear_cache' 2 | __builtin___clear_cache(1.11, 0); | ^~~~ | | | double clearcache-double.c:2:27: note: expected 'void *' but argument is of type 'double' ``` gcc/ChangeLog: PR target/100316 * builtins.c (maybe_emit_call_builtin___clear_cache): Allow CONST_INT for BEGIN and END, and use gcc_assert rather than error. gcc/testsuite/ChangeLog: PR target/100316 * gcc.c-torture/compile/pr100316.c: New.
-rw-r--r--gcc/builtins.c10
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr100316.c18
2 files changed, 22 insertions, 6 deletions
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 3e57eb0..80a1bb1 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -5163,12 +5163,10 @@ default_emit_call_builtin___clear_cache (rtx begin, rtx end)
void
maybe_emit_call_builtin___clear_cache (rtx begin, rtx end)
{
- if ((GET_MODE (begin) != ptr_mode && GET_MODE (begin) != Pmode)
- || (GET_MODE (end) != ptr_mode && GET_MODE (end) != Pmode))
- {
- error ("both arguments to %<__builtin___clear_cache%> must be pointers");
- return;
- }
+ gcc_assert ((GET_MODE (begin) == ptr_mode || GET_MODE (begin) == Pmode
+ || CONST_INT_P (begin))
+ && (GET_MODE (end) == ptr_mode || GET_MODE (end) == Pmode
+ || CONST_INT_P (end)));
if (targetm.have_clear_cache ())
{
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr100316.c b/gcc/testsuite/gcc.c-torture/compile/pr100316.c
new file mode 100644
index 0000000..38eca86
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr100316.c
@@ -0,0 +1,18 @@
+void foo(){
+ __builtin___clear_cache(0, 0);
+}
+
+void foo1(){
+ __builtin___clear_cache((void*)0, (void*)0);
+}
+
+void foo2(){
+ void *yy = 0;
+ __builtin___clear_cache(yy, yy);
+}
+
+void foo3(){
+ void *yy = (void*)0x1000;
+ __builtin___clear_cache(yy, yy);
+}
+