[llvm-dev] Help with SROA throwing away no-alias information

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

[llvm-dev] Help with SROA throwing away no-alias information

Jonas Paulsson via llvm-dev
I'm having an issue where SROA will throw away no-alias information on some loads after inlining, because the loads are derived from a store to an alloca which can be removed after inlining.

The pointers that were originally stored into the alloca do not have any aliasing information - the only context that allowed me to assert aliasing was that the inlined-function guaranteed it to be so.

I know why SROA has done this - its just removing a store -> load on an alloca by forwarding the store, but is there anyway I can preserve the information that these pointers must no-alias?

Here is the pre/post from when SROA is run and you can see the now missing information of no-alias:

define dllexport void @"Burst.Compiler.IL.Tests.Aliasing.CheckInlinedFunctionPreservesAliasing(ref Burst.Compiler.IL.Tests.Aliasing.NoAliasWithContentsStruct s)_862A52BC559AC318"(%"Burst.Compiler.IL.Tests.Aliasing/NoAliasWithContentsStruct"* nocapture nonnull readonly %s) local_unnamed_addr #0 !ubaa. !1 {
entry:
  %var.0 = alloca %"Burst.Compiler.IL.Tests.Aliasing/NoAliasField", align 8
  %0 = bitcast %"Burst.Compiler.IL.Tests.Aliasing/NoAliasWithContentsStruct"* %s to i64*
  %1 = load i64, i64* %0, align 1
  %2 = getelementptr %"Burst.Compiler.IL.Tests.Aliasing/NoAliasWithContentsStruct", %"Burst.Compiler.IL.Tests.Aliasing/NoAliasWithContentsStruct"* %s, i64 0, i32 1
  %3 = bitcast i8** %2 to i64*
  %4 = load i64, i64* %3, align 1
  %5 = bitcast %"Burst.Compiler.IL.Tests.Aliasing/NoAliasField"* %var.0 to i64*
  store i64 %1, i64* %5, align 8
  %.fca.1.gep = getelementptr inbounds %"Burst.Compiler.IL.Tests.Aliasing/NoAliasField", %"Burst.Compiler.IL.Tests.Aliasing/NoAliasField"* %var.0, i64 0, i32 1
  %6 = bitcast i32** %.fca.1.gep to i64*
  store i64 %4, i64* %6, align 8
  %7 = bitcast %"Burst.Compiler.IL.Tests.Aliasing/NoAliasField"* %var.0 to i8**
  %8 = load i8*, i8** %7, align 1, !alias.scope !2, !noalias !5
  %9 = getelementptr %"Burst.Compiler.IL.Tests.Aliasing/NoAliasField", %"Burst.Compiler.IL.Tests.Aliasing/NoAliasField"* %var.0, i64 0, i32 1
  %10 = bitcast i32** %9 to i8**
  %11 = load i8*, i8** %10, align 1, !alias.scope !5, !noalias !2
  call void @llvm.ubaa.expect.no.alias(i8* %8, i64 -1, i8* %11, i64 -1, metadata !"C:\\Users\\NeilHenning\\Home\\burst\\src\\Burst.Compiler.IL.Tests\\Shared\\083-Aliasing.cs(229,9): ") #0
  ret void
}
*** IR Dump After SROA ***
; Function Attrs: nounwind
define dllexport void @"Burst.Compiler.IL.Tests.Aliasing.CheckInlinedFunctionPreservesAliasing(ref Burst.Compiler.IL.Tests.Aliasing.NoAliasWithContentsStruct s)_862A52BC559AC318"(%"Burst.Compiler.IL.Tests.Aliasing/NoAliasWithContentsStruct"* nocapture nonnull readonly %s) local_unnamed_addr #0 !ubaa. !1 {
entry:
  %0 = bitcast %"Burst.Compiler.IL.Tests.Aliasing/NoAliasWithContentsStruct"* %s to i64*
  %1 = load i64, i64* %0, align 1
  %2 = getelementptr %"Burst.Compiler.IL.Tests.Aliasing/NoAliasWithContentsStruct", %"Burst.Compiler.IL.Tests.Aliasing/NoAliasWithContentsStruct"* %s, i64 0, i32 1
  %3 = bitcast i8** %2 to i64*
  %4 = load i64, i64* %3, align 1
  %5 = inttoptr i64 %1 to i8*
  %6 = inttoptr i64 %4 to i8*
  call void @llvm.ubaa.expect.no.alias(i8* %5, i64 -1, i8* %6, i64 -1, metadata !"C:\\Users\\NeilHenning\\Home\\burst\\src\\Burst.Compiler.IL.Tests\\Shared\\083-Aliasing.cs(229,9): ") #0
  ret void
}

