[llvm] [IR] Reject unhandled assume bundles and seperate them from normal attributes (PR #197007)

via llvm-commits llvm-commits at lists.llvm.org
Mon May 11 10:54:54 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-transforms

Author: Nikolas Klauser (philnik777)

<details>
<summary>Changes</summary>



---

Patch is 61.37 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/197007.diff


19 Files Affected:

- (added) llvm/include/llvm/IR/BundleAttributes.def (+18) 
- (added) llvm/include/llvm/IR/BundleAttributes.h (+62) 
- (modified) llvm/include/llvm/IR/InstrTypes.h (+6) 
- (modified) llvm/include/llvm/Transforms/Utils/PredicateInfo.h (+3-2) 
- (modified) llvm/lib/Analysis/LazyValueInfo.cpp (+17-19) 
- (modified) llvm/lib/Analysis/ValueTracking.cpp (+32-29) 
- (added) llvm/lib/IR/BundleAttributes.cpp (+57) 
- (modified) llvm/lib/IR/CMakeLists.txt (+1) 
- (modified) llvm/lib/IR/Verifier.cpp (+48-43) 
- (modified) llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp (+54-40) 
- (modified) llvm/lib/Transforms/Utils/AssumeBundleBuilder.cpp (+1-8) 
- (modified) llvm/lib/Transforms/Utils/PredicateInfo.cpp (+9-8) 
- (modified) llvm/test/Transforms/Attributor/nofpclass.ll (-28) 
- (modified) llvm/test/Transforms/Attributor/nofree.ll (-81) 
- (modified) llvm/test/Transforms/Coroutines/coro-split-musttail-chain-pgo-counter-promo.ll (+3-3) 
- (added) llvm/test/Transforms/InstCombine/test.ll (+38) 
- (modified) llvm/test/Transforms/Util/assume-builder.ll (-217) 
- (modified) llvm/test/Verifier/assume-bundles.ll (+65-12) 
- (modified) llvm/unittests/Analysis/AssumeBundleQueriesTest.cpp (-27) 


``````````diff
diff --git a/llvm/include/llvm/IR/BundleAttributes.def b/llvm/include/llvm/IR/BundleAttributes.def
new file mode 100644
index 0000000000000..2d57a0b697edc
--- /dev/null
+++ b/llvm/include/llvm/IR/BundleAttributes.def
@@ -0,0 +1,18 @@
+//===- llvm/BundleAttributes.def - LLVM Bundle Attributes -------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+ATTR(Align, align)
+ATTR(Cold, cold)
+ATTR(Dereferenceable, dereferenceable)
+ATTR(DereferenceableOrNull, dereferenceable_or_null)
+ATTR(Ignore, ignore)
+ATTR(NonNull, nonnull)
+ATTR(NoUndef, noundef) // FIXME: Is this actually useful? It's currently exclusively emitted through tests.
+ATTR(SeparateStorage, separate_storage)
+
+#undef ATTR
diff --git a/llvm/include/llvm/IR/BundleAttributes.h b/llvm/include/llvm/IR/BundleAttributes.h
new file mode 100644
index 0000000000000..789e5b95fc1e4
--- /dev/null
+++ b/llvm/include/llvm/IR/BundleAttributes.h
@@ -0,0 +1,62 @@
+//===- llvm/BundleAttributes.h - LLVM Bundle Attributes ---------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_BUNDLE_ATTRIBUTES_H
+#define LLVM_IR_BUNDLE_ATTRIBUTES_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/IR/InstrTypes.h"
+
+enum class BundleAttr {
+  None,
+#define ATTR(Name, String) Name,
+#include "BundleAttributes.def"
+};
+
+namespace llvm {
+
+LLVM_ABI StringRef getNameFromBundleAttr(BundleAttr);
+LLVM_ABI BundleAttr getBundleAttrFromString(StringRef);
+
+inline BundleAttr getBundleAttrFromOBU(OperandBundleUse OBU) {
+  return getBundleAttrFromString(OBU.getTagName());
+}
+
+struct AssumeAlignInfo {
+  Value *Ptr;
+  Value *Alignment;
+  Value *Offset;
+};
+
+LLVM_ABI AssumeAlignInfo getAssumeAlignInfo(OperandBundleUse);
+
+struct AssumeSeparateStorageInfo {
+  const Use *Ptr1;
+  const Use *Ptr2;
+};
+
+LLVM_ABI
+AssumeSeparateStorageInfo getAssumeSeparateStorageInfo(OperandBundleUse);
+
+struct AssumeNonNullInfo {
+  Value *Ptr;
+};
+
+LLVM_ABI AssumeNonNullInfo getAssumeNonNullInfo(OperandBundleUse);
+
+struct AssumeDereferenceableInfo {
+  Value *Ptr;
+  Value *Count;
+};
+
+LLVM_ABI
+AssumeDereferenceableInfo getAssumeDereferenceableInfo(OperandBundleUse);
+
+} // namespace llvm
+
+#endif // LLVM_IR_BUNDLE_ATTRIBUTES_H
diff --git a/llvm/include/llvm/IR/InstrTypes.h b/llvm/include/llvm/IR/InstrTypes.h
index 61dc5ebef1b1d..123a42d09ce7c 100644
--- a/llvm/include/llvm/IR/InstrTypes.h
+++ b/llvm/include/llvm/IR/InstrTypes.h
@@ -2286,6 +2286,12 @@ class CallBase : public Instruction {
     return make_range(bundle_op_info_begin(), bundle_op_info_end());
   }
 
+  auto operand_bundles() const {
+    return map_range(bundle_op_infos(), [this](BundleOpInfo BOI) {
+      return operandBundleFromBundleOpInfo(BOI);
+    });
+  }
+
   /// Populate the BundleOpInfo instances and the Use& vector from \p
   /// Bundles.  Return the op_iterator pointing to the Use& one past the last
   /// last bundle operand use.
diff --git a/llvm/include/llvm/Transforms/Utils/PredicateInfo.h b/llvm/include/llvm/Transforms/Utils/PredicateInfo.h
index e472656d7b9fb..06ce720bda6a9 100644
--- a/llvm/include/llvm/Transforms/Utils/PredicateInfo.h
+++ b/llvm/include/llvm/Transforms/Utils/PredicateInfo.h
@@ -52,6 +52,7 @@
 
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/SmallSet.h"
+#include "llvm/IR/BundleAttributes.h"
 #include "llvm/IR/Instructions.h"
 #include "llvm/IR/PassManager.h"
 #include "llvm/IR/ValueHandle.h"
@@ -132,9 +133,9 @@ class PredicateAssume : public PredicateBase {
 
 class PredicateBundleAssume : public PredicateAssume {
 public:
-  Attribute::AttrKind AttrKind;
+  BundleAttr AttrKind;
   PredicateBundleAssume(Value *Op, IntrinsicInst *AssumeInst,
-                        Attribute::AttrKind AttrKind)
+                        BundleAttr AttrKind)
       : PredicateAssume(PT_BundleAssume, Op, AssumeInst, nullptr),
         AttrKind(AttrKind) {}
 
diff --git a/llvm/lib/Analysis/LazyValueInfo.cpp b/llvm/lib/Analysis/LazyValueInfo.cpp
index b70c380dd5466..37771985bd455 100644
--- a/llvm/lib/Analysis/LazyValueInfo.cpp
+++ b/llvm/lib/Analysis/LazyValueInfo.cpp
@@ -14,7 +14,6 @@
 #include "llvm/Analysis/LazyValueInfo.h"
 #include "llvm/ADT/DenseSet.h"
 #include "llvm/ADT/STLExtras.h"
-#include "llvm/Analysis/AssumeBundleQueries.h"
 #include "llvm/Analysis/AssumptionCache.h"
 #include "llvm/Analysis/ConstantFolding.h"
 #include "llvm/Analysis/InstructionSimplify.h"
@@ -23,6 +22,7 @@
 #include "llvm/Analysis/ValueLattice.h"
 #include "llvm/Analysis/ValueTracking.h"
 #include "llvm/IR/AssemblyAnnotationWriter.h"
+#include "llvm/IR/BundleAttributes.h"
 #include "llvm/IR/CFG.h"
 #include "llvm/IR/ConstantRange.h"
 #include "llvm/IR/Constants.h"
@@ -856,26 +856,24 @@ void LazyValueInfoImpl::intersectAssumeOrGuardBlockValueConstantRange(
       continue;
 
     if (AssumeVH.Index != AssumptionCache::ExprResultIdx) {
-      if (RetainedKnowledge RK = getKnowledgeFromBundle(
-              *I, I->bundle_op_info_begin()[AssumeVH.Index])) {
-        if (RK.WasOn != Val)
-          continue;
-        switch (RK.AttrKind) {
-        case Attribute::NonNull:
-          BBLV = BBLV.intersect(ValueLatticeElement::getNot(
-              Constant::getNullValue(RK.WasOn->getType())));
-          break;
+      auto OBU = I->operand_bundles().begin()[AssumeVH.Index];
+      switch (getBundleAttrFromOBU(OBU)) {
+      case BundleAttr::NonNull:
+        assert(getAssumeNonNullInfo(OBU).Ptr == Val);
+        BBLV = BBLV.intersect(ValueLatticeElement::getNot(
+            Constant::getNullValue(Val->getType())));
+        break;
 
-        case Attribute::Dereferenceable:
-          if (auto *CI = dyn_cast<ConstantInt>(RK.IRArgValue);
-              CI && !CI->isZero())
-            BBLV = BBLV.intersect(ValueLatticeElement::getNot(
-                Constant::getNullValue(RK.WasOn->getType())));
-          break;
+      case BundleAttr::Dereferenceable: {
+        auto [Ptr, Count] = getAssumeDereferenceableInfo(OBU);
+        assert(Ptr == Val);
+        if (auto *CI = dyn_cast<ConstantInt>(Count); CI && !CI->isZero())
+          BBLV = BBLV.intersect(ValueLatticeElement::getNot(
+              Constant::getNullValue(Val->getType())));
+      } break;
 
-        default:
-          break;
-        }
+      default:
+        break;
       }
     } else {
       BBLV = BBLV.intersect(*getValueFromCondition(Val, I->getArgOperand(0),
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 91ad517f194a6..7a391182594ee 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -38,6 +38,7 @@
 #include "llvm/IR/Argument.h"
 #include "llvm/IR/Attributes.h"
 #include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/BundleAttributes.h"
 #include "llvm/IR/Constant.h"
 #include "llvm/IR/ConstantFPRange.h"
 #include "llvm/IR/ConstantRange.h"
@@ -829,32 +830,28 @@ static bool isKnownNonZeroFromAssume(const Value *V, const SimplifyQuery &Q) {
            "Got assumption for the wrong function!");
 
     if (Elem.Index != AssumptionCache::ExprResultIdx) {
-      if (!V->getType()->isPointerTy())
-        continue;
-      if (RetainedKnowledge RK = getKnowledgeFromBundle(
-              *I, I->bundle_op_info_begin()[Elem.Index])) {
-        if (RK.WasOn != V)
-          continue;
-        bool AssumeImpliesNonNull = [&]() {
-          if (RK.AttrKind == Attribute::NonNull)
-            return true;
+      auto OBU = I->operand_bundles().begin()[Elem.Index];
+      bool AssumeImpliesNonNull = [&]() {
+        switch (getBundleAttrFromOBU(OBU)) {
+        case BundleAttr::Dereferenceable: {
+          auto [Ptr, Count] = getAssumeDereferenceableInfo(OBU);
+          if (NullPointerIsDefined(Q.CxtI->getFunction(),
+                                   V->getType()->getPointerAddressSpace()))
+            return false;
 
-          if (RK.AttrKind == Attribute::Dereferenceable) {
-            if (NullPointerIsDefined(Q.CxtI->getFunction(),
-                                     V->getType()->getPointerAddressSpace()))
-              return false;
-            assert(RK.IRArgValue &&
-                   "Dereferenceable attribute without IR argument?");
+          auto *CI = dyn_cast<ConstantInt>(Count);
+          return CI && !CI->isZero();
+        }
 
-            auto *CI = dyn_cast<ConstantInt>(RK.IRArgValue);
-            return CI && !CI->isZero();
-          }
+        case BundleAttr::NonNull:
+          return true;
 
+        default:
           return false;
-        }();
-        if (AssumeImpliesNonNull && isValidAssumeForContext(I, Q))
-          return true;
-      }
+        }
+      }();
+      if (AssumeImpliesNonNull && isValidAssumeForContext(I, Q))
+        return true;
       continue;
     }
 
@@ -1090,13 +1087,19 @@ void llvm::computeKnownBitsFromContext(const Value *V, KnownBits &Known,
            "Got assumption for the wrong function!");
 
     if (Elem.Index != AssumptionCache::ExprResultIdx) {
-      if (!V->getType()->isPointerTy())
-        continue;
-      if (RetainedKnowledge RK = getKnowledgeFromBundle(
-              *I, I->bundle_op_info_begin()[Elem.Index])) {
-        if (RK.WasOn == V && RK.AttrKind == Attribute::Alignment &&
-            isPowerOf2_64(RK.ArgValue) && isValidAssumeForContext(I, Q))
-          Known.Zero.setLowBits(Log2_64(RK.ArgValue));
+      auto OBU = I->operand_bundles().begin()[Elem.Index];
+      if (getBundleAttrFromOBU(OBU) == BundleAttr::Align) {
+        auto [Ptr, Alignment, Offset] = getAssumeAlignInfo(OBU);
+        assert(Ptr == V);
+        if ((Offset && !isa<ConstantInt>(Offset)) ||
+            !isa<ConstantInt>(Alignment))
+          continue;
+        auto AlignVal =
+            MinAlign(Offset ? cast<ConstantInt>(Offset)->getZExtValue() : 0,
+                     cast<ConstantInt>(Alignment)->getZExtValue());
+        if (!isPowerOf2_64(AlignVal) || !isValidAssumeForContext(I, Q))
+          continue;
+        Known.Zero.setLowBits(Log2_64(AlignVal));
       }
       continue;
     }
diff --git a/llvm/lib/IR/BundleAttributes.cpp b/llvm/lib/IR/BundleAttributes.cpp
new file mode 100644
index 0000000000000..6fbf1bdcbb539
--- /dev/null
+++ b/llvm/lib/IR/BundleAttributes.cpp
@@ -0,0 +1,57 @@
+//===- llvm/BundleAttributes.cpp - LLVM Bundle Attributes -------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/IR/BundleAttributes.h"
+
+using namespace llvm;
+
+StringRef llvm::getNameFromBundleAttr(BundleAttr BA) {
+  switch (BA) {
+#define ATTR(Name, Str)                                                        \
+  case BundleAttr::Name:                                                       \
+    return #Str;
+#include "llvm/IR/BundleAttributes.def"
+  case BundleAttr::None:
+    return "none";
+  }
+}
+
+BundleAttr llvm::getBundleAttrFromString(StringRef Str) {
+  return StringSwitch<BundleAttr>(Str)
+#define ATTR(Name, Str) .Case(#Str, BundleAttr::Name)
+#include "llvm/IR/BundleAttributes.def"
+      .Default(BundleAttr::None);
+}
+
+AssumeAlignInfo llvm::getAssumeAlignInfo(OperandBundleUse OBU) {
+  assert(OBU.getTagName() == "align" && OBU.Inputs.size() >= 2 &&
+         OBU.Inputs.size() <= 3);
+  AssumeAlignInfo Ret{};
+  Ret.Ptr = OBU.Inputs[0];
+  Ret.Alignment = OBU.Inputs[1];
+  if (OBU.Inputs.size() == 3)
+    Ret.Offset = OBU.Inputs[2];
+  return Ret;
+}
+
+AssumeSeparateStorageInfo
+llvm::getAssumeSeparateStorageInfo(OperandBundleUse OBU) {
+  assert(OBU.getTagName() == "separate_storage" && OBU.Inputs.size() == 2);
+  return {&OBU.Inputs[0], &OBU.Inputs[1]};
+}
+
+AssumeNonNullInfo llvm::getAssumeNonNullInfo(OperandBundleUse OBU) {
+  assert(OBU.getTagName() == "nonnull" && OBU.Inputs.size() == 1);
+  return {OBU.Inputs[0]};
+}
+
+AssumeDereferenceableInfo
+llvm::getAssumeDereferenceableInfo(OperandBundleUse OBU) {
+  assert(OBU.getTagName() == "dereferenceable" && OBU.Inputs.size() == 2);
+  return {OBU.Inputs[0], OBU.Inputs[1]};
+}
diff --git a/llvm/lib/IR/CMakeLists.txt b/llvm/lib/IR/CMakeLists.txt
index 5511c3b33b0d7..9cc45ef0e1773 100644
--- a/llvm/lib/IR/CMakeLists.txt
+++ b/llvm/lib/IR/CMakeLists.txt
@@ -6,6 +6,7 @@ add_llvm_component_library(LLVMCore
   AutoUpgrade.cpp
   BasicBlock.cpp
   BuiltinGCs.cpp
+  BundleAttributes.cpp
   Comdat.cpp
   ConstantFold.cpp
   ConstantFPRange.cpp
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index e75ba813e4559..8b5748bbf6f4e 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -64,6 +64,7 @@
 #include "llvm/IR/AttributeMask.h"
 #include "llvm/IR/Attributes.h"
 #include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/BundleAttributes.h"
 #include "llvm/IR/CFG.h"
 #include "llvm/IR/CallingConv.h"
 #include "llvm/IR/Comdat.h"
@@ -5995,56 +5996,60 @@ void Verifier::visitIntrinsicCall(Intrinsic::ID ID, CallBase &Call) {
       Check(Cond && Cond->isOne(),
             "assume with operand bundles must have i1 true condition", Call);
     }
-    for (auto &Elem : Call.bundle_op_infos()) {
-      unsigned ArgCount = Elem.End - Elem.Begin;
+    for (auto OBU : Call.operand_bundles()) {
       // Separate storage assumptions are special insofar as they're the only
       // operand bundles allowed on assumes that aren't parameter attributes.
-      if (Elem.Tag->getKey() == "separate_storage") {
-        Check(ArgCount == 2,
-              "separate_storage assumptions should have 2 arguments", Call);
-        Check(Call.getOperand(Elem.Begin)->getType()->isPointerTy() &&
-                  Call.getOperand(Elem.Begin + 1)->getType()->isPointerTy(),
-              "arguments to separate_storage assumptions should be pointers",
-              Call);
-        continue;
-      }
-      Check(Elem.Tag->getKey() == "ignore" ||
-                Attribute::isExistingAttribute(Elem.Tag->getKey()),
-            "tags must be valid attribute names", Call);
-      Attribute::AttrKind Kind =
-          Attribute::getAttrKindFromName(Elem.Tag->getKey());
-      if (Kind == Attribute::Alignment) {
-        Check(ArgCount <= 3 && ArgCount >= 2,
+
+      auto GetTypeAt = [&](unsigned Index) {
+        return OBU.Inputs[Index]->getType();
+      };
+
+      switch (getBundleAttrFromOBU(OBU)) {
+      case BundleAttr::None:
+        CheckFailed("tags must be valid attribute names", Call);
+        break;
+      case BundleAttr::Align:
+        Check(OBU.Inputs.size() >= 2 && OBU.Inputs.size() <= 3,
               "alignment assumptions should have 2 or 3 arguments", Call);
-        Check(Call.getOperand(Elem.Begin)->getType()->isPointerTy(),
-              "first argument should be a pointer", Call);
-        Check(Call.getOperand(Elem.Begin + 1)->getType()->isIntegerTy(),
+        Check(GetTypeAt(0)->isPointerTy(), "first argument should be a pointer",
+              Call);
+        Check(GetTypeAt(1)->isIntegerTy(),
               "second argument should be an integer", Call);
-        if (ArgCount == 3)
-          Check(Call.getOperand(Elem.Begin + 2)->getType()->isIntegerTy(),
-                "third argument should be an integer if present", Call);
-        continue;
-      }
-      if (Kind == Attribute::Dereferenceable) {
-        Check(ArgCount == 2,
+        Check(OBU.Inputs.size() < 3 || GetTypeAt(2)->isIntegerTy(),
+              "third argument should be an integer if present", Call);
+        break;
+      case BundleAttr::Cold:
+        Check(OBU.Inputs.size() == 0,
+              "cold assumptions should have no arguments", Call);
+        break;
+      case BundleAttr::Dereferenceable:
+      case BundleAttr::DereferenceableOrNull:
+        Check(OBU.Inputs.size() == 2,
               "dereferenceable assumptions should have 2 arguments", Call);
-        Check(Call.getOperand(Elem.Begin)->getType()->isPointerTy(),
-              "first argument should be a pointer", Call);
-        Check(Call.getOperand(Elem.Begin + 1)->getType()->isIntegerTy(),
+        Check(GetTypeAt(0)->isPointerTy(), "first argument should be a pointer",
+              Call);
+        Check(GetTypeAt(1)->isIntegerTy(),
               "second argument should be an integer", Call);
-        continue;
-      }
-      Check(ArgCount <= 2, "too many arguments", Call);
-      if (Kind == Attribute::None)
         break;
-      if (Attribute::isIntAttrKind(Kind)) {
-        Check(ArgCount == 2, "this attribute should have 2 arguments", Call);
-        Check(isa<ConstantInt>(Call.getOperand(Elem.Begin + 1)),
-              "the second argument should be a constant integral value", Call);
-      } else if (Attribute::canUseAsParamAttr(Kind)) {
-        Check((ArgCount) == 1, "this attribute should have one argument", Call);
-      } else if (Attribute::canUseAsFnAttr(Kind)) {
-        Check((ArgCount) == 0, "this attribute has no argument", Call);
+      case BundleAttr::Ignore:
+        break;
+      case BundleAttr::NonNull:
+        Check(OBU.Inputs.size() == 1,
+              "nonnull assumptions should have 1 argument", Call);
+        Check(GetTypeAt(0)->isPointerTy(), "first argument should be a pointer",
+              Call);
+        break;
+      case BundleAttr::NoUndef:
+        Check(OBU.Inputs.size() == 1,
+              "noundef assumptions should have 1 argument", Call);
+        break;
+      case BundleAttr::SeparateStorage:
+        Check(OBU.Inputs.size() == 2,
+              "separate_storage assumptions should have 2 arguments", Call);
+        Check(GetTypeAt(0)->isPointerTy() && GetTypeAt(1)->isPointerTy(),
+              "arguments to separate_storage assumptions should be pointers",
+              Call);
+        break;
       }
     }
     break;
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index 2a8bf3ffecd6f..3ee5d65f7f8b7 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -31,6 +31,7 @@
 #include "llvm/IR/AttributeMask.h"
 #include "llvm/IR/Attributes.h"
 #include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/BundleAttributes.h"
 #include "llvm/IR/Constant.h"
 #include "llvm/IR/Constants.h"
 #include "llvm/IR/DataLayout.h"
@@ -3621,66 +3622,48 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
       return eraseInstFromFunction(*II);
     }
 
-    for (unsigned Idx = 0; Idx < II->getNumOperandBundles(); Idx++) {
-      OperandBundleUse OBU = II->getOperandBundleAt(Idx);
+    for (auto OBU : II->operand_bundles()) {
+      switch (getBundleAttrFromOBU(OBU)) {
+      case BundleAttr::None:
+        llvm_unreachable("Unexpected Attribute");
+      case BundleAttr::Align: {
+        // Try to remove redundant alignment assumptions.
+        auto [Ptr, Alignment, Offset] = getAssumeAlignInfo(OBU);
 
-      // Separate storage assumptions apply to the underlying allocations, not
-      // any particular pointer within them. When evaluating the hints for AA
-      // purposes we getUnderlyingObject them; by precomputing the answers here
-      // we can avoid having to do so repeatedly there.
-      if (OBU.getTagName() == "separate_storage") {
-        assert(OBU.Inputs.size() == 2);
-        auto MaybeSimplifyHint = [&](const Use &U) {
-          Value *Hint = U.get();
-          // Not having a limit is safe because InstCombine removes unreachable
-          // code.
-          Value *UnderlyingObject = getUnderlyingObject(Hint, /*MaxLookup*/ 0);
-          if (Hint != UnderlyingObject)
-            replaceUse(const_cast<Use &>(U), UnderlyingObject);
-        };
-        MaybeSimplifyHint(OBU.Inputs[0]);
-        MaybeSimplifyHint(OBU.Inputs[1]);
-      }
-
-      // Try to remove redundant alignment assumptions.
-      if (OBU.getTagName() == "align" ...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/197007


More information about the llvm-commits mailing list