]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[PR/target 100316] Allow constant address for __builtin___clear_cache.
authorKito Cheng <kito.cheng@sifive.com>
Thu, 7 Oct 2021 08:17:13 +0000 (16:17 +0800)
committerKito Cheng <kito.cheng@sifive.com>
Mon, 11 Oct 2021 06:14:08 +0000 (14:14 +0800)
__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.

gcc/builtins.c
gcc/testsuite/gcc.c-torture/compile/pr100316.c [new file with mode: 0644]

index 3e57eb03af039f6a1ee5d390f0ab630c54b70cdd..80a1bb191c660eda20b35ab0a93dcbe74385bc0d 100644 (file)
@@ -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 (file)
index 0000000..38eca86
--- /dev/null
@@ -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);
+}
+