My only workaround I can dream up locally is to run a pass before SROA to do the alias.scope and noalias forwarding myself by looking back through the store...

Cheers,
-Neil.

--
Neil Henning
Senior Software Engineer Compiler

_______________________________________________
LLVM Developers mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] Help with SROA throwing away no-alias information

Jonas Paulsson via llvm-dev
  Hi Neil,

  I don't know what `llvm.ubaa` is but maybe you can use of `llvm.assume`
  here if it is just about keeping the load alive without impacting too
  many passes. If we make the change described here [0] (we have patches
  as well) you can write:

   %l = load ... noalias ...
   call llvm.assume(i1 true) ['keep_alive'(%l)]

  or maybe also something like:

   call llvm.assume(i1 true) ['no-alias'(%a, %b)]

  I hope this helps,
    Johannes

  [0] lists.llvm.org/pipermail/llvm-dev/2019-December/137632.html




---------------------------------------
Johannes Doerfert
Researcher

Argonne National Laboratory
Lemont, IL 60439, USA

[hidden email]

________________________________________
From: llvm-dev <[hidden email]> on behalf of Neil Henning via llvm-dev <[hidden email]>
Sent: Friday, January 17, 2020 10:22
To: llvm-dev
Subject: [llvm-dev] Help with SROA throwing away no-alias information

I'm having an issue where SROA will throw away no-alias information on some loads after inlining, because the loads are derived from a store to an alloca which can be removed after inlining.

The pointers that were originally stored into the alloca do not have any aliasing information - the only context that allowed me to assert aliasing was that the inlined-function guaranteed it to be so.

I know why SROA has done this - its just removing a store -> load on an alloca by forwarding the store, but is there anyway I can preserve the information that these pointers must no-alias?

Here is the pre/post from when SROA is run and you can see the now missing information of no-alias:

define dllexport void @"Burst.Compiler.IL.Tests.Aliasing.CheckInlinedFunctionPreservesAliasing(ref Burst.Compiler.IL.Tests.Aliasing.NoAliasWithContentsStruct s)_862A52BC559AC318"(%"Burst.Compiler.IL.Tests.Aliasing/NoAliasWithContentsStruct"* nocapture nonnull readonly %s) local_unnamed_addr #0 !ubaa. !1 {
entry:
  %var.0 = alloca %"Burst.Compiler.IL.Tests.Aliasing/NoAliasField", align 8
  %0 = bitcast %"Burst.Compiler.IL.Tests.Aliasing/NoAliasWithContentsStruct"* %s to i64*
  %1 = load i64, i64* %0, align 1
  %2 = getelementptr %"Burst.Compiler.IL.Tests.Aliasing/NoAliasWithContentsStruct", %"Burst.Compiler.IL.Tests.Aliasing/NoAliasWithContentsStruct"* %s, i64 0, i32 1
  %3 = bitcast i8** %2 to i64*
  %4 = load i64, i64* %3, align 1
  %5 = bitcast %"Burst.Compiler.IL.Tests.Aliasing/NoAliasField"* %var.0 to i64*
  store i64 %1, i64* %5, align 8
  %.fca.1.gep = getelementptr inbounds %"Burst.Compiler.IL.Tests.Aliasing/NoAliasField", %"Burst.Compiler.IL.Tests.Aliasing/NoAliasField"* %var.0, i64 0, i32 1
  %6 = bitcast i32** %.fca.1.gep to i64*
  store i64 %4, i64* %6, align 8
  %7 = bitcast %"Burst.Compiler.IL.Tests.Aliasing/NoAliasField"* %var.0 to i8**
  %8 = load i8*, i8** %7, align 1, !alias.scope !2, !noalias !5
  %9 = getelementptr %"Burst.Compiler.IL.Tests.Aliasing/NoAliasField", %"Burst.Compiler.IL.Tests.Aliasing/NoAliasField"* %var.0, i64 0, i32 1
  %10 = bitcast i32** %9 to i8**
  %11 = load i8*, i8** %10, align 1, !alias.scope !5, !noalias !2
  call void @llvm.ubaa.expect.no.alias(i8* %8, i64 -1, i8* %11, i64 -1, metadata !"C:\\Users\\NeilHenning\\Home\\burst\\src\\Burst.Compiler.IL.Tests\\Shared\\083-Aliasing.cs(229,9): ") #0
  ret void
}
*** IR Dump After SROA ***
; Function Attrs: nounwind
define dllexport void @"Burst.Compiler.IL.Tests.Aliasing.CheckInlinedFunctionPreservesAliasing(ref Burst.Compiler.IL.Tests.Aliasing.NoAliasWithContentsStruct s)_862A52BC559AC318"(%"Burst.Compiler.IL.Tests.Aliasing/NoAliasWithContentsStruct"* nocapture nonnull readonly %s) local_unnamed_addr #0 !ubaa. !1 {
entry:
  %0 = bitcast %"Burst.Compiler.IL.Tests.Aliasing/NoAliasWithContentsStruct"* %s to i64*
  %1 = load i64, i64* %0, align 1
  %2 = getelementptr %"Burst.Compiler.IL.Tests.Aliasing/NoAliasWithContentsStruct", %"Burst.Compiler.IL.Tests.Aliasing/NoAliasWithContentsStruct"* %s, i64 0, i32 1
  %3 = bitcast i8** %2 to i64*
  %4 = load i64, i64* %3, align 1
  %5 = inttoptr i64 %1 to i8*
  %6 = inttoptr i64 %4 to i8*
  call void @llvm.ubaa.expect.no.alias(i8* %5, i64 -1, i8* %6, i64 -1, metadata !"C:\\Users\\NeilHenning\\Home\\burst\\src\\Burst.Compiler.IL.Tests\\Shared\\083-Aliasing.cs(229,9): ") #0
  ret void
}

