[llvm-branch-commits] [lldb] [llvm] release/22.x: [SafeStack] Fix crashing with scalable TypeSizes (#180547) (PR #203745)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Sat Jun 13 21:33:50 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-lldb
@llvm/pr-subscribers-compiler-rt-sanitizer
@llvm/pr-subscribers-backend-nvptx
Author: llvmbot
<details>
<summary>Changes</summary>
Backport ba2bd3fbba3a3d3985ba62144bb49e600ea469a4 537f3d3a7588d226b86590f97c4401107585e1ce
Requested by: @<!-- -->brad0
---
Patch is 21.86 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/203745.diff
17 Files Affected:
- (modified) lldb/source/Expression/IRInterpreter.cpp (+6-5)
- (modified) llvm/lib/CodeGen/CodeGenPrepare.cpp (+5-3)
- (modified) llvm/lib/CodeGen/SafeStack.cpp (+15-7)
- (modified) llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp (+3-5)
- (modified) llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (+3-3)
- (modified) llvm/lib/CodeGen/StackProtector.cpp (+17-16)
- (modified) llvm/lib/IR/Value.cpp (+2-3)
- (modified) llvm/lib/Target/AMDGPU/AMDGPULibCalls.cpp (+1-1)
- (modified) llvm/lib/Target/AMDGPU/AMDGPUTargetTransformInfo.cpp (+9-6)
- (modified) llvm/lib/Target/NVPTX/NVPTXLowerAlloca.cpp (+5-6)
- (modified) llvm/lib/Target/X86/X86WinEHState.cpp (+4-4)
- (modified) llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp (+3-14)
- (modified) llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp (+5-11)
- (modified) llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp (+4-8)
- (modified) llvm/test/CodeGen/AArch64/GlobalISel/combiner-load-store-indexing.ll (+2-2)
- (added) llvm/test/CodeGen/AArch64/safestack_scalar.ll (+17)
- (modified) llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-sincos.ll (+1-2)
``````````diff
diff --git a/lldb/source/Expression/IRInterpreter.cpp b/lldb/source/Expression/IRInterpreter.cpp
index 91404831aeb9b..48b4dd67d2d89 100644
--- a/lldb/source/Expression/IRInterpreter.cpp
+++ b/lldb/source/Expression/IRInterpreter.cpp
@@ -884,9 +884,10 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function,
case Instruction::Alloca: {
const AllocaInst *alloca_inst = cast<AllocaInst>(inst);
- if (alloca_inst->isArrayAllocation()) {
- LLDB_LOGF(log,
- "AllocaInsts are not handled if isArrayAllocation() is true");
+ std::optional<TypeSize> alloca_size =
+ alloca_inst->getAllocationSize(frame.m_target_data);
+ if (!alloca_size || alloca_size->isScalable()) {
+ LLDB_LOGF(log, "AllocaInsts are not handled if size is not computable");
error = lldb_private::Status::FromErrorString(unsupported_opcode_error);
return false;
}
@@ -898,10 +899,10 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function,
// buffer
// Write the virtual address of R into P
- Type *T = alloca_inst->getAllocatedType();
Type *Tptr = alloca_inst->getType();
- lldb::addr_t R = frame.Malloc(T);
+ lldb::addr_t R = frame.Malloc(alloca_size->getFixedValue(),
+ alloca_inst->getAlign().value());
if (R == LLDB_INVALID_ADDRESS) {
LLDB_LOGF(log, "Couldn't allocate memory for an AllocaInst");
diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp
index 6161f78182eef..4cba8051327a4 100644
--- a/llvm/lib/CodeGen/CodeGenPrepare.cpp
+++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp
@@ -2662,9 +2662,11 @@ bool CodeGenPrepare::optimizeCallInst(CallInst *CI, ModifyDT &ModifiedDT) {
if (!isAligned(PrefAlign, Offset2))
continue;
AllocaInst *AI;
- if ((AI = dyn_cast<AllocaInst>(Val)) && AI->getAlign() < PrefAlign &&
- DL->getTypeAllocSize(AI->getAllocatedType()) >= MinSize + Offset2)
- AI->setAlignment(PrefAlign);
+ if ((AI = dyn_cast<AllocaInst>(Val)) && AI->getAlign() < PrefAlign) {
+ std::optional<TypeSize> AllocaSize = AI->getAllocationSize(*DL);
+ if (AllocaSize && AllocaSize->getKnownMinValue() >= MinSize + Offset2)
+ AI->setAlignment(PrefAlign);
+ }
// Global variables can only be aligned if they are defined in this
// object (i.e. they are uniquely initialized in this object), and
// over-aligning global variables that have an explicit section is
diff --git a/llvm/lib/CodeGen/SafeStack.cpp b/llvm/lib/CodeGen/SafeStack.cpp
index 1c109a1f9fed1..d8c727df2a395 100644
--- a/llvm/lib/CodeGen/SafeStack.cpp
+++ b/llvm/lib/CodeGen/SafeStack.cpp
@@ -176,6 +176,8 @@ class SafeStack {
bool IsMemIntrinsicSafe(const MemIntrinsic *MI, const Use &U,
const Value *AllocaPtr, uint64_t AllocaSize);
+ bool IsAccessSafe(Value *Addr, TypeSize Size, const Value *AllocaPtr,
+ uint64_t AllocaSize);
bool IsAccessSafe(Value *Addr, uint64_t Size, const Value *AllocaPtr,
uint64_t AllocaSize);
@@ -196,14 +198,20 @@ class SafeStack {
};
uint64_t SafeStack::getStaticAllocaAllocationSize(const AllocaInst* AI) {
- uint64_t Size = DL.getTypeAllocSize(AI->getAllocatedType());
- if (AI->isArrayAllocation()) {
- auto C = dyn_cast<ConstantInt>(AI->getArraySize());
- if (!C)
- return 0;
- Size *= C->getZExtValue();
+ if (auto Size = AI->getAllocationSize(DL))
+ if (Size->isFixed())
+ return Size->getFixedValue();
+ return 0;
+}
+
+bool SafeStack::IsAccessSafe(Value *Addr, TypeSize AccessSize,
+ const Value *AllocaPtr, uint64_t AllocaSize) {
+ if (AccessSize.isScalable()) {
+ // In case we don't know the size at compile time we cannot verify if the
+ // access is safe.
+ return false;
}
- return Size;
+ return IsAccessSafe(Addr, AccessSize.getFixedValue(), AllocaPtr, AllocaSize);
}
bool SafeStack::IsAccessSafe(Value *Addr, uint64_t AccessSize,
diff --git a/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp b/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
index dfaabae6e1f97..7eacdc0bd7bc4 100644
--- a/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
@@ -142,12 +142,10 @@ void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf,
// do this if there is an extra alignment requirement.
if (AI->isStaticAlloca() &&
(TFI->isStackRealignable() || (Alignment <= StackAlign))) {
- const ConstantInt *CUI = cast<ConstantInt>(AI->getArraySize());
uint64_t TySize =
- MF->getDataLayout().getTypeAllocSize(Ty).getKnownMinValue();
-
- TySize *= CUI->getZExtValue(); // Get total allocated size.
- if (TySize == 0) TySize = 1; // Don't create zero-sized stack objects.
+ AI->getAllocationSize(MF->getDataLayout())->getKnownMinValue();
+ if (TySize == 0)
+ TySize = 1; // Don't create zero-sized stack objects.
int FrameIndex = INT_MAX;
auto Iter = CatchObjects.find(AI);
if (Iter != CatchObjects.end() && TLI->needsFixedCatchObjects()) {
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index ac90cd9ed164d..4071abb1d5292 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -11676,10 +11676,10 @@ findArgumentCopyElisionCandidates(const DataLayout &DL,
// Don't elide copies from the same argument twice.
const Value *Val = SI->getValueOperand()->stripPointerCasts();
const auto *Arg = dyn_cast<Argument>(Val);
+ std::optional<TypeSize> AllocaSize = AI->getAllocationSize(DL);
if (!Arg || Arg->hasPassPointeeByValueCopyAttr() ||
- Arg->getType()->isEmptyTy() ||
- DL.getTypeStoreSize(Arg->getType()) !=
- DL.getTypeAllocSize(AI->getAllocatedType()) ||
+ Arg->getType()->isEmptyTy() || !AllocaSize ||
+ DL.getTypeStoreSize(Arg->getType()) != *AllocaSize ||
!DL.typeSizeEqualsStoreSize(Arg->getType()) ||
ArgCopyElisionCandidates.count(Arg)) {
*Info = StaticAllocaInfo::Clobbered;
diff --git a/llvm/lib/CodeGen/StackProtector.cpp b/llvm/lib/CodeGen/StackProtector.cpp
index 9ddd61b0f20ef..5833dbb578f97 100644
--- a/llvm/lib/CodeGen/StackProtector.cpp
+++ b/llvm/lib/CodeGen/StackProtector.cpp
@@ -495,22 +495,23 @@ bool SSPLayoutAnalysis::requiresStackProtector(Function *F,
continue;
}
- if (Strong &&
- HasAddressTaken(
- AI, M->getDataLayout().getTypeAllocSize(AI->getAllocatedType()),
- M, VisitedPHIs)) {
- ++NumAddrTaken;
- if (!Layout)
- return true;
- Layout->insert(std::make_pair(AI, MachineFrameInfo::SSPLK_AddrOf));
- ORE.emit([&]() {
- return OptimizationRemark(DEBUG_TYPE, "StackProtectorAddressTaken",
- &I)
- << "Stack protection applied to function "
- << ore::NV("Function", F)
- << " due to the address of a local variable being taken";
- });
- NeedsProtector = true;
+ if (Strong) {
+ std::optional<TypeSize> AllocSize =
+ AI->getAllocationSize(M->getDataLayout());
+ if (!AllocSize || HasAddressTaken(AI, *AllocSize, M, VisitedPHIs)) {
+ ++NumAddrTaken;
+ if (!Layout)
+ return true;
+ Layout->insert(std::make_pair(AI, MachineFrameInfo::SSPLK_AddrOf));
+ ORE.emit([&]() {
+ return OptimizationRemark(DEBUG_TYPE,
+ "StackProtectorAddressTaken", &I)
+ << "Stack protection applied to function "
+ << ore::NV("Function", F)
+ << " due to the address of a local variable being taken";
+ });
+ NeedsProtector = true;
+ }
}
// Clear any PHIs that we visited, to make sure we examine all uses of
// any subsequent allocas that we look at.
diff --git a/llvm/lib/IR/Value.cpp b/llvm/lib/IR/Value.cpp
index a43d63077bf9f..8a9e2c163b8a7 100644
--- a/llvm/lib/IR/Value.cpp
+++ b/llvm/lib/IR/Value.cpp
@@ -942,9 +942,8 @@ uint64_t Value::getPointerDereferenceableBytes(const DataLayout &DL,
CanBeNull = true;
}
} else if (auto *AI = dyn_cast<AllocaInst>(this)) {
- if (!AI->isArrayAllocation()) {
- DerefBytes =
- DL.getTypeStoreSize(AI->getAllocatedType()).getKnownMinValue();
+ if (std::optional<TypeSize> Size = AI->getAllocationSize(DL)) {
+ DerefBytes = Size->getKnownMinValue();
CanBeNull = false;
CanBeFreed = false;
}
diff --git a/llvm/lib/Target/AMDGPU/AMDGPULibCalls.cpp b/llvm/lib/Target/AMDGPU/AMDGPULibCalls.cpp
index 821d7f38fcb41..c5c19d9d572b7 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPULibCalls.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPULibCalls.cpp
@@ -1333,7 +1333,7 @@ AMDGPULibCalls::insertSinCos(Value *Arg, FastMathFlags FMF, IRBuilder<> &B,
// TODO: Is it worth trying to preserve the location for the cos calls for the
// load?
- LoadInst *LoadCos = B.CreateLoad(Alloc->getAllocatedType(), Alloc);
+ LoadInst *LoadCos = B.CreateLoad(Arg->getType(), Alloc);
return {SinCos, LoadCos, SinCos};
}
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUTargetTransformInfo.cpp b/llvm/lib/Target/AMDGPU/AMDGPUTargetTransformInfo.cpp
index 35406a387cf0f..7b8c0e2f0e439 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUTargetTransformInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUTargetTransformInfo.cpp
@@ -206,9 +206,8 @@ void AMDGPUTTIImpl::getUnrollingPreferences(
dyn_cast<AllocaInst>(getUnderlyingObject(Ptr));
if (!Alloca || !Alloca->isStaticAlloca())
continue;
- Type *Ty = Alloca->getAllocatedType();
- unsigned AllocaSize = Ty->isSized() ? DL.getTypeAllocSize(Ty) : 0;
- if (AllocaSize > MaxAlloca)
+ auto AllocaSize = Alloca->getAllocationSize(DL);
+ if (!AllocaSize || AllocaSize->getFixedValue() > MaxAlloca)
continue;
} else if (AS == AMDGPUAS::LOCAL_ADDRESS ||
AS == AMDGPUAS::REGION_ADDRESS) {
@@ -1490,7 +1489,8 @@ static unsigned getCallArgsTotalAllocaSize(const CallBase *CB,
if (!AI || !AI->isStaticAlloca() || !AIVisited.insert(AI).second)
continue;
- AllocaSize += DL.getTypeAllocSize(AI->getAllocatedType());
+ if (auto Size = AI->getAllocationSize(DL))
+ AllocaSize += Size->getFixedValue();
}
return AllocaSize;
}
@@ -1544,10 +1544,13 @@ unsigned GCNTTIImpl::getCallerAllocaCost(const CallBase *CB,
Threshold += Threshold / 2;
}
- auto ArgAllocaSize = DL.getTypeAllocSize(AI->getAllocatedType());
+ auto ArgAllocaSize = AI->getAllocationSize(DL);
+ if (!ArgAllocaSize)
+ return 0;
// Attribute the bonus proportionally to the alloca size
- unsigned AllocaThresholdBonus = (Threshold * ArgAllocaSize) / AllocaSize;
+ unsigned AllocaThresholdBonus =
+ (Threshold * ArgAllocaSize->getFixedValue()) / AllocaSize;
return AllocaThresholdBonus;
}
diff --git a/llvm/lib/Target/NVPTX/NVPTXLowerAlloca.cpp b/llvm/lib/Target/NVPTX/NVPTXLowerAlloca.cpp
index 88bc000f39bf7..5dc18e9ac4e62 100644
--- a/llvm/lib/Target/NVPTX/NVPTXLowerAlloca.cpp
+++ b/llvm/lib/Target/NVPTX/NVPTXLowerAlloca.cpp
@@ -64,16 +64,13 @@ bool NVPTXLowerAlloca::runOnFunction(Function &F) {
if (auto allocaInst = dyn_cast<AllocaInst>(&I)) {
Changed = true;
- PointerType *AllocInstPtrTy =
- cast<PointerType>(allocaInst->getType()->getScalarType());
- unsigned AllocAddrSpace = AllocInstPtrTy->getAddressSpace();
+ unsigned AllocAddrSpace = allocaInst->getAddressSpace();
assert((AllocAddrSpace == ADDRESS_SPACE_GENERIC ||
AllocAddrSpace == ADDRESS_SPACE_LOCAL) &&
"AllocaInst can only be in Generic or Local address space for "
"NVPTX.");
Instruction *AllocaInLocalAS = allocaInst;
- auto ETy = allocaInst->getAllocatedType();
// We need to make sure that LLVM has info that alloca needs to go to
// ADDRESS_SPACE_LOCAL for InferAddressSpace pass.
@@ -87,14 +84,16 @@ bool NVPTXLowerAlloca::runOnFunction(Function &F) {
if (AllocAddrSpace == ADDRESS_SPACE_GENERIC) {
auto ASCastToLocalAS = new AddrSpaceCastInst(
allocaInst,
- PointerType::get(ETy->getContext(), ADDRESS_SPACE_LOCAL), "");
+ PointerType::get(allocaInst->getContext(), ADDRESS_SPACE_LOCAL),
+ "");
ASCastToLocalAS->insertAfter(allocaInst->getIterator());
AllocaInLocalAS = ASCastToLocalAS;
}
auto AllocaInGenericAS = new AddrSpaceCastInst(
AllocaInLocalAS,
- PointerType::get(ETy->getContext(), ADDRESS_SPACE_GENERIC), "");
+ PointerType::get(allocaInst->getContext(), ADDRESS_SPACE_GENERIC),
+ "");
AllocaInGenericAS->insertAfter(AllocaInLocalAS->getIterator());
for (Use &AllocaUse : llvm::make_early_inc_range(allocaInst->uses())) {
diff --git a/llvm/lib/Target/X86/X86WinEHState.cpp b/llvm/lib/Target/X86/X86WinEHState.cpp
index a650f6f069e5f..b568f1b4086ed 100644
--- a/llvm/lib/Target/X86/X86WinEHState.cpp
+++ b/llvm/lib/Target/X86/X86WinEHState.cpp
@@ -788,8 +788,8 @@ void WinEHStatePass::addStateStores(Function &F, WinEHFuncInfo &FuncInfo) {
IRBuilder<> Builder(Call);
Value *State;
if (InCleanup) {
- Value *StateField = Builder.CreateStructGEP(RegNode->getAllocatedType(),
- RegNode, StateFieldIndex);
+ Value *StateField =
+ Builder.CreateStructGEP(RegNodeTy, RegNode, StateFieldIndex);
State = Builder.CreateLoad(Builder.getInt32Ty(), StateField);
} else {
State = Builder.getInt32(getStateForCall(BlockColors, FuncInfo, *Call));
@@ -800,8 +800,8 @@ void WinEHStatePass::addStateStores(Function &F, WinEHFuncInfo &FuncInfo) {
void WinEHStatePass::insertStateNumberStore(Instruction *IP, int State) {
IRBuilder<> Builder(IP);
- Value *StateField = Builder.CreateStructGEP(RegNode->getAllocatedType(),
- RegNode, StateFieldIndex);
+ Value *StateField =
+ Builder.CreateStructGEP(RegNodeTy, RegNode, StateFieldIndex);
Builder.CreateStore(Builder.getInt32(State), StateField);
}
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp b/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
index 5bca0bb8846c0..6ca3e496da7f4 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
@@ -872,20 +872,9 @@ static bool isObjectSizeLessThanOrEq(Value *V, uint64_t MaxSize,
// If we know how big this object is, and it is less than MaxSize, continue
// searching. Otherwise, return false.
if (AllocaInst *AI = dyn_cast<AllocaInst>(P)) {
- if (!AI->getAllocatedType()->isSized())
- return false;
-
- ConstantInt *CS = dyn_cast<ConstantInt>(AI->getArraySize());
- if (!CS)
- return false;
-
- TypeSize TS = DL.getTypeAllocSize(AI->getAllocatedType());
- if (TS.isScalable())
- return false;
- // Make sure that, even if the multiplication below would wrap as an
- // uint64_t, we still do the right thing.
- if ((CS->getValue().zext(128) * APInt(128, TS.getFixedValue()))
- .ugt(MaxSize))
+ std::optional<TypeSize> AllocSize = AI->getAllocationSize(DL);
+ if (!AllocSize || AllocSize->isScalable() ||
+ AllocSize->getFixedValue() > MaxSize)
return false;
continue;
}
diff --git a/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp b/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
index d72d216e0b3b2..7f061e2259711 100644
--- a/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
+++ b/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
@@ -1124,17 +1124,11 @@ void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB,
InsertBefore = AI->getNextNode();
// Make an estimate on the stack usage.
- if (AI->isStaticAlloca()) {
- uint32_t Bytes = DL.getTypeAllocSize(AI->getAllocatedType());
- if (AI->isArrayAllocation()) {
- if (const ConstantInt *arraySize =
- dyn_cast<ConstantInt>(AI->getArraySize())) {
- Bytes *= arraySize->getZExtValue();
- } else {
- HasDynamicAlloc = true;
- }
- }
- EstimatedStackSize += Bytes;
+ if (auto AllocaSize = AI->getAllocationSize(DL)) {
+ if (AllocaSize->isFixed())
+ EstimatedStackSize += AllocaSize->getFixedValue();
+ else
+ HasDynamicAlloc = true;
} else {
HasDynamicAlloc = true;
}
diff --git a/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp b/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
index f054b21f2e9dd..7ad2955c0abb0 100644
--- a/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
+++ b/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
@@ -869,16 +869,12 @@ bool MemCpyOptPass::performCallSlotOptzn(Instruction *cpyLoad,
if (!srcAlloca)
return false;
- ConstantInt *srcArraySize = dyn_cast<ConstantInt>(srcAlloca->getArraySize());
- if (!srcArraySize)
- return false;
-
const DataLayout &DL = cpyLoad->getDataLayout();
- TypeSize SrcAllocaSize = DL.getTypeAllocSize(srcAlloca->getAllocatedType());
- // We can't optimize scalable types.
- if (SrcAllocaSize.isScalable())
+ // We can't optimize scalable types or variable-length allocas.
+ std::optional<TypeSize> SrcAllocaSize = srcAlloca->getAllocationSize(DL);
+ if (!SrcAllocaSize || SrcAllocaSize->isScalable())
return false;
- uint64_t srcSize = SrcAllocaSize * srcArraySize->getZExtValue();
+ uint64_t srcSize = SrcAllocaSize->getFixedValue();
if (cpySize < srcSize)
return false;
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/combiner-load-store-indexing.ll b/llvm/test/CodeGen/AArch64/GlobalISel/combiner-load-store-indexing.ll
index cae1b3949dca7..5b04f63679161 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/combiner-load-store-indexing.ll
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/combiner-load-store-indexing.ll
@@ -104,7 +104,7 @@ define ptr @test_alloca_load_pre() {
; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 42
; CHECK-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0.ptr
; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[FRAME_INDEX]], [[C]](s64)
- ; CHECK-NEXT: [[LOAD:%[0-9]+]]:_(s8) = G_LOAD [[PTR_ADD]](p0) :: (volatile load (s8) from %ir.next)
+ ; CHECK-NEXT: [[LOAD:%[0-9]+]]:_(s8) = G_LOAD [[PTR_ADD]](p0) :: (volatile dereferenceable load (s8) from %ir.next)
; CHECK-NEXT: $x0 = COPY [[PTR_ADD]](p0)
; CHECK-NEXT: RET_ReallyLR implicit $x0
%ptr = alloca i8, i32 128
@@ -183,7 +183,7 @@ define ptr @test_load_post_alloca() {
; CHECK-LABEL: name: test_load_post_alloca
; CHECK: bb.1 (%ir-block.0):
; CHECK-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0.ptr
- ; CHECK-NEXT: [[LOAD:%[0-9]+]]:_(s8) = G_LOAD [[FRAME_INDEX]](p0) :: (volatile load (s8) from %ir.ptr)
+ ; CHECK-NEXT: [[LOAD:%[0-9]+]]:_(s8) = G_LOAD [[FRAME_INDEX]](p0) :: (volatile dereferenceable load (s8) from %ir.ptr)
; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 42
; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[FRAME_INDEX]], [[C]](s64)
; CHECK-NEXT: $x0 = COPY [[PTR_ADD]](p0)
diff --git a/llvm/test/CodeGen/AArch64/safestack_scalar.ll b/llvm/test/CodeGen/AArch64/safestack_scalar.ll
new file mode 100644
index 0000000000000..f8675e7a709d3
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/safestack_scalar.ll
@@ -0,0 +1,17 @@
+; RUN: llc -mtriple=aarch64-linux-gnu -stop-after=safe-stack < %s | FileCheck %s
+
+...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/203745
More information about the llvm-branch-commits
mailing list