[llvm] Local: Handle noalias_addrspace in combineMetadata (PR #103938)

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 25 18:27:49 PDT 2024


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

>From 916880dcacd35ea2ed504cc37bb9ccd49fa46353 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Wed, 14 Aug 2024 16:19:30 +0400
Subject: [PATCH 1/6] Local: Handle noalias_addrspace in combineMetadata

This should act like range.
---
 llvm/lib/Transforms/Utils/Local.cpp                     | 7 ++++++-
 llvm/test/Transforms/SimplifyCFG/hoist-with-metadata.ll | 6 ++++--
 2 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp
index 65c1669f92b4d3..6804e4d6bac574 100644
--- a/llvm/lib/Transforms/Utils/Local.cpp
+++ b/llvm/lib/Transforms/Utils/Local.cpp
@@ -3391,6 +3391,10 @@ void llvm::combineMetadata(Instruction *K, const Instruction *J,
         if (DoesKMove)
           K->setMetadata(Kind, MDNode::getMergedProfMetadata(KMD, JMD, K, J));
         break;
+      case LLVMContext::MD_noalias_addrspace:
+        if (DoesKMove)
+          K->setMetadata(Kind, MDNode::getMostGenericRange(JMD, KMD));
+        break;
     }
   }
   // Set !invariant.group from J if J has it. If both instructions have it
@@ -3432,7 +3436,8 @@ void llvm::combineMetadataForCSE(Instruction *K, const Instruction *J,
                          LLVMContext::MD_prof,
                          LLVMContext::MD_nontemporal,
                          LLVMContext::MD_noundef,
-                         LLVMContext::MD_mmra};
+                         LLVMContext::MD_mmra,
+                         LLVMContext::MD_noalias_addrspace};
   combineMetadata(K, J, KnownIDs, KDominatesJ);
 }
 
