[Bug tree-optimization/110589] New: Missed optimization with call-clobbered restrict qualified references
javier.martinez.bugzilla at gmail dot com
gcc-bugzilla@gcc.gnu.org
Fri Jul 7 15:26:37 GMT 2023
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110589
Bug ID: 110589
Summary: Missed optimization with call-clobbered restrict
qualified references
Product: gcc
Version: 14.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: javier.martinez.bugzilla at gmail dot com
Target Milestone: ---
I see this on GCC trunk and do not think it is a regression, the optimization
is being taken by Clang.
https://godbolt.org/z/G8qrzaKn9
extern void foo(void);
int test_clobber_by_call (int * restrict val_ptr) {
*val_ptr = 1;
foo();
return *val_ptr;
}
GCC 14.0 -O3 produces:
test_clobber_by_call:
push rbx
mov rbx, rdi
mov BYTE PTR [rdi], 1
call foo
movzx eax, BYTE PTR [rbx] ; <--- Not expected
pop rbx
ret
I would expect restrict to be a guarantee that foo() will not alias val_ptr,
producing:
test_clobber_by_call:
mov DWORD PTR [rdi], 1
call foo
mov eax, 1
ret
This is indeed the output when the compiler recognizes that foo does not alias,
as in:
__attribute((noinline)) void foo(int *a) {
*(a+10) = 0;
}
int test_clobber_by_call (int * val_ptr) {
*val_ptr = 1;
foo(val_ptr);
return *val_ptr;
}
-------------------------
It looks to me as if tree-ssa-alias.c#call_may_clobber_ref_p is not considering
a restrict qualified reference.
The following patch produces optimized code for the above example. I do not
claim that it is correct, but it does reflect what I expected to see:
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c
index c3f43dc..277a21e 100644
--- a/gcc/tree-ssa-alias.c
+++ b/gcc/tree-ssa-alias.c
@@ -3037,6 +3037,16 @@ call_may_clobber_ref_p_1 (gcall *call, ao_ref *ref, bool
tbaa_p)
&& SSA_NAME_POINTS_TO_READONLY_MEMORY (TREE_OPERAND (base, 0)))
return false;
+ /* perhaps should be moved further up */
+ if ((TREE_CODE (base) == MEM_REF
+ || TREE_CODE (base) == TARGET_MEM_REF)
+ && TREE_CODE(TREE_OPERAND (base, 0)) == SSA_NAME)
+ {
+ struct ptr_info_def *pi = SSA_NAME_PTR_INFO (TREE_OPERAND (base, 0));
+ if (pi && pi->pt.vars_contains_restrict)
+ return false;
+ }
+
if (int res = check_fnspec (call, ref, true))
{
if (res == 1)
test_clobber_by_call:
sub rsp, 8
mov BYTE PTR [rdi], 1
call may_alias
mov eax, 1 ; <----- deref gone
add rsp, 8
ret
More information about the Gcc-bugs
mailing list