[llvm] Inline: Fix handling of byval using non-alloca addrspace (PR #97306)

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 1 11:05:19 PDT 2024


https://github.com/arsenm updated https://github.com/llvm/llvm-project/pull/97306

>From 77ceba2f579a0d685c4c99df765cf84b5626ef82 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Mon, 1 Jul 2024 16:44:34 +0200
Subject: [PATCH 1/3] Inline: Fix handling of byval using non-alloca addrspace

Use the address space of the original pointer argument instead
of querying the datalayout. This avoids producing a verifier error
since this was changing the address space for the user instructions.

Fixes #97086
---
 llvm/lib/Transforms/Utils/InlineFunction.cpp  |  5 ++-
 .../Inline/byval-with-non-alloca-addrspace.ll | 38 +++++++++++++++++++
 2 files changed, 41 insertions(+), 2 deletions(-)
 create mode 100644 llvm/test/Transforms/Inline/byval-with-non-alloca-addrspace.ll

diff --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp b/llvm/lib/Transforms/Utils/InlineFunction.cpp
index 0725addfbb90a..46605492490ea 100644
--- a/llvm/lib/Transforms/Utils/InlineFunction.cpp
+++ b/llvm/lib/Transforms/Utils/InlineFunction.cpp
@@ -1674,8 +1674,9 @@ static Value *HandleByValArgument(Type *ByValType, Value *Arg,
   if (ByValAlignment)
     Alignment = std::max(Alignment, *ByValAlignment);
 
-  AllocaInst *NewAlloca = new AllocaInst(ByValType, DL.getAllocaAddrSpace(),
-                                         nullptr, Alignment, Arg->getName());
+  AllocaInst *NewAlloca = new AllocaInst(
+      ByValType, cast<PointerType>(Arg->getType())->getAddressSpace(), nullptr,
+      Alignment, Arg->getName());
   NewAlloca->insertBefore(Caller->begin()->begin());
   IFI.StaticAllocas.push_back(NewAlloca);
 
diff --git a/llvm/test/Transforms/Inline/byval-with-non-alloca-addrspace.ll b/llvm/test/Transforms/Inline/byval-with-non-alloca-addrspace.ll
new file mode 100644
index 0000000000000..42ec0f2bf5699
--- /dev/null
+++ b/llvm/test/Transforms/Inline/byval-with-non-alloca-addrspace.ll
@@ -0,0 +1,38 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt -S -passes=always-inline %s | FileCheck %s
+
+; The byval parameters use a different address space from the alloca
+; address space. Make sure this is gracefully handled by using the
+; original byval pointer type's address space instead of what the
+; datalayout says to use.
+
+target datalayout = "A5"
+
+%struct = type { i64, i64 }
+
+define i64 @bar(ptr byval(%struct) %a) alwaysinline {
+; CHECK-LABEL: define i64 @bar(
+; CHECK-SAME: ptr byval([[STRUCT:%.*]]) [[A:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr [[STRUCT]], ptr [[A]], i64 0, i32 1
+; CHECK-NEXT:    [[TMP2:%.*]] = load i64, ptr [[TMP1]], align 4
+; CHECK-NEXT:    ret i64 0
+;
+  %1 = getelementptr %struct, ptr %a, i64 0, i32 1
+  %2 = load i64, ptr %1, align 4
+  ret i64 0
+}
+
+define i64 @foo(ptr %arg) {
+; CHECK-LABEL: define i64 @foo(
+; CHECK-SAME: ptr [[ARG:%.*]]) {
+; CHECK-NEXT:    [[ARG1:%.*]] = alloca [[STRUCT:%.*]], align 8
+; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 16, ptr [[ARG1]])
+; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 1 [[ARG1]], ptr align 1 [[ARG]], i64 16, i1 false)
+; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr [[STRUCT]], ptr [[ARG1]], i64 0, i32 1
+; CHECK-NEXT:    [[TMP2:%.*]] = load i64, ptr [[TMP1]], align 4
+; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 16, ptr [[ARG1]])
+; CHECK-NEXT:    ret i64 0
+;
+  %1 = call i64 @bar(ptr byval(%struct) align 8 %arg)
+  ret i64 0
+}

>From 7fa34cd79023f3c4257193161a2f7291ff82b6d9 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Mon, 1 Jul 2024 17:57:22 +0200
Subject: [PATCH 2/3] Update InlineFunction.cpp

Co-authored-by: Nikita Popov <npopov at redhat.com>
---
 llvm/lib/Transforms/Utils/InlineFunction.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp b/llvm/lib/Transforms/Utils/InlineFunction.cpp
index 46605492490ea..cfcc658f74967 100644
--- a/llvm/lib/Transforms/Utils/InlineFunction.cpp
+++ b/llvm/lib/Transforms/Utils/InlineFunction.cpp
@@ -1675,7 +1675,7 @@ static Value *HandleByValArgument(Type *ByValType, Value *Arg,
     Alignment = std::max(Alignment, *ByValAlignment);
 
   AllocaInst *NewAlloca = new AllocaInst(
-      ByValType, cast<PointerType>(Arg->getType())->getAddressSpace(), nullptr,
+      ByValType, Arg->getType()->getPointerAddressSpace(), nullptr,
       Alignment, Arg->getName());
   NewAlloca->insertBefore(Caller->begin()->begin());
   IFI.StaticAllocas.push_back(NewAlloca);

>From 4cc0aa4c2947bd6ecb11d354e9080613b3e9f241 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Mon, 1 Jul 2024 20:05:03 +0200
Subject: [PATCH 3/3] Run clang-format

---
 llvm/lib/Transforms/Utils/InlineFunction.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp b/llvm/lib/Transforms/Utils/InlineFunction.cpp
index cfcc658f74967..036527c797e89 100644
--- a/llvm/lib/Transforms/Utils/InlineFunction.cpp
+++ b/llvm/lib/Transforms/Utils/InlineFunction.cpp
@@ -1674,9 +1674,9 @@ static Value *HandleByValArgument(Type *ByValType, Value *Arg,
   if (ByValAlignment)
     Alignment = std::max(Alignment, *ByValAlignment);
 
-  AllocaInst *NewAlloca = new AllocaInst(
-      ByValType, Arg->getType()->getPointerAddressSpace(), nullptr,
-      Alignment, Arg->getName());
+  AllocaInst *NewAlloca =
+      new AllocaInst(ByValType, Arg->getType()->getPointerAddressSpace(),
+                     nullptr, Alignment, Arg->getName());
   NewAlloca->insertBefore(Caller->begin()->begin());
   IFI.StaticAllocas.push_back(NewAlloca);
 



More information about the llvm-commits mailing list