[llvm-dev] Question on TBAA and optimization

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

[llvm-dev] Question on TBAA and optimization

Jeremy Morse via llvm-dev
TBAA Question.

Please consider the following test case.

---Snip--
struct B {
  int b1;
  int b2;
};

struct C {
 int b1;
};

struct A {
 int a1;
 struct C SC;
 int a2;
};

int foo1(struct A * Aptr, struct B* Bptr)
{
   int *a = &Aptr->SC.b1;
   *a=10;
   Bptr->b1 = 11;
   return *a;
}

int foo2(struct A * Aptr, struct B* Bptr)
{
   Aptr->SC.b1=10;
   Bptr->b1 = 11;
   return Aptr->SC.b1;
}
---Snip--

The structure pointers "Aptr" and "Bptr" will not alias each other in both the functions.
TBAA is able to figure that out in the case of "foo2". Hence it could propagate the  value "10" directly for return in "foo2".

--IR snippet ---

; Function Attrs: nounwind uwtable
define dso_local i32 @foo1(%struct.A* %Aptr, %struct.B* %Bptr) local_unnamed_addr #0 {
entry:
  %b1 = getelementptr inbounds %struct.A, %struct.A* %Aptr, i64 0, i32 1, i32 0
  store i32 10, i32* %b1, align 4, !tbaa !2
  %b11 = getelementptr inbounds %struct.B, %struct.B* %Bptr, i64 0, i32 0
  store i32 11, i32* %b11, align 4, !tbaa !6
  %0 = load i32, i32* %b1, align 4, !tbaa !2 <== reloads from memory.
  ret i32 %0
}

; Function Attrs: nounwind uwtable
define dso_local i32 @foo2(%struct.A* %Aptr, %struct.B* %Bptr) local_unnamed_addr #0 {
entry:
  %b1 = getelementptr inbounds %struct.A, %struct.A* %Aptr, i64 0, i32 1, i32 0
  store i32 10, i32* %b1, align 4, !tbaa !8
  %b11 = getelementptr inbounds %struct.B, %struct.B* %Bptr, i64 0, i32 0
  store i32 11, i32* %b11, align 4, !tbaa !6
  ret i32 10 <== returns 10
}
---IR snippet ---

I assume for both cases there is no possibility of memory aliasing. is my assumption wrong?
Why we are not optimizing the return for function "foo1"?  is that because TBAA is not formed in that case?

Please clarify.

regards,
Venkat.

_______________________________________________
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] Question on TBAA and optimization

Jeremy Morse via llvm-dev
Can someone clarify on this please?

On Thu, 28 Nov 2019 at 21:58, Venkataramanan Kumar <[hidden email]> wrote:
TBAA Question.

Please consider the following test case.

---Snip--
struct B {
  int b1;
  int b2;
};

struct C {
 int b1;
};

struct A {
 int a1;
 struct C SC;
 int a2;
};

int foo1(struct A * Aptr, struct B* Bptr)
{
   int *a = &Aptr->SC.b1;
   *a=10;
   Bptr->b1 = 11;
   return *a;
}

int foo2(struct A * Aptr, struct B* Bptr)
{
   Aptr->SC.b1=10;
   Bptr->b1 = 11;
   return Aptr->SC.b1;
}
---Snip--

The structure pointers "Aptr" and "Bptr" will not alias each other in both the functions.
TBAA is able to figure that out in the case of "foo2". Hence it could propagate the  value "10" directly for return in "foo2".

--IR snippet ---

; Function Attrs: nounwind uwtable
define dso_local i32 @foo1(%struct.A* %Aptr, %struct.B* %Bptr) local_unnamed_addr #0 {
entry:
  %b1 = getelementptr inbounds %struct.A, %struct.A* %Aptr, i64 0, i32 1, i32 0
  store i32 10, i32* %b1, align 4, !tbaa !2
  %b11 = getelementptr inbounds %struct.B, %struct.B* %Bptr, i64 0, i32 0
  store i32 11, i32* %b11, align 4, !tbaa !6
  %0 = load i32, i32* %b1, align 4, !tbaa !2 <== reloads from memory.
  ret i32 %0
}

; Function Attrs: nounwind uwtable
define dso_local i32 @foo2(%struct.A* %Aptr, %struct.B* %Bptr) local_unnamed_addr #0 {
entry:
  %b1 = getelementptr inbounds %struct.A, %struct.A* %Aptr, i64 0, i32 1, i32 0
  store i32 10, i32* %b1, align 4, !tbaa !8
  %b11 = getelementptr inbounds %struct.B, %struct.B* %Bptr, i64 0, i32 0
  store i32 11, i32* %b11, align 4, !tbaa !6
  ret i32 10 <== returns 10
}
---IR snippet ---

I assume for both cases there is no possibility of memory aliasing. is my assumption wrong?
Why we are not optimizing the return for function "foo1"?  is that because TBAA is not formed in that case?

Please clarify.

regards,
Venkat.

_______________________________________________
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] Question on TBAA and optimization

Jeremy Morse via llvm-dev
I can reproduce your results - its not forwarding the load from the previous store. I'm not sure why but none of the alias analysis passes are detecting that the two GEPs do not alias (they always come out as MayAlias) and I think its abandoning doing the store forwarding as a result.

You might want to file a bug for this?

Cheers,
-Neil.

On Mon, Dec 2, 2019 at 3:41 PM Venkataramanan Kumar via llvm-dev <[hidden email]> wrote:
Can someone clarify on this please?