diff --git a/llvm/test/Transforms/SimplifyCFG/hoist-with-metadata.ll b/llvm/test/Transforms/SimplifyCFG/hoist-with-metadata.ll
index 18aa5c9e044a98..f8985e78c0ca57 100644
--- a/llvm/test/Transforms/SimplifyCFG/hoist-with-metadata.ll
+++ b/llvm/test/Transforms/SimplifyCFG/hoist-with-metadata.ll
@@ -319,7 +319,7 @@ out:
 define void @hoist_noalias_addrspace_both(i1 %c, ptr %p, i64 %val) {
 ; CHECK-LABEL: @hoist_noalias_addrspace_both(
 ; CHECK-NEXT:  if:
-; CHECK-NEXT:    [[T:%.*]] = atomicrmw add ptr [[P:%.*]], i64 [[VAL:%.*]] seq_cst, align 8
+; CHECK-NEXT:    [[T:%.*]] = atomicrmw add ptr [[P:%.*]], i64 [[VAL:%.*]] seq_cst, align 8, !noalias.addrspace [[META7:![0-9]+]]
 ; CHECK-NEXT:    ret void
 ;
 if:
@@ -361,7 +361,7 @@ out:
 define void @hoist_noalias_addrspace_switch(i64 %i, ptr %p, i64 %val) {
 ; CHECK-LABEL: @hoist_noalias_addrspace_switch(
 ; CHECK-NEXT:  out:
-; CHECK-NEXT:    [[T:%.*]] = atomicrmw add ptr [[P:%.*]], i64 [[VAL:%.*]] seq_cst, align 8
+; CHECK-NEXT:    [[T:%.*]] = atomicrmw add ptr [[P:%.*]], i64 [[VAL:%.*]] seq_cst, align 8, !noalias.addrspace [[META8:![0-9]+]]
 ; CHECK-NEXT:    ret void
 ;
   switch i64 %i, label %bb0 [
@@ -398,4 +398,6 @@ out:
 ; CHECK: [[RNG4]] = !{i32 0, i32 10}
 ; CHECK: [[META5]] = !{i64 4}
 ; CHECK: [[META6]] = !{float 2.500000e+00}
+; CHECK: [[META7]] = !{i32 5, i32 6}
+; CHECK: [[META8]] = !{i32 4, i32 8}
 ;.

>From 7a2702f60543c187ad05e8904120cd7065a0d6cd Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Tue, 8 Oct 2024 14:47:22 +0400
Subject: [PATCH 2/6] Add another test with ranges

---
 .../SimplifyCFG/hoist-with-metadata.ll        | 26 +++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/llvm/test/Transforms/SimplifyCFG/hoist-with-metadata.ll b/llvm/test/Transforms/SimplifyCFG/hoist-with-metadata.ll
index f8985e78c0ca57..ec58c84cef827f 100644
--- a/llvm/test/Transforms/SimplifyCFG/hoist-with-metadata.ll
+++ b/llvm/test/Transforms/SimplifyCFG/hoist-with-metadata.ll
@@ -381,6 +381,28 @@ out:
   ret void
 }
 
+define void @hoist_noalias_addrspace_switch_multiple(i64 %i, ptr %p, i64 %val) {
+; CHECK-LABEL: @hoist_noalias_addrspace_switch_multiple(
+; CHECK-NEXT:  out:
+; CHECK-NEXT:    [[T:%.*]] = atomicrmw add ptr [[P:%.*]], i64 [[VAL:%.*]] seq_cst, align 8, !noalias.addrspace [[META9:![0-9]+]]
+; CHECK-NEXT:    ret void
+;
+  switch i64 %i, label %bb0 [
+  i64 1, label %bb1
+  i64 2, label %bb2
+  ]
+bb0:
+  %t = atomicrmw add ptr %p, i64 %val seq_cst, !noalias.addrspace !7
+  br label %out
+bb1:
+  %e = atomicrmw add ptr %p, i64 %val seq_cst, !noalias.addrspace !8
+  br label %out
+bb2:
+  %f = atomicrmw add ptr %p, i64 %val seq_cst, !noalias.addrspace !9
+  br label %out
+out:
+  ret void
+}
 
 !0 = !{ i8 0, i8 1 }
 !1 = !{ i8 3, i8 5 }
@@ -389,6 +411,9 @@ out:
 !4 = !{i32 5, i32 6}
 !5 = !{i32 5, i32 7}
 !6 = !{i32 4, i32 8}
+!7 = !{i32 4, i32 8, i32 20, i32 31}
+!8 = !{i32 2, i32 5}
+!9 = !{i32 2, i32 5, i32 22, i32 42, i32 45, i32 50}
 
 ;.
 ; CHECK: [[RNG0]] = !{i8 0, i8 1, i8 3, i8 5}
@@ -400,4 +425,5 @@ out:
 ; CHECK: [[META6]] = !{float 2.500000e+00}
 ; CHECK: [[META7]] = !{i32 5, i32 6}
 ; CHECK: [[META8]] = !{i32 4, i32 8}
+; CHECK: [[META9]] = !{i32 2, i32 8, i32 20, i32 42, i32 45, i32 50}
 ;.

>From 1f67e1977383e12f7a7928ce55e4a81fb260c2c7 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Tue, 8 Oct 2024 20:18:26 +0400
Subject: [PATCH 3/6] Correctly intersect

---
 llvm/include/llvm/IR/ConstantRangeList.h      |  4 +-
 llvm/include/llvm/IR/Metadata.h               |  1 +
 llvm/lib/IR/ConstantRangeList.cpp             | 15 +++++---
 llvm/lib/IR/Metadata.cpp                      | 38 +++++++++++++++++++
 llvm/lib/Transforms/Utils/Local.cpp           |  3 +-
 .../SimplifyCFG/hoist-with-metadata.ll        |  7 ++--
 6 files changed, 55 insertions(+), 13 deletions(-)

diff --git a/llvm/include/llvm/IR/ConstantRangeList.h b/llvm/include/llvm/IR/ConstantRangeList.h
index 44d1daebe49e4a..c8611a416e5eb4 100644
--- a/llvm/include/llvm/IR/ConstantRangeList.h
+++ b/llvm/include/llvm/IR/ConstantRangeList.h
@@ -35,7 +35,7 @@ class [[nodiscard]] ConstantRangeList {
   ConstantRangeList(ArrayRef<ConstantRange> RangesRef) {
     assert(isOrderedRanges(RangesRef));
     for (const ConstantRange &R : RangesRef) {
-      assert(R.getBitWidth() == getBitWidth());
+      assert(empty() || R.getBitWidth() == getBitWidth());
       Ranges.push_back(R);
     }
   }
@@ -60,7 +60,7 @@ class [[nodiscard]] ConstantRangeList {
   bool empty() const { return Ranges.empty(); }
 
   /// Get the bit width of this ConstantRangeList.
-  uint32_t getBitWidth() const { return 64; }
+  uint32_t getBitWidth() const { return Ranges.front().getBitWidth(); }
 
   /// Return the number of ranges in this ConstantRangeList.
   size_t size() const { return Ranges.size(); }
diff --git a/llvm/include/llvm/IR/Metadata.h b/llvm/include/llvm/IR/Metadata.h
index 70882767545164..35580f3f38c615 100644
--- a/llvm/include/llvm/IR/Metadata.h
+++ b/llvm/include/llvm/IR/Metadata.h
@@ -1456,6 +1456,7 @@ class MDNode : public Metadata {
   static MDNode *getMostGenericTBAA(MDNode *A, MDNode *B);
   static MDNode *getMostGenericFPMath(MDNode *A, MDNode *B);
   static MDNode *getMostGenericRange(MDNode *A, MDNode *B);
+  static MDNode *getMostGenericNoaliasAddrspace(MDNode *A, MDNode *B);
   static MDNode *getMostGenericAliasScope(MDNode *A, MDNode *B);
   static MDNode *getMostGenericAlignmentOrDereferenceable(MDNode *A, MDNode *B);
   /// Merge !prof metadata from two instructions.
diff --git a/llvm/lib/IR/ConstantRangeList.cpp b/llvm/lib/IR/ConstantRangeList.cpp
index 0856f79bb9191a..3ee8d6f22b7487 100644
--- a/llvm/lib/IR/ConstantRangeList.cpp
+++ b/llvm/lib/IR/ConstantRangeList.cpp
@@ -39,12 +39,14 @@ void ConstantRangeList::insert(const ConstantRange &NewRange) {
     return;
   assert(!NewRange.isFullSet() && "Do not support full set");
   assert(NewRange.getLower().slt(NewRange.getUpper()));
-  assert(getBitWidth() == NewRange.getBitWidth());
   // Handle common cases.
   if (empty() || Ranges.back().getUpper().slt(NewRange.getLower())) {
     Ranges.push_back(NewRange);
     return;
   }
+
+  assert(getBitWidth() == NewRange.getBitWidth());
+
   if (NewRange.getUpper().slt(Ranges.front().getLower())) {
     Ranges.insert(Ranges.begin(), NewRange);
     return;
@@ -142,14 +144,15 @@ void ConstantRangeList::subtract(const ConstantRange &SubRange) {
 
 ConstantRangeList
 ConstantRangeList::unionWith(const ConstantRangeList &CRL) const {
-  assert(getBitWidth() == CRL.getBitWidth() &&
-         "ConstantRangeList bitwidths don't agree!");
   // Handle common cases.
   if (empty())
     return CRL;
   if (CRL.empty())
     return *this;
 
+  assert(getBitWidth() == CRL.getBitWidth() &&
+         "ConstantRangeList bitwidths don't agree!");
+
   ConstantRangeList Result;
   size_t i = 0, j = 0;
   // "PreviousRange" tracks the lowest unioned range that is being processed.
@@ -192,15 +195,15 @@ ConstantRangeList::unionWith(const ConstantRangeList &CRL) const {
 
 ConstantRangeList
 ConstantRangeList::intersectWith(const ConstantRangeList &CRL) const {
-  assert(getBitWidth() == CRL.getBitWidth() &&
-         "ConstantRangeList bitwidths don't agree!");
-
   // Handle common cases.
   if (empty())
     return *this;
   if (CRL.empty())
     return CRL;
 
+  assert(getBitWidth() == CRL.getBitWidth() &&
+         "ConstantRangeList bitwidths don't agree!");
+
   ConstantRangeList Result;
   size_t i = 0, j = 0;
   while (i < size() && j < CRL.size()) {
diff --git a/llvm/lib/IR/Metadata.cpp b/llvm/lib/IR/Metadata.cpp
index ea2d1dc8440bce..5124e8ec38a0a5 100644
--- a/llvm/lib/IR/Metadata.cpp
+++ b/llvm/lib/IR/Metadata.cpp
@@ -29,6 +29,7 @@
 #include "llvm/IR/BasicBlock.h"
 #include "llvm/IR/Constant.h"
 #include "llvm/IR/ConstantRange.h"
+#include "llvm/IR/ConstantRangeList.h"
 #include "llvm/IR/Constants.h"
 #include "llvm/IR/DebugInfoMetadata.h"
 #include "llvm/IR/DebugLoc.h"
@@ -1354,6 +1355,43 @@ MDNode *MDNode::getMostGenericRange(MDNode *A, MDNode *B) {
   return MDNode::get(A->getContext(), MDs);
 }
 
+MDNode *MDNode::getMostGenericNoaliasAddrspace(MDNode *A, MDNode *B) {
+  if (!A || !B)
+    return nullptr;
+
+  if (A == B)
+    return A;
+
+  SmallVector<ConstantRange> RangeListA, RangeListB;
+  for (unsigned I = 0, E = A->getNumOperands() / 2; I != E; ++I) {
+    auto *LowA = mdconst::extract<ConstantInt>(A->getOperand(2 * I + 0));
+    auto *HighA = mdconst::extract<ConstantInt>(A->getOperand(2 * I + 1));
+    RangeListA.push_back(ConstantRange(LowA->getValue(), HighA->getValue()));
+  }
+
+  for (unsigned I = 0, E = B->getNumOperands() / 2; I != E; ++I) {
+    auto *LowB = mdconst::extract<ConstantInt>(B->getOperand(2 * I + 0));
+    auto *HighB = mdconst::extract<ConstantInt>(B->getOperand(2 * I + 1));
+    RangeListB.push_back(ConstantRange(LowB->getValue(), HighB->getValue()));
+  }
+
+  ConstantRangeList CRLA(RangeListA);
+  ConstantRangeList CRLB(RangeListB);
+  ConstantRangeList Result = CRLA.intersectWith(CRLB);
+  if (Result.empty())
+    return nullptr;
+
+  SmallVector<Metadata *> MDs;
+  for (const ConstantRange &CR : Result) {
+    MDs.push_back(ConstantAsMetadata::get(
+        ConstantInt::get(A->getContext(), CR.getLower())));
+    MDs.push_back(ConstantAsMetadata::get(
+        ConstantInt::get(A->getContext(), CR.getUpper())));
+  }
+
+  return MDNode::get(A->getContext(), MDs);
+}
+
 MDNode *MDNode::getMostGenericAlignmentOrDereferenceable(MDNode *A, MDNode *B) {
   if (!A || !B)
     return nullptr;
diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp
index 6804e4d6bac574..ae4431c0d54014 100644
--- a/llvm/lib/Transforms/Utils/Local.cpp
+++ b/llvm/lib/Transforms/Utils/Local.cpp
@@ -3393,7 +3393,8 @@ void llvm::combineMetadata(Instruction *K, const Instruction *J,
         break;
       case LLVMContext::MD_noalias_addrspace:
         if (DoesKMove)
-          K->setMetadata(Kind, MDNode::getMostGenericRange(JMD, KMD));
+          K->setMetadata(Kind,
+                         MDNode::getMostGenericNoaliasAddrspace(JMD, KMD));
         break;
     }
   }
diff --git a/llvm/test/Transforms/SimplifyCFG/hoist-with-metadata.ll b/llvm/test/Transforms/SimplifyCFG/hoist-with-metadata.ll
index ec58c84cef827f..96de04b4c5ed87 100644
--- a/llvm/test/Transforms/SimplifyCFG/hoist-with-metadata.ll
+++ b/llvm/test/Transforms/SimplifyCFG/hoist-with-metadata.ll
@@ -361,7 +361,7 @@ out:
 define void @hoist_noalias_addrspace_switch(i64 %i, ptr %p, i64 %val) {
 ; CHECK-LABEL: @hoist_noalias_addrspace_switch(
 ; CHECK-NEXT:  out:
-; CHECK-NEXT:    [[T:%.*]] = atomicrmw add ptr [[P:%.*]], i64 [[VAL:%.*]] seq_cst, align 8, !noalias.addrspace [[META8:![0-9]+]]
+; CHECK-NEXT:    [[T:%.*]] = atomicrmw add ptr [[P:%.*]], i64 [[VAL:%.*]] seq_cst, align 8, !noalias.addrspace [[META7]]
 ; CHECK-NEXT:    ret void
 ;
   switch i64 %i, label %bb0 [
@@ -384,7 +384,7 @@ out:
 define void @hoist_noalias_addrspace_switch_multiple(i64 %i, ptr %p, i64 %val) {
 ; CHECK-LABEL: @hoist_noalias_addrspace_switch_multiple(
 ; CHECK-NEXT:  out:
-; CHECK-NEXT:    [[T:%.*]] = atomicrmw add ptr [[P:%.*]], i64 [[VAL:%.*]] seq_cst, align 8, !noalias.addrspace [[META9:![0-9]+]]
+; CHECK-NEXT:    [[T:%.*]] = atomicrmw add ptr [[P:%.*]], i64 [[VAL:%.*]] seq_cst, align 8, !noalias.addrspace [[META8:![0-9]+]]
 ; CHECK-NEXT:    ret void
 ;
   switch i64 %i, label %bb0 [
@@ -424,6 +424,5 @@ out:
 ; CHECK: [[META5]] = !{i64 4}
 ; CHECK: [[META6]] = !{float 2.500000e+00}
 ; CHECK: [[META7]] = !{i32 5, i32 6}
-; CHECK: [[META8]] = !{i32 4, i32 8}
-; CHECK: [[META9]] = !{i32 2, i32 8, i32 20, i32 42, i32 45, i32 50}
+; CHECK: [[META8]] = !{i32 4, i32 5}
 ;.

>From 17797f062ea12e284b87b0089888b964a2749ea5 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Tue, 8 Oct 2024 21:05:01 +0400
Subject: [PATCH 4/6] Add !DoesKMove test

---
 .../Transforms/EarlyCSE/noalias-addrspace.ll  | 73 +++++++++++++++++++
 1 file changed, 73 insertions(+)
 create mode 100644 llvm/test/Transforms/EarlyCSE/noalias-addrspace.ll

diff --git a/llvm/test/Transforms/EarlyCSE/noalias-addrspace.ll b/llvm/test/Transforms/EarlyCSE/noalias-addrspace.ll
new file mode 100644
index 00000000000000..0a001b55f684cf
--- /dev/null
+++ b/llvm/test/Transforms/EarlyCSE/noalias-addrspace.ll
@@ -0,0 +1,73 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt -passes='early-cse<memssa>' -S < %s | FileCheck %s
+
+declare void @use(i1)
+declare void @use.ptr(ptr) memory(read)
+
+define void @load_first_noalias_addrspace(ptr %p) {
+; CHECK-LABEL: define void @load_first_noalias_addrspace(
+; CHECK-SAME: ptr [[P:%.*]]) {
+; CHECK-NEXT:    [[V1:%.*]] = load ptr, ptr [[P]], align 8, !nonnull [[META0:![0-9]+]], !noundef [[META0]], !noalias.addrspace [[META1:![0-9]+]]
+; CHECK-NEXT:    call void @use.ptr(ptr [[V1]])
+; CHECK-NEXT:    call void @use.ptr(ptr [[V1]])
+; CHECK-NEXT:    ret void
+;
+  %v1 = load ptr, ptr %p, !nonnull !{}, !noundef !{}, !noalias.addrspace !0
+  call void @use.ptr(ptr %v1)
+  %v2 = load ptr, ptr %p
+  call void @use.ptr(ptr %v2)
+  ret void
+}
+
+define void @load_both_same_noalias_addrspace(ptr %p) {
+; CHECK-LABEL: define void @load_both_same_noalias_addrspace(
+; CHECK-SAME: ptr [[P:%.*]]) {
+; CHECK-NEXT:    [[V1:%.*]] = load ptr, ptr [[P]], align 8, !nonnull [[META0]], !noundef [[META0]], !noalias.addrspace [[META1]]
+; CHECK-NEXT:    call void @use.ptr(ptr [[V1]])
+; CHECK-NEXT:    call void @use.ptr(ptr [[V1]])
+; CHECK-NEXT:    ret void
+;
+  %v1 = load ptr, ptr %p, !nonnull !{}, !noundef !{}, !noalias.addrspace !0
+  call void @use.ptr(ptr %v1)
+  %v2 = load ptr, ptr %p, !noalias.addrspace !0
+  call void @use.ptr(ptr %v2)
+  ret void
+}
+
+define void @load_both_disjoint_noalias_addrspace(ptr %p) {
+; CHECK-LABEL: define void @load_both_disjoint_noalias_addrspace(
+; CHECK-SAME: ptr [[P:%.*]]) {
+; CHECK-NEXT:    [[V1:%.*]] = load ptr, ptr [[P]], align 8, !nonnull [[META0]], !noundef [[META0]], !noalias.addrspace [[META1]]
+; CHECK-NEXT:    call void @use.ptr(ptr [[V1]])
+; CHECK-NEXT:    call void @use.ptr(ptr [[V1]])
+; CHECK-NEXT:    ret void
+;
+  %v1 = load ptr, ptr %p, !nonnull !{}, !noundef !{}, !noalias.addrspace !0
+  call void @use.ptr(ptr %v1)
+  %v2 = load ptr, ptr %p, !noalias.addrspace !1
+  call void @use.ptr(ptr %v2)
+  ret void
+}
+
+define void @load_both_overlap_noalias_addrspace(ptr %p) {
+; CHECK-LABEL: define void @load_both_overlap_noalias_addrspace(
+; CHECK-SAME: ptr [[P:%.*]]) {
+; CHECK-NEXT:    [[V1:%.*]] = load ptr, ptr [[P]], align 8, !nonnull [[META0]], !noundef [[META0]], !noalias.addrspace [[META1]]
+; CHECK-NEXT:    call void @use.ptr(ptr [[V1]])
+; CHECK-NEXT:    call void @use.ptr(ptr [[V1]])
+; CHECK-NEXT:    ret void
+;
+  %v1 = load ptr, ptr %p, !nonnull !{}, !noundef !{}, !noalias.addrspace !0
+  call void @use.ptr(ptr %v1)
+  %v2 = load ptr, ptr %p, !noalias.addrspace !2
+  call void @use.ptr(ptr %v2)
+  ret void
+}
+
+!0 = !{i32 5, i32 6}
+!1 = !{i32 7, i32 8}
+!2 = !{i32 5, i32 7}
+;.
+; CHECK: [[META0]] = !{}
+; CHECK: [[META1]] = !{i32 5, i32 6}
+;.

>From 40b372883f26b9596671550795ed0531eeb2ed04 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Tue, 8 Oct 2024 21:58:54 +0400
Subject: [PATCH 5/6] Add speculation test that shows noalias_addrspace is
 dropped

---
 .../SimplifyCFG/hoist-with-metadata.ll        | 20 +++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/llvm/test/Transforms/SimplifyCFG/hoist-with-metadata.ll b/llvm/test/Transforms/SimplifyCFG/hoist-with-metadata.ll
index 96de04b4c5ed87..d34ac2bb300407 100644
--- a/llvm/test/Transforms/SimplifyCFG/hoist-with-metadata.ll
+++ b/llvm/test/Transforms/SimplifyCFG/hoist-with-metadata.ll
@@ -404,6 +404,26 @@ out:
   ret void
 }
 
+; !noalias_addrspace is not safe to speculate as it causes immediate undefined behavior.
+define ptr @speculate_noalias_addrspace(i1 %c, ptr dereferenceable(8) align 8 %p) {
+; CHECK-LABEL: @speculate_noalias_addrspace(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[V:%.*]] = load ptr, ptr [[P:%.*]], align 8, !nonnull [[META2]]
+; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[C:%.*]], ptr [[V]], ptr null
+; CHECK-NEXT:    ret ptr [[SPEC_SELECT]]
+;
+entry:
+  br i1 %c, label %if, label %join
+
+if:
+  %v = load ptr, ptr %p, !nonnull !{}, !noundef !{}, !noalias.addrspace !4
+  br label %join
+
+join:
+  %phi = phi ptr [ %v, %if ], [ null, %entry ]
+  ret ptr %phi
+}
+
 !0 = !{ i8 0, i8 1 }
 !1 = !{ i8 3, i8 5 }
 !2 = !{}

>From 74249904f0713902598379deef718a3c2c3926d5 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Fri, 25 Oct 2024 18:25:12 -0700
Subject: [PATCH 6/6] Add comment

---
 llvm/include/llvm/IR/ConstantRangeList.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/llvm/include/llvm/IR/ConstantRangeList.h b/llvm/include/llvm/IR/ConstantRangeList.h
index c8611a416e5eb4..b12c913103df57 100644
--- a/llvm/include/llvm/IR/ConstantRangeList.h
+++ b/llvm/include/llvm/IR/ConstantRangeList.h
@@ -59,7 +59,8 @@ class [[nodiscard]] ConstantRangeList {
   /// Return true if this list contains no members.
   bool empty() const { return Ranges.empty(); }
 
-  /// Get the bit width of this ConstantRangeList.
+  /// Get the bit width of this ConstantRangeList. It is invalid to call this
+  /// with an empty range.
   uint32_t getBitWidth() const { return Ranges.front().getBitWidth(); }
 
   /// Return the number of ranges in this ConstantRangeList.



More information about the llvm-commits mailing list