diff --git a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp --- a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp +++ b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp @@ -38,12 +38,14 @@ #include "llvm/IR/Instruction.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/IntrinsicInst.h" +#include "llvm/IR/Value.h" #include "llvm/IR/NoFolder.h" #include "llvm/Support/Alignment.h" #include "llvm/Support/Casting.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FileSystem.h" +#include "llvm/Support/MathExtras.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Transforms/IPO/ArgumentPromotion.h" #include "llvm/Transforms/Utils/Local.h" @@ -6356,7 +6358,8 @@ continue; if (Value *Align = getAllocAlignment(AI.CB, TLI)) { - if (!getAPInt(A, *this, *Align)) { + Optional APAlign = getAPInt(A, *this, *Align); + if (!APAlign) { // Can't generate an alloca which respects the required alignment // on the allocation. LLVM_DEBUG(dbgs() << "[H2S] Unknown allocation alignment: " << *AI.CB @@ -6364,6 +6367,14 @@ AI.Status = AllocationInfo::INVALID; Changed = ChangeStatus::CHANGED; continue; + } else { + uint64_t AlignInt = APAlign.getValue().getZExtValue(); + if (AlignInt > llvm::Value::MaximumAlignment || !isPowerOf2_64(AlignInt)) { + LLVM_DEBUG(dbgs() << "[H2S] Invalid allocation alignment: " << AlignInt << "\n"); + AI.Status = AllocationInfo::INVALID; + Changed = ChangeStatus::CHANGED; + continue; + } } } diff --git a/llvm/test/Transforms/Attributor/heap_to_stack.ll b/llvm/test/Transforms/Attributor/heap_to_stack.ll --- a/llvm/test/Transforms/Attributor/heap_to_stack.ll +++ b/llvm/test/Transforms/Attributor/heap_to_stack.ll @@ -218,6 +218,20 @@ ret void } +; leave alone a constant-but-invalid alignment +define void @test3d(i8* %p) { +; CHECK-LABEL: define {{[^@]+}}@test3d +; CHECK-SAME; (i8* nocapture [[P:%.*]]) { +; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @aligned_alloc(i64 allocalign noundef 33, i64 noundef 128) +; CHECK: tail call void @free(i8* noalias nocapture [[TMP1]]) +; CHECK-NEXT: ret void +; + %1 = tail call noalias i8* @aligned_alloc(i64 allocalign 33, i64 128) + tail call void @nofree_arg_only(i8* %1, i8* %p) + tail call void @free(i8* %1) + ret void +} + declare noalias i8* @calloc(i64, i64) define void @test0() {