This is an archive of the discontinued LLVM Phabricator instance.

[PATCH 20/27] [noalias] SROA/PromoteMemoryToRegister: Learn how to handle noalias intrinsics
Needs ReviewPublic

Authored by jeroen.dobbelaere on Oct 4 2019, 3:13 PM.

Details

Reviewers
hfinkel
jdoerfert
Summary

This is part of the series started by D68484.

Ensures that alloca's can be split and optimized away, while keeping
the noalias information correct.

Note: this is a stable point and tests should run fine with the patches applied up to this point.

Diff Detail

Event Timeline

Herald added a project: Restricted Project. · View Herald TranscriptOct 4 2019, 3:13 PM

Adapt test to i64 p.objId. (was i32)

Jeroen, we discovered an assertion in introduceNoAliasWhenCopyGuardIndicesAreCompatible() for the case described below; we would appreciate your input.

This function expects a GEP between a load and a copy.guard, however, it's not always so; consider the following case where there's a bitcast instruction instead:

%3 = call %struct.FOO* @llvm.noalias.copy.guard.p0s_struct.FOOs.p0i8(%struct.FOO* %ssrc, i8* %0, metadata !12, metadata !6)
%src_bitcast = bitcast %struct.FOO* %3 to i32*
%src_data = load i32, i32* %src_bitcast, noalias_sidechannel i32* undef, align 4, !noalias !6

On platforms with 32-bit pointers, pointers might be treated as 32-bit integers, hence the bitcast. I attach an llvm-lit test case, hope it helps.

I don't think that we can emit an llvm.noalias intrinsic here since the pointer is treated as a integer, so maybe we should just bail.. What do you think?

[..]

On platforms with 32-bit pointers, pointers might be treated as 32-bit integers, hence the bitcast. I attach an llvm-lit test case, hope it helps.

I don't think that we can emit an llvm.noalias intrinsic here since the pointer is treated as a integer, so maybe we should just bail.. What do you think?

Is the bitcast introduced by 'clang' (frontend), or was it introduced by one of the optimization passes ? In the latter case, which pass is this? We should probably handle it and
treat it as a 'gep with all-0 indices'... And make sure that the pointer-type for the llvm.noalias is somewhat usable.

If it is based on 'a pointer to int' conversion in the c-language, then it should be ok to just ignore it.

Is the bitcast introduced by 'clang' (frontend), or was it introduced by one of the optimization passes ? In the latter case, which pass is this? We should probably handle it and
treat it as a 'gep with all-0 indices'... And make sure that the pointer-type for the llvm.noalias is somewhat usable.

If it is based on 'a pointer to int' conversion in the c-language, then it should be ok to just ignore it.

I looked into it, it is instruction combining that introduces the bitcasts. IR before:

%2 = call %"struct.std::_Array"* @"llvm.noalias.copy.guard.p0s_struct.std::_Arrays.p0i8"(%"struct.std::_Array"* %_M_array4, i8* null, metadata !13, metadata !2)
%3 = bitcast %"struct.std::_Array"* %_M_array to i8*
%4 = bitcast %"struct.std::_Array"* %2 to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %3, i8* align 4 %4, i32 4, i1 false)

IR after:

%2 = call %"struct.std::_Array"* @"llvm.noalias.copy.guard.p0s_struct.std::_Arrays.p0i8"(%"struct.std::_Array"* nonnull %_M_array4, i8* null, metadata !44, metadata !47)
%3 = bitcast %"struct.std::_Array"* %2 to i32*
%4 = bitcast %"struct.std::_Array"* %_M_array to i32*
%5 = load i32, i32* %3, align 4
store i32 %5, i32* %4, align 4

I'm trying to understand your suggestion of treating this kind of bitcasts as a zero-offset GEP, how would we insert an llvm.noalias intrinsic? The first operand of llvm.noalias obviously should be a pointer but the load above doesn't return a pointer, it returns an i32.

jeroen.dobbelaere retitled this revision from [PATCH 31/38] [noalias] SROA/PromoteMemoryToRegister: Learn how to handle noalias intrinsics to [PATCH 20/26] [noalias] SROA/PromoteMemoryToRegister: Learn how to handle noalias intrinsics.
jeroen.dobbelaere retitled this revision from [PATCH 20/26] [noalias] SROA/PromoteMemoryToRegister: Learn how to handle noalias intrinsics to [PATCH 20/27] [noalias] SROA/PromoteMemoryToRegister: Learn how to handle noalias intrinsics.

Rebased to 9fb46a452d4e5666828c95610ceac8dcd9e4ce16 (September 7, 2020)

Fixed build warning and testcase failure in Release mode.