My only workaround I can dream up locally is to run a pass before SROA to do the alias.scope and noalias forwarding myself by looking back through the store...

Cheers,
-Neil.

--
[https://unity3d.com/profiles/unity3d/themes/unity/images/ui/other/unity-logo-dark-email.png]
Neil Henning
Senior Software Engineer Compiler
unity.com<http://unity.com>
_______________________________________________
LLVM Developers mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] Help with SROA throwing away no-alias information

Jonas Paulsson via llvm-dev
In reply to this post by Jonas Paulsson via llvm-dev

Hi Neil,

 

This should be solved with the 'full restrict patches' https://reviews.llvm.org/D68484 : it treats %noalias arguments in a different

way so that we keep more accurate information during SROA.

A convenience single patch is available here: https://reviews.llvm.org/D69542

 

Please let me know, if you happen to try it out, that it indeed solves your problem.

 

Thanks,

 

Jeroen Dobbelaere

 

 

From: llvm-dev <[hidden email]> On Behalf Of Neil Henning via llvm-dev
Sent: Friday, January 17, 2020 17:22
To: llvm-dev <[hidden email]>
Subject: [llvm-dev] Help with SROA throwing away no-alias information

 

I'm having an issue where SROA will throw away no-alias information on some loads after inlining, because the loads are derived from a store to an alloca which can be removed after inlining.

 

The pointers that were originally stored into the alloca do not have any aliasing information - the only context that allowed me to assert aliasing was that the inlined-function guaranteed it to be so.

 

I know why SROA has done this - its just removing a store -> load on an alloca by forwarding the store, but is there anyway I can preserve the information that these pointers must no-alias?

 

Here is the pre/post from when SROA is run and you can see the now missing information of no-alias:

 