On Thu, 28 Nov 2019 at 21:58, Venkataramanan Kumar <[hidden email]> wrote:
TBAA Question.

Please consider the following test case.

---Snip--
struct B {
  int b1;
  int b2;
};

struct C {
 int b1;
};

struct A {
 int a1;
 struct C SC;
 int a2;
};

int foo1(struct A * Aptr, struct B* Bptr)
{
   int *a = &Aptr->SC.b1;
   *a=10;
   Bptr->b1 = 11;
   return *a;
}

int foo2(struct A * Aptr, struct B* Bptr)
{
   Aptr->SC.b1=10;
   Bptr->b1 = 11;
   return Aptr->SC.b1;
}
---Snip--

The structure pointers "Aptr" and "Bptr" will not alias each other in both the functions.
TBAA is able to figure that out in the case of "foo2". Hence it could propagate the  value "10" directly for return in "foo2".

--IR snippet ---

; Function Attrs: nounwind uwtable
define dso_local i32 @foo1(%struct.A* %Aptr, %struct.B* %Bptr) local_unnamed_addr #0 {
entry:
  %b1 = getelementptr inbounds %struct.A, %struct.A* %Aptr, i64 0, i32 1, i32 0
  store i32 10, i32* %b1, align 4, !tbaa !2
  %b11 = getelementptr inbounds %struct.B, %struct.B* %Bptr, i64 0, i32 0
  store i32 11, i32* %b11, align 4, !tbaa !6
  %0 = load i32, i32* %b1, align 4, !tbaa !2 <== reloads from memory.
  ret i32 %0
}

; Function Attrs: nounwind uwtable
define dso_local i32 @foo2(%struct.A* %Aptr, %struct.B* %Bptr) local_unnamed_addr #0 {
entry:
  %b1 = getelementptr inbounds %struct.A, %struct.A* %Aptr, i64 0, i32 1, i32 0
  store i32 10, i32* %b1, align 4, !tbaa !8
  %b11 = getelementptr inbounds %struct.B, %struct.B* %Bptr, i64 0, i32 0
  store i32 11, i32* %b11, align 4, !tbaa !6
  ret i32 10 <== returns 10
}
---IR snippet ---

I assume for both cases there is no possibility of memory aliasing. is my assumption wrong?
Why we are not optimizing the return for function "foo1"?  is that because TBAA is not formed in that case?

Please clarify.

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


--
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] Question on TBAA and optimization

Jeremy Morse via llvm-dev
Sure I will create a PR for this.
regards,
Venkat.

On Tue, 3 Dec 2019 at 15:02, Neil Henning <[hidden email]> wrote:
I can reproduce your results - its not forwarding the load from the previous store. I'm not sure why but none of the alias analysis passes are detecting that the two GEPs do not alias (they always come out as MayAlias) and I think its abandoning doing the store forwarding as a result.

You might want to file a bug for this?

Cheers,
-Neil.

On Mon, Dec 2, 2019 at 3:41 PM Venkataramanan Kumar via llvm-dev <[hidden email]> wrote:
Can someone clarify on this please?

On Thu, 28 Nov 2019 at 21:58, Venkataramanan Kumar <[hidden email]> wrote:
TBAA Question.

Please consider the following test case.

---Snip--
struct B {
  int b1;
  int b2;
};

struct C {
 int b1;
};

struct A {
 int a1;
 struct C SC;
 int a2;
};

int foo1(struct A * Aptr, struct B* Bptr)
{
   int *a = &Aptr->SC.b1;
   *a=10;
   Bptr->b1 = 11;
   return *a;
}

int foo2(struct A * Aptr, struct B* Bptr)
{
   Aptr->SC.b1=10;
   Bptr->b1 = 11;
   return Aptr->SC.b1;
}
---Snip--

The structure pointers "Aptr" and "Bptr" will not alias each other in both the functions.
TBAA is able to figure that out in the case of "foo2". Hence it could propagate the  value "10" directly for return in "foo2".

--IR snippet ---

; Function Attrs: nounwind uwtable
define dso_local i32 @foo1(%struct.A* %Aptr, %struct.B* %Bptr) local_unnamed_addr #0 {
entry:
  %b1 = getelementptr inbounds %struct.A, %struct.A* %Aptr, i64 0, i32 1, i32 0
  store i32 10, i32* %b1, align 4, !tbaa !2
  %b11 = getelementptr inbounds %struct.B, %struct.B* %Bptr, i64 0, i32 0
  store i32 11, i32* %b11, align 4, !tbaa !6
  %0 = load i32, i32* %b1, align 4, !tbaa !2 <== reloads from memory.
  ret i32 %0
}

; Function Attrs: nounwind uwtable
define dso_local i32 @foo2(%struct.A* %Aptr, %struct.B* %Bptr) local_unnamed_addr #0 {
entry:
  %b1 = getelementptr inbounds %struct.A, %struct.A* %Aptr, i64 0, i32 1, i32 0
  store i32 10, i32* %b1, align 4, !tbaa !8
  %b11 = getelementptr inbounds %struct.B, %struct.B* %Bptr, i64 0, i32 0
  store i32 11, i32* %b11, align 4, !tbaa !6
  ret i32 10 <== returns 10
}
---IR snippet ---

I assume for both cases there is no possibility of memory aliasing. is my assumption wrong?
Why we are not optimizing the return for function "foo1"?  is that because TBAA is not formed in that case?

Please clarify.

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


--
Neil Henning
Senior Software Engineer Compiler

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