[clang] [llvm] [Clang] Correct __builtin_dynamic_object_size for subobject types (PR #78526)

via cfe-commits cfe-commits at lists.llvm.org
Wed Jan 17 16:44:47 PST 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-globalisel
@llvm/pr-subscribers-backend-amdgpu

@llvm/pr-subscribers-clang-codegen

Author: Bill Wendling (bwendling)

<details>
<summary>Changes</summary>

The second argument of __builtin_dynamic_object_size controls whether it
returns the size of the whole object or the closest surrounding object.
For this struct:
    
      struct s {
        int  foo;
        char bar[2][40];
        int  baz;
        int  qux;
      };
    
      int main(int argc, char **argv) {
        struct s f;
    
      #define report(x) fprintf(stderr, #x ": %zu\n", x)
    
        argc = 1;
        report(__builtin_dynamic_object_size(f.bar[argc], 0));
        report(__builtin_dynamic_object_size(f.bar[argc], 1));
        return 0;
      }
    
should return:
    
      __builtin_dynamic_object_size(f.bar[argc], 0): 48
      __builtin_dynamic_object_size(f.bar[argc], 1): 40
    
determined by the least significant bit of the TYPE.
    
Add a new parameter to the llvm.objectsize intrinsic to control which
size it should return.


---

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


40 Files Affected:

- (modified) clang/lib/CodeGen/CGBuiltin.cpp (+6-1) 
- (modified) clang/lib/CodeGen/CGExpr.cpp (+3-1) 
- (modified) clang/test/CodeGen/catch-undef-behavior.c (+1-1) 
- (modified) clang/test/CodeGen/pass-object-size.c (+3-3) 
- (modified) llvm/docs/LangRef.rst (+21-13) 
- (modified) llvm/include/llvm/Analysis/MemoryBuiltins.h (+9) 
- (modified) llvm/include/llvm/IR/Intrinsics.td (+1-1) 
- (modified) llvm/lib/Analysis/MemoryBuiltins.cpp (+31-4) 
- (modified) llvm/lib/IR/AutoUpgrade.cpp (+37-6) 
- (modified) llvm/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp (+2-2) 
- (modified) llvm/test/Analysis/CostModel/X86/free-intrinsics.ll (+4-4) 
- (modified) llvm/test/Analysis/CostModel/free-intrinsics-datalayout.ll (+4-4) 
- (modified) llvm/test/Analysis/CostModel/free-intrinsics-no_info.ll (+4-4) 
- (modified) llvm/test/Assembler/auto_upgrade_intrinsics.ll (+4-4) 
- (modified) llvm/test/Bitcode/objectsize-upgrade-7.0.ll (+2-2) 
- (modified) llvm/test/CodeGen/AArch64/GlobalISel/memcpy_chk_no_tail.ll (+2-2) 
- (modified) llvm/test/CodeGen/AArch64/memsize-remarks.ll (+16-16) 
- (modified) llvm/test/CodeGen/AMDGPU/promote-alloca-mem-intrinsics.ll (+4-4) 
- (modified) llvm/test/Other/cgscc-libcall-update.ll (+2-2) 
- (modified) llvm/test/Transforms/InferAddressSpaces/AMDGPU/debug-info.ll (+4-4) 
- (modified) llvm/test/Transforms/InferAddressSpaces/AMDGPU/intrinsics.ll (+6-6) 
- (modified) llvm/test/Transforms/InferAlignment/propagate-assume.ll (+2-2) 
- (modified) llvm/test/Transforms/Inline/call-intrinsic-objectsize.ll (+3-3) 
- (modified) llvm/test/Transforms/InstCombine/allocsize.ll (+5-5) 
- (modified) llvm/test/Transforms/InstCombine/builtin-dynamic-object-size.ll (+13-13) 
- (modified) llvm/test/Transforms/InstCombine/builtin-object-size-custom-dl.ll (+3-3) 
- (modified) llvm/test/Transforms/InstCombine/builtin-object-size-strdup-family.ll (+5-5) 
- (modified) llvm/test/Transforms/InstCombine/invoke.ll (+1-1) 
- (modified) llvm/test/Transforms/InstCombine/memset_chk-1.ll (+5-5) 
- (modified) llvm/test/Transforms/InstCombine/objsize.ll (+38-38) 
- (modified) llvm/test/Transforms/InstCombine/stpcpy_chk-1.ll (+4-4) 
- (modified) llvm/test/Transforms/InstCombine/strcpy_chk-1.ll (+5-5) 
- (modified) llvm/test/Transforms/LowerConstantIntrinsics/builtin-object-size-load.ll (+2-2) 
- (modified) llvm/test/Transforms/LowerConstantIntrinsics/builtin-object-size-phi.ll (+5-5) 
- (modified) llvm/test/Transforms/LowerConstantIntrinsics/builtin-object-size-posix-memalign.ll (+8-8) 
- (modified) llvm/test/Transforms/LowerConstantIntrinsics/constant-intrinsics.ll (+2-2) 
- (modified) llvm/test/Transforms/LowerConstantIntrinsics/crash-on-large-allocas.ll (+2-2) 
- (modified) llvm/test/Transforms/LowerConstantIntrinsics/objectsize_basic.ll (+18-19) 
- (modified) llvm/test/Transforms/LowerConstantIntrinsics/stale-worklist-phi.ll (+2-2) 
- (modified) llvm/test/Transforms/SCCP/issue59602-assume-like-call-users.ll (+5-5) 


``````````diff
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index de48b15645b1ab..513a007aa009b7 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -1103,12 +1103,17 @@ CodeGenFunction::emitBuiltinObjectSize(const Expr *E, unsigned Type,
   Function *F =
       CGM.getIntrinsic(Intrinsic::objectsize, {ResType, Ptr->getType()});
 
+  // If the least significant bit is clear, objects are whole variables. If
+  // it's set, a closest surrounding subobject is considered the object a
+  // pointer points to.
+  Value *WholeObj = Builder.getInt1((Type & 1) == 0);
+
   // LLVM only supports 0 and 2, make sure that we pass along that as a boolean.
   Value *Min = Builder.getInt1((Type & 2) != 0);
   // For GCC compatibility, __builtin_object_size treat NULL as unknown size.
   Value *NullIsUnknown = Builder.getTrue();
   Value *Dynamic = Builder.getInt1(IsDynamic);
-  return Builder.CreateCall(F, {Ptr, Min, NullIsUnknown, Dynamic});
+  return Builder.CreateCall(F, {Ptr, WholeObj, Min, NullIsUnknown, Dynamic});
 }
 
 namespace {
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index d12e85b48d0b00..7149e459a1390e 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -744,11 +744,13 @@ void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc,
       // FIXME: Get object address space
       llvm::Type *Tys[2] = { IntPtrTy, Int8PtrTy };
       llvm::Function *F = CGM.getIntrinsic(llvm::Intrinsic::objectsize, Tys);
+      llvm::Value *WholeObj = Builder.getTrue();
       llvm::Value *Min = Builder.getFalse();
       llvm::Value *NullIsUnknown = Builder.getFalse();
       llvm::Value *Dynamic = Builder.getFalse();
       llvm::Value *LargeEnough = Builder.CreateICmpUGE(
-          Builder.CreateCall(F, {Ptr, Min, NullIsUnknown, Dynamic}), Size);
+          Builder.CreateCall(F, {Ptr, WholeObj, Min, NullIsUnknown, Dynamic}),
+          Size);
       Checks.push_back(std::make_pair(LargeEnough, SanitizerKind::ObjectSize));
     }
   }