define dllexport void @"Burst.Compiler.IL.Tests.Aliasing.CheckInlinedFunctionPreservesAliasing(ref Burst.Compiler.IL.Tests.Aliasing.NoAliasWithContentsStruct s)_862A52BC559AC318"(%"Burst.Compiler.IL.Tests.Aliasing/NoAliasWithContentsStruct"* nocapture nonnull readonly %s) local_unnamed_addr #0 !ubaa. !1 {
entry:
  %var.0 = alloca %"Burst.Compiler.IL.Tests.Aliasing/NoAliasField", align 8
  %0 = bitcast %"Burst.Compiler.IL.Tests.Aliasing/NoAliasWithContentsStruct"* %s to i64*
  %1 = load i64, i64* %0, align 1
  %2 = getelementptr %"Burst.Compiler.IL.Tests.Aliasing/NoAliasWithContentsStruct", %"Burst.Compiler.IL.Tests.Aliasing/NoAliasWithContentsStruct"* %s, i64 0, i32 1
  %3 = bitcast i8** %2 to i64*
  %4 = load i64, i64* %3, align 1
  %5 = bitcast %"Burst.Compiler.IL.Tests.Aliasing/NoAliasField"* %var.0 to i64*
  store i64 %1, i64* %5, align 8
  %.fca.1.gep = getelementptr inbounds %"Burst.Compiler.IL.Tests.Aliasing/NoAliasField", %"Burst.Compiler.IL.Tests.Aliasing/NoAliasField"* %var.0, i64 0, i32 1
  %6 = bitcast i32** %.fca.1.gep to i64*
  store i64 %4, i64* %6, align 8
  %7 = bitcast %"Burst.Compiler.IL.Tests.Aliasing/NoAliasField"* %var.0 to i8**
  %8 = load i8*, i8** %7, align 1, !alias.scope !2, !noalias !5
  %9 = getelementptr %"Burst.Compiler.IL.Tests.Aliasing/NoAliasField", %"Burst.Compiler.IL.Tests.Aliasing/NoAliasField"* %var.0, i64 0, i32 1
  %10 = bitcast i32** %9 to i8**
  %11 = load i8*, i8** %10, align 1, !alias.scope !5, !noalias !2
  call void @llvm.ubaa.expect.no.alias(i8* %8, i64 -1, i8* %11, i64 -1, metadata !"C:\\Users\\NeilHenning\\Home\\burst\\src\\Burst.Compiler.IL.Tests\\Shared\\083-Aliasing.cs(229,9): ") #0
  ret void
}
*** IR Dump After SROA ***
; Function Attrs: nounwind
define dllexport void @"Burst.Compiler.IL.Tests.Aliasing.CheckInlinedFunctionPreservesAliasing(ref Burst.Compiler.IL.Tests.Aliasing.NoAliasWithContentsStruct s)_862A52BC559AC318"(%"Burst.Compiler.IL.Tests.Aliasing/NoAliasWithContentsStruct"* nocapture nonnull readonly %s) local_unnamed_addr #0 !ubaa. !1 {
entry:
  %0 = bitcast %"Burst.Compiler.IL.Tests.Aliasing/NoAliasWithContentsStruct"* %s to i64*
  %1 = load i64, i64* %0, align 1
  %2 = getelementptr %"Burst.Compiler.IL.Tests.Aliasing/NoAliasWithContentsStruct", %"Burst.Compiler.IL.Tests.Aliasing/NoAliasWithContentsStruct"* %s, i64 0, i32 1
  %3 = bitcast i8** %2 to i64*
  %4 = load i64, i64* %3, align 1
  %5 = inttoptr i64 %1 to i8*
  %6 = inttoptr i64 %4 to i8*
  call void @llvm.ubaa.expect.no.alias(i8* %5, i64 -1, i8* %6, i64 -1, metadata !"C:\\Users\\NeilHenning\\Home\\burst\\src\\Burst.Compiler.IL.Tests\\Shared\\083-Aliasing.cs(229,9): ") #0
  ret void
}

 

My only workaround I can dream up locally is to run a pass before SROA to do the alias.scope and noalias forwarding myself by looking back through the store...

 

Cheers,

-Neil.


--

Image removed by sender.

Neil Henning

Senior Software Engineer Compiler

 


_______________________________________________
LLVM Developers mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] Help with SROA throwing away no-alias information

Jonas Paulsson via llvm-dev
Hey Jeroen,

Ok cool - once I can work out how to apply that patch successfully without using ARC I'll give it a whirl (sidenote: oh how I lament not just being able to use github to pull the PR!).

Cheers,
-Neil.

On Mon, Jan 20, 2020 at 8:09 AM Jeroen Dobbelaere <[hidden email]> wrote:

Hi Neil,

 

This should be solved with the 'full restrict patches' https://reviews.llvm.org/D68484 : it treats %noalias arguments in a different

way so that we keep more accurate information during SROA.

A convenience single patch is available here: https://reviews.llvm.org/D69542

 

Please let me know, if you happen to try it out, that it indeed solves your problem.

 

Thanks,

 

Jeroen Dobbelaere

 

 

From: llvm-dev <[hidden email]> On Behalf Of Neil Henning via llvm-dev
Sent: Friday, January 17, 2020 17:22
To: llvm-dev <[hidden email]>
Subject: [llvm-dev] Help with SROA throwing away no-alias information

 

I'm having an issue where SROA will throw away no-alias information on some loads after inlining, because the loads are derived from a store to an alloca which can be removed after inlining.

 

The pointers that were originally stored into the alloca do not have any aliasing information - the only context that allowed me to assert aliasing was that the inlined-function guaranteed it to be so.

 

I know why SROA has done this - its just removing a store -> load on an alloca by forwarding the store, but is there anyway I can preserve the information that these pointers must no-alias?

 

