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.
Paths
| Differential D68515
[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
Diff Detail Event Timelinelebedev.ri added a parent revision: D68514: [PATCH 19/27] [noalias] Introduce ConnectNoAliasDecl pass.Oct 5 2019, 9:52 AM lebedev.ri added a child revision: D68516: [PATCH 21/27] [noalias] LICM: learn about noalias intrinsics and ptr_provenance. Comment Actions 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. noalias-copyguard.ll3 KBDownload
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? Comment Actions
[..]
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 If it is based on 'a pointer to int' conversion in the c-language, then it should be ok to just ignore it. Comment Actions
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. Comment ActionsRebased to 9fb46a452d4e5666828c95610ceac8dcd9e4ce16 (September 7, 2020)
Revision Contents
Diff 346133 llvm/lib/Transforms/Scalar/SROA.cpp
llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp
|
clang-tidy: warning: function 'gatherValidNoAliasPointerOffsets' is within a recursive call chain [misc-no-recursion]
not useful