diff --git a/clang/test/CodeGen/catch-undef-behavior.c b/clang/test/CodeGen/catch-undef-behavior.c
index af37ef9e8565b1..41cbe6db881bf0 100644
--- a/clang/test/CodeGen/catch-undef-behavior.c
+++ b/clang/test/CodeGen/catch-undef-behavior.c
@@ -35,7 +35,7 @@
 void foo(void) {
   union { int i; } u;
 
-  // CHECK-COMMON: %[[SIZE:.*]] = call i64 @llvm.objectsize.i64.p0(ptr %[[PTR:.*]], i1 false, i1 false, i1 false)
+  // CHECK-COMMON: %[[SIZE:.*]] = call i64 @llvm.objectsize.i64.p0(ptr %[[PTR:.*]], i1 true, i1 false, i1 false, i1 false)
   // CHECK-COMMON-NEXT: %[[OK:.*]] = icmp uge i64 %[[SIZE]], 4
 
   // CHECK-UBSAN: br i1 %[[OK]], {{.*}} !prof ![[WEIGHT_MD:.*]], !nosanitize
diff --git a/clang/test/CodeGen/pass-object-size.c b/clang/test/CodeGen/pass-object-size.c
index c7c505b0fb3e78..cbc54db301a5c8 100644
--- a/clang/test/CodeGen/pass-object-size.c
+++ b/clang/test/CodeGen/pass-object-size.c
@@ -85,16 +85,16 @@ void test1(unsigned long sz) {
 
   char *ptr = (char *)malloc(sz);
 
-  // CHECK: [[REG:%.*]] = call i64 @llvm.objectsize.i64.p0({{.*}}, i1 false, i1 true, i1 true)
+  // CHECK: [[REG:%.*]] = call i64 @llvm.objectsize.i64.p0({{.*}}, i1 true, i1 false, i1 true, i1 true)
   // CHECK: call i32 @DynamicObjectSize0(ptr noundef %{{.*}}, i64 noundef [[REG]])
   gi = DynamicObjectSize0(ptr);
 
   // CHECK: [[WITH_OFFSET:%.*]] = getelementptr
-  // CHECK: [[REG:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[WITH_OFFSET]], i1 false, i1 true, i1 true)
+  // CHECK: [[REG:%.*]] = call i64 @llvm.objectsize.i64.p0(ptr [[WITH_OFFSET]], i1 true, i1 false, i1 true, i1 true)
   // CHECK: call i32 @DynamicObjectSize0(ptr noundef {{.*}}, i64 noundef [[REG]])
   gi = DynamicObjectSize0(ptr+10);
 
-  // CHECK: [[REG:%.*]] = call i64 @llvm.objectsize.i64.p0({{.*}}, i1 true, i1 true, i1 true)
+  // CHECK: [[REG:%.*]] = call i64 @llvm.objectsize.i64.p0({{.*}}, i1 true, i1 true, i1 true, i1 true)
   // CHECK: call i32 @DynamicObjectSize2(ptr noundef {{.*}}, i64 noundef [[REG]])
   gi = DynamicObjectSize2(ptr);
 }
diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index d881deb30049a2..054333fe52fcd5 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -26520,8 +26520,8 @@ Syntax:
 
 ::
 
-      declare i32 @llvm.objectsize.i32(ptr <object>, i1 <min>, i1 <nullunknown>, i1 <dynamic>)
-      declare i64 @llvm.objectsize.i64(ptr <object>, i1 <min>, i1 <nullunknown>, i1 <dynamic>)
+      declare i32 @llvm.objectsize.i32(ptr <object>, i1 <wholeobj>, i1 <min>, i1 <nullunknown>, i1 <dynamic>)
+      declare i64 @llvm.objectsize.i64(ptr <object>, i1 <wholeobj>, i1 <min>, i1 <nullunknown>, i1 <dynamic>)
 
 Overview:
 """""""""
@@ -26535,18 +26535,26 @@ class, structure, array, or other object.
 Arguments:
 """"""""""
 
-The ``llvm.objectsize`` intrinsic takes four arguments. The first argument is a
-pointer to or into the ``object``. The second argument determines whether
-``llvm.objectsize`` returns 0 (if true) or -1 (if false) when the object size is
-unknown. The third argument controls how ``llvm.objectsize`` acts when ``null``
-in address space 0 is used as its pointer argument. If it's ``false``,
-``llvm.objectsize`` reports 0 bytes available when given ``null``. Otherwise, if
-the ``null`` is in a non-zero address space or if ``true`` is given for the
-third argument of ``llvm.objectsize``, we assume its size is unknown. The fourth
-argument to ``llvm.objectsize`` determines if the value should be evaluated at
-runtime.
+The ``llvm.objectsize`` intrinsic takes five arguments:
+
+- The first argument is a pointer to or into the ``object``.
+- The second argument controls which size ``llvm.objectsize`` returns:
+  - If it's ``false``, ``llvm.objectsize`` returns the size of the closest
+    surrounding subobject.
+  - If it's ``true``, ``llvm.objectsize`` returns the size of the whole object.
+- The third argument controls which value to return when the size is unknown:
+  - If it's ``false``, ``llvm.objectsize`` returns ``-1``.
+  - If it's ``true``, ``llvm.objectsize`` returns ``0``.
+- The fourth argument controls how ``llvm.objectsize`` acts when ``null`` in
+  address space 0 is used as its pointer argument:
+  - If it's ``false``, ``llvm.objectsize`` reports 0 bytes available when given
+    ``null``.
+  - If it's ``true``, or the ``null`` pointer is in a non-zero address space,
+    the size is assumed to be unknown.
+- The fifth argument to ``llvm.objectsize`` determines if the value should be
+  evaluated at runtime.
 
-The second, third, and fourth arguments only accept constants.
+The second, third, fourth, and fifth arguments accept only constants.
 
 Semantics:
 """"""""""
diff --git a/llvm/include/llvm/Analysis/MemoryBuiltins.h b/llvm/include/llvm/Analysis/MemoryBuiltins.h
index 37ce1518f00c08..ee5cc950788678 100644
--- a/llvm/include/llvm/Analysis/MemoryBuiltins.h
+++ b/llvm/include/llvm/Analysis/MemoryBuiltins.h
@@ -157,6 +157,11 @@ struct ObjectSizeOpts {
   /// Whether to round the result up to the alignment of allocas, byval
   /// arguments, and global variables.
   bool RoundToAlign = false;
+  /// If this is true, return the whole size of the object. Otherwise, return
+  /// the size of the closest surrounding subobject.
+  /// FIXME: The default before being added was to return the whole size of the
+  /// object. Review if this is the correct default.
+  bool WholeObjectSize = true;
   /// If this is true, null pointers in address space 0 will be treated as
   /// though they can't be evaluated. Otherwise, null is always considered to
   /// point to a 0 byte region of memory.
@@ -231,6 +236,7 @@ class ObjectSizeOffsetVisitor
   APInt Zero;
   SmallDenseMap<Instruction *, SizeOffsetAPInt, 8> SeenInsts;
   unsigned InstructionsVisited;
+  const StructType *AllocaTy = nullptr;
 
   APInt align(APInt Size, MaybeAlign Align);
 
@@ -242,6 +248,8 @@ class ObjectSizeOffsetVisitor
 
   SizeOffsetAPInt compute(Value *V);
 
+  const StructType *getAllocaType() const { return AllocaTy; }
+
   // These are "private", except they can't actually be made private. Only
   // compute() should be used by external users.
   SizeOffsetAPInt visitAllocaInst(AllocaInst &I);
@@ -313,6 +321,7 @@ class ObjectSizeOffsetEvaluator
   PtrSetTy SeenVals;
   ObjectSizeOpts EvalOpts;
   SmallPtrSet<Instruction *, 8> InsertedInstructions;
+  const StructType *AllocaTy = nullptr;
 
   SizeOffsetValue compute_(Value *V);
 
diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td
index b54c697296b20a..cef4c756d5a31e 100644
--- a/llvm/include/llvm/IR/Intrinsics.td
+++ b/llvm/include/llvm/IR/Intrinsics.td
@@ -1071,7 +1071,7 @@ def int_maximum : DefaultAttrsIntrinsic<[llvm_anyfloat_ty],
 
 // Internal interface for object size checking
 def int_objectsize : DefaultAttrsIntrinsic<[llvm_anyint_ty],
-                               [llvm_anyptr_ty, llvm_i1_ty,
+                               [llvm_anyptr_ty, llvm_i1_ty, llvm_i1_ty,
                                 llvm_i1_ty, llvm_i1_ty],
                                [IntrNoMem, IntrSpeculatable, IntrWillReturn,
                                 ImmArg<ArgIndex<1>>, ImmArg<ArgIndex<2>>,
diff --git a/llvm/lib/Analysis/MemoryBuiltins.cpp b/llvm/lib/Analysis/MemoryBuiltins.cpp
index 46a7a921d86d3d..56d6313905865e 100644
--- a/llvm/lib/Analysis/MemoryBuiltins.cpp
+++ b/llvm/lib/Analysis/MemoryBuiltins.cpp
@@ -615,12 +615,15 @@ Value *llvm::lowerObjectSizeCall(
   assert(ObjectSize->getIntrinsicID() == Intrinsic::objectsize &&
          "ObjectSize must be a call to llvm.objectsize!");
 
-  bool MaxVal = cast<ConstantInt>(ObjectSize->getArgOperand(1))->isZero();
   ObjectSizeOpts EvalOptions;
   EvalOptions.AA = AA;
 
+  EvalOptions.WholeObjectSize =
+      cast<ConstantInt>(ObjectSize->getArgOperand(1))->isOne();
+
   // Unless we have to fold this to something, try to be as accurate as
   // possible.
+  bool MaxVal = cast<ConstantInt>(ObjectSize->getArgOperand(2))->isZero();
   if (MustSucceed)
     EvalOptions.EvalMode =
         MaxVal ? ObjectSizeOpts::Mode::Max : ObjectSizeOpts::Mode::Min;
@@ -628,10 +631,10 @@ Value *llvm::lowerObjectSizeCall(
     EvalOptions.EvalMode = ObjectSizeOpts::Mode::ExactSizeFromOffset;
 
   EvalOptions.NullIsUnknownSize =
-      cast<ConstantInt>(ObjectSize->getArgOperand(2))->isOne();
+      cast<ConstantInt>(ObjectSize->getArgOperand(3))->isOne();
 
   auto *ResultType = cast<IntegerType>(ObjectSize->getType());
-  bool StaticOnly = cast<ConstantInt>(ObjectSize->getArgOperand(3))->isZero();
+  bool StaticOnly = cast<ConstantInt>(ObjectSize->getArgOperand(4))->isZero();
   if (StaticOnly) {
     // FIXME: Does it make sense to just return a failure value if the size won't
     // fit in the output and `!MustSucceed`?
@@ -726,6 +729,25 @@ SizeOffsetAPInt ObjectSizeOffsetVisitor::computeImpl(Value *V) {
   if (!IndexTypeSizeChanged && Offset.isZero())
     return SOT;
 
+  if (!Options.WholeObjectSize && AllocaTy) {
+    // At this point, SOT.Size is the size of the whole struct. However, we
+    // want the size of the sub-object.
+    const StructLayout &SL = *DL.getStructLayout(
+        const_cast<StructType *>(AllocaTy));
+
+    unsigned Idx = SL.getElementContainingOffset(Offset.getLimitedValue());
+
+    // Get the size of the sub-object.
+    TypeSize ElemSize = DL.getTypeAllocSize(AllocaTy->getTypeAtIndex(Idx));
+    APInt Size(InitialIntTyBits, ElemSize.getKnownMinValue());
+
+    // Adjust the offset to reflect the sub-object's offset.
+    TypeSize ElemOffset = SL.getElementOffset(Idx);
+    Offset -= ElemOffset.getKnownMinValue();
+
+    SOT = SizeOffsetAPInt(Size, Offset);
+  }
+
   // We stripped an address space cast that changed the index type size or we
   // accumulated some constant offset (or both). Readjust the bit width to match
   // the argument index type size and apply the offset, as required.
@@ -781,9 +803,12 @@ SizeOffsetAPInt ObjectSizeOffsetVisitor::visitAllocaInst(AllocaInst &I) {
   TypeSize ElemSize = DL.getTypeAllocSize(I.getAllocatedType());
   if (ElemSize.isScalable() && Options.EvalMode != ObjectSizeOpts::Mode::Min)
     return ObjectSizeOffsetVisitor::unknown();
+
   APInt Size(IntTyBits, ElemSize.getKnownMinValue());
-  if (!I.isArrayAllocation())
+  if (!I.isArrayAllocation()) {
+    AllocaTy = dyn_cast<StructType>(I.getAllocatedType());
     return SizeOffsetAPInt(align(Size, I.getAlign()), Zero);
+  }
 
   Value *ArraySize = I.getArraySize();
   if (const ConstantInt *C = dyn_cast<ConstantInt>(ArraySize)) {
@@ -1086,6 +1111,8 @@ SizeOffsetValue ObjectSizeOffsetEvaluator::compute(Value *V) {
 SizeOffsetValue ObjectSizeOffsetEvaluator::compute_(Value *V) {
   ObjectSizeOffsetVisitor Visitor(DL, TLI, Context, EvalOpts);
   SizeOffsetAPInt Const = Visitor.compute(V);
+  AllocaTy = Visitor.getAllocaType();
+
   if (Const.bothKnown())
     return SizeOffsetValue(ConstantInt::get(Context, Const.Size),
                            ConstantInt::get(Context, Const.Offset));
diff --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp
index 1a9e474911b39c..0fafe91762d162 100644
--- a/llvm/lib/IR/AutoUpgrade.cpp
+++ b/llvm/lib/IR/AutoUpgrade.cpp
@@ -4393,12 +4393,43 @@ void llvm::UpgradeIntrinsicCall(CallBase *CI, Function *NewFn) {
     break;
 
   case Intrinsic::objectsize: {
-    Value *NullIsUnknownSize =
-        CI->arg_size() == 2 ? Builder.getFalse() : CI->getArgOperand(2);
-    Value *Dynamic =
-        CI->arg_size() < 4 ? Builder.getFalse() : CI->getArgOperand(3);
-    NewCall = Builder.CreateCall(
-        NewFn, {CI->getArgOperand(0), CI->getArgOperand(1), NullIsUnknownSize, Dynamic});
+    // The default behavior before the addition of the '<wholeobj>' argument
+    // was to return the size of the whole object.
+    Value *WholeObj = nullptr;
+    Value *UnknownVal = nullptr;
+    Value *NullIsUnknownSize = nullptr;
+    Value *Dynamic = nullptr;
+
+    switch (CI->arg_size()) {
+    case 2:
+      WholeObj = Builder.getTrue();
+      UnknownVal = CI->getArgOperand(1);
+      NullIsUnknownSize = Builder.getFalse();
+      Dynamic = Builder.getFalse();
+      break;
+    case 3:
+      WholeObj = Builder.getTrue();
+      UnknownVal = CI->getArgOperand(1);
+      NullIsUnknownSize = CI->getArgOperand(2);
+      Dynamic = Builder.getFalse();
+      break;
+    case 4:
+      WholeObj = Builder.getTrue();
+      UnknownVal = CI->getArgOperand(1);
+      NullIsUnknownSize = CI->getArgOperand(2);
+      Dynamic = CI->getArgOperand(3);
+      break;
+    case 5:
+      WholeObj = CI->getArgOperand(1);
+      UnknownVal = CI->getArgOperand(2);
+      NullIsUnknownSize = CI->getArgOperand(3);
+      Dynamic = CI->getArgOperand(4);
+      break;
+    }
+
+    NewCall =
+        Builder.CreateCall(NewFn, {CI->getArgOperand(0), WholeObj, UnknownVal,
+                                   NullIsUnknownSize, Dynamic});
     break;
   }
 
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp b/llvm/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp
index 5e73411cae9b70..3bb203442dd513 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp
@@ -1486,8 +1486,8 @@ bool AMDGPUPromoteAllocaImpl::tryPromoteAllocaToLDS(AllocaInst &I,
            PointerType::get(Context, AMDGPUAS::LOCAL_ADDRESS)});
 
       CallInst *NewCall = Builder.CreateCall(
-          ObjectSize,
-          {Src, Intr->getOperand(1), Intr->getOperand(2), Intr->getOperand(3)});
+          ObjectSize, {Src, Intr->getOperand(1), Intr->getOperand(2),
+                       Intr->getOperand(3), Intr->getOperand(4)});
       Intr->replaceAllUsesWith(NewCall);
       Intr->eraseFromParent();
       continue;
diff --git a/llvm/test/Analysis/CostModel/X86/free-intrinsics.ll b/llvm/test/Analysis/CostModel/X86/free-intrinsics.ll
index 3c39e456eed5f9..3d2e836b97517a 100644
--- a/llvm/test/Analysis/CostModel/X86/free-intrinsics.ll
+++ b/llvm/test/Analysis/CostModel/X86/free-intrinsics.ll
@@ -18,7 +18,7 @@ define i32 @trivially_free() {
 ; CHECK-SIZE-NEXT:  Cost Model: Found an estimated cost of 0 for instruction: %a4 = call i1 @llvm.is.constant.i32(i32 undef)
 ; CHECK-SIZE-NEXT:  Cost Model: Found an estimated cost of 0 for instruction: call void @llvm.lifetime.start.p0(i64 1, ptr undef)
 ; CHECK-SIZE-NEXT:  Cost Model: Found an estimated cost of 0 for instruction: call void @llvm.lifetime.end.p0(i64 1, ptr undef)
-; CHECK-SIZE-NEXT:  Cost Model: Found an estimated cost of 0 for instruction: %a5 = call i64 @llvm.objectsize.i64.p0(ptr undef, i1 true, i1 true, i1 true)
+; CHECK-SIZE-NEXT:  Cost Model: Found an estimated cost of 0 for instruction: %a5 = call i64 @llvm.objectsize.i64.p0(ptr undef, i1 true, i1 true, i1 true, i1 true)
 ; CHECK-SIZE-NEXT:  Cost Model: Found an estimated cost of 0 for instruction: %a6 = call ptr @llvm.ptr.annotation.p0.p0(ptr undef, ptr undef, ptr undef, i32 undef, ptr undef)
 ; CHECK-SIZE-NEXT:  Cost Model: Found an estimated cost of 0 for instruction: call void @llvm.var.annotation.p0.p0(ptr undef, ptr undef, ptr undef, i32 undef, ptr undef)
 ; CHECK-SIZE-NEXT:  Cost Model: Found an estimated cost of 1 for instruction: ret i32 undef
@@ -38,7 +38,7 @@ define i32 @trivially_free() {
 ; CHECK-THROUGHPUT-NEXT:  Cost Model: Found an estimated cost of 0 for instruction: %a4 = call i1 @llvm.is.constant.i32(i32 undef)
 ; CHECK-THROUGHPUT-NEXT:  Cost Model: Found an estimated cost of 0 for instruction: call void @llvm.lifetime.start.p0(i64 1, ptr undef)
 ; CHECK-THROUGHPUT-NEXT:  Cost Model: Found an estimated cost of 0 for instruction: call void @llvm.lifetime.end.p0(i64 1, ptr undef)
-; CHECK-THROUGHPUT-NEXT:  Cost Model: Found an estimated cost of 0 for instruction: %a5 = call i64 @llvm.objectsize.i64.p0(ptr undef, i1 true, i1 true, i1 true)
+; CHECK-THROUGHPUT-NEXT:  Cost Model: Found an estimated cost of 0 for instruction: %a5 = call i64 @llvm.objectsize.i64.p0(ptr undef, i1 true, i1 true, i1 true, i1 true)
 ; CHECK-THROUGHPUT-NEXT:  Cost Model: Found an estimated cost of 0 for instruction: %a6 = call ptr @llvm.ptr.annotation.p0.p0(ptr undef, ptr undef, ptr undef, i32 undef, ptr undef)
 ; CHECK-THROUGHPUT-NEXT:  Cost Model: Found an estimated cost of 0 for instruction: call void @llvm.var.annotation.p0.p0(ptr undef, ptr undef, ptr undef, i32 undef, ptr undef)
 ; CHECK-THROUGHPUT-NEXT:  Cost Model: Found an estimated cost of 0 for instruction: ret i32 undef
@@ -58,7 +58,7 @@ define i32 @trivially_free() {
   %a4 = call i1 @llvm.is.constant.i32(i32 undef)
   call void @llvm.lifetime.start.p0(i64 1, ptr undef)
   call void @llvm.lifetime.end.p0(i64 1, ptr undef)
-  %a5 = call i64 @llvm.objectsize.i64.p0(ptr undef, i1 1, i1 1, i1 1)
+  %a5 = call i64 @llvm.objectsize.i64.p0(ptr undef, i1 1, i1 1, i1 1, i1 1)
   %a6 = call ptr @llvm.ptr.annotation.p0(ptr undef, ptr undef, ptr undef, i32 undef, ptr undef)
   call void @llvm.var.annotation(ptr undef, ptr undef, ptr undef, i32 undef, ptr undef)
   ret i32 undef
@@ -79,7 +79,7 @@ declare ptr @llvm.strip.invariant.group.p0(ptr)
 declare i1 @llvm.is.constant.i32(i32)
 declare void @llvm.lifetime.start.p0(i64, ptr)
 declare void @llvm.lifetime.end.p0(i64, ptr)
-declare i64 @llvm.objectsize.i64.p0(ptr, i1, i1, i1)
+declare i64 @llvm.objectsize.i64.p0(ptr, i1, i1, i1, i1)
 declare ptr @llvm.ptr.annotation.p0(ptr, ptr, ptr, i32, ptr)
 declare void @llvm.var.annotation(ptr, ptr, ptr, i32, ptr)
 
diff --git a/llvm/test/Analysis/CostModel/free-intrinsics-datalayout.ll b/llvm/test/Analysis/CostModel/free-intrinsics-datalayout.ll
index b5f204c2d9b26e..3674e87a6fc05b 100644
--- a/llvm/test/Analysis/CostModel/free-intrinsics-datalayout.ll
+++ b/llvm/test/Analysis/CostModel/free-intrinsics-datalayout.ll
@@ -20,7 +20,7 @@ define i32 @trivially_free() {
 ; CHECK-SIZE-NEXT:  Cost Model: Found an estimated cost of 0 for instruction: %a4 = call i1 @llvm.is.constant.i32(i32 undef)
 ; CHECK-SIZE-NEXT:  Cost Model: Found an estimated cost of 0 for instruction: call void @llvm.lifetime.start.p0(i64 1, ptr undef)
 ; CHECK-SIZE-NEXT:  Cost Model: Found an estimated cost of 0 for instruction: call void @llvm.lifetime.end.p0(i64 1, ptr undef)
-; CHECK-SIZE-NEXT:  Cost Model: Found an estimated cost of 0 for instruction: %a5 = call i64 @llvm.objectsize.i64.p0(ptr undef, i1 true, i1 true, i1 true)
+; CHECK-SIZE-NEXT:  Cost Model: Found an estimated cost of 0 for instruction: %a...
[truncated]

``````````

</details>


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


More information about the cfe-commits mailing list