Here is the pre/post from when SROA is run and you can see the now missing information of no-alias:

 

define dllexport void @"Burst.Compiler.IL.Tests.Aliasing.CheckInlinedFunctionPreservesAliasing(ref Burst.Compiler.IL.Tests.Aliasing.NoAliasWithContentsStruct s)_862A52BC559AC318"(%"Burst.Compiler.IL.Tests.Aliasing/NoAliasWithContentsStruct"* nocapture nonnull readonly %s) local_unnamed_addr #0 !ubaa. !1 {
entry:
  %var.0 = alloca %"Burst.Compiler.IL.Tests.Aliasing/NoAliasField", align 8
  %0 = bitcast %"Burst.Compiler.IL.Tests.Aliasing/NoAliasWithContentsStruct"* %s to i64*
  %1 = load i64, i64* %0, align 1
  %2 = getelementptr %"Burst.Compiler.IL.Tests.Aliasing/NoAliasWithContentsStruct", %"Burst.Compiler.IL.Tests.Aliasing/NoAliasWithContentsStruct"* %s, i64 0, i32 1
  %3 = bitcast i8** %2 to i64*
  %4 = load i64, i64* %3, align 1
  %5 = bitcast %"Burst.Compiler.IL.Tests.Aliasing/NoAliasField"* %var.0 to i64*
  store i64 %1, i64* %5, align 8
  %.fca.1.gep = getelementptr inbounds %"Burst.Compiler.IL.Tests.Aliasing/NoAliasField", %"Burst.Compiler.IL.Tests.Aliasing/NoAliasField"* %var.0, i64 0, i32 1
  %6 = bitcast i32** %.fca.1.gep to i64*
  store i64 %4, i64* %6, align 8
  %7 = bitcast %"Burst.Compiler.IL.Tests.Aliasing/NoAliasField"* %var.0 to i8**
  %8 = load i8*, i8** %7, align 1, !alias.scope !2, !noalias !5
  %9 = getelementptr %"Burst.Compiler.IL.Tests.Aliasing/NoAliasField", %"Burst.Compiler.IL.Tests.Aliasing/NoAliasField"* %var.0, i64 0, i32 1
  %10 = bitcast i32** %9 to i8**
  %11 = load i8*, i8** %10, align 1, !alias.scope !5, !noalias !2
  call void @llvm.ubaa.expect.no.alias(i8* %8, i64 -1, i8* %11, i64 -1, metadata !"C:\\Users\\NeilHenning\\Home\\burst\\src\\Burst.Compiler.IL.Tests\\Shared\\083-Aliasing.cs(229,9): ") #0
  ret void
}
*** IR Dump After SROA ***
; Function Attrs: nounwind
define dllexport void @"Burst.Compiler.IL.Tests.Aliasing.CheckInlinedFunctionPreservesAliasing(ref Burst.Compiler.IL.Tests.Aliasing.NoAliasWithContentsStruct s)_862A52BC559AC318"(%"Burst.Compiler.IL.Tests.Aliasing/NoAliasWithContentsStruct"* nocapture nonnull readonly %s) local_unnamed_addr #0 !ubaa. !1 {
entry:
  %0 = bitcast %"Burst.Compiler.IL.Tests.Aliasing/NoAliasWithContentsStruct"* %s to i64*
  %1 = load i64, i64* %0, align 1
  %2 = getelementptr %"Burst.Compiler.IL.Tests.Aliasing/NoAliasWithContentsStruct", %"Burst.Compiler.IL.Tests.Aliasing/NoAliasWithContentsStruct"* %s, i64 0, i32 1
  %3 = bitcast i8** %2 to i64*
  %4 = load i64, i64* %3, align 1
  %5 = inttoptr i64 %1 to i8*
  %6 = inttoptr i64 %4 to i8*
  call void @llvm.ubaa.expect.no.alias(i8* %5, i64 -1, i8* %6, i64 -1, metadata !"C:\\Users\\NeilHenning\\Home\\burst\\src\\Burst.Compiler.IL.Tests\\Shared\\083-Aliasing.cs(229,9): ") #0
  ret void
}

 

My only workaround I can dream up locally is to run a pass before SROA to do the alias.scope and noalias forwarding myself by looking back through the store...

 

Cheers,

-Neil.


--

Image removed by sender.

Neil Henning

Senior Software Engineer Compiler

 



--
Neil Henning
Senior Software Engineer Compiler

_______________________________________________
LLVM Developers mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev