diff --git a/llvm/lib/Transforms/Utils/Debugify.cpp b/llvm/lib/Transforms/Utils/Debugify.cpp --- a/llvm/lib/Transforms/Utils/Debugify.cpp +++ b/llvm/lib/Transforms/Utils/Debugify.cpp @@ -44,8 +44,9 @@ raw_ostream &dbg() { return Quiet ? nulls() : errs(); } -uint64_t getAllocSizeInBits(Module &M, Type *Ty) { - return Ty->isSized() ? M.getDataLayout().getTypeAllocSizeInBits(Ty) : 0; +TypeSize getAllocSizeInBits(Module &M, Type *Ty) { + return Ty->isSized() ? M.getDataLayout().getTypeAllocSizeInBits(Ty) + : TypeSize::getFixed(0); } bool isFunctionSkipped(Function &F) { @@ -276,7 +277,7 @@ return false; Type *Ty = V->getType(); - uint64_t ValueOperandSize = getAllocSizeInBits(M, Ty); + TypeSize ValueOperandSize = getAllocSizeInBits(M, Ty); Optional DbgVarSize = DVI->getFragmentSizeInBits(); if (!ValueOperandSize || !DbgVarSize) return false; @@ -285,7 +286,7 @@ if (Ty->isIntegerTy()) { auto Signedness = DVI->getVariable()->getSignedness(); if (Signedness && *Signedness == DIBasicType::Signedness::Signed) - HasBadSize = ValueOperandSize < *DbgVarSize; + HasBadSize = ValueOperandSize.getFixedSize() < *DbgVarSize; } else { HasBadSize = ValueOperandSize != *DbgVarSize; } diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp --- a/llvm/lib/Transforms/Utils/Local.cpp +++ b/llvm/lib/Transforms/Utils/Local.cpp @@ -1368,16 +1368,22 @@ /// least n bits. static bool valueCoversEntireFragment(Type *ValTy, DbgVariableIntrinsic *DII) { const DataLayout &DL = DII->getModule()->getDataLayout(); - uint64_t ValueSize = DL.getTypeAllocSizeInBits(ValTy); - if (auto FragmentSize = DII->getFragmentSizeInBits()) - return ValueSize >= *FragmentSize; + TypeSize ValueSize = DL.getTypeAllocSizeInBits(ValTy); + if (Optional FragmentSize = DII->getFragmentSizeInBits()) { + assert(!ValueSize.isScalable() && + "Fragments don't work on scalable types."); + return ValueSize.getFixedSize() >= *FragmentSize; + } // We can't always calculate the size of the DI variable (e.g. if it is a // VLA). Try to use the size of the alloca that the dbg intrinsic describes // intead. if (DII->isAddressOfVariable()) if (auto *AI = dyn_cast_or_null(DII->getVariableLocation())) - if (auto FragmentSize = AI->getAllocationSizeInBits(DL)) - return ValueSize >= *FragmentSize; + if (Optional FragmentSize = AI->getAllocationSizeInBits(DL)) { + assert(ValueSize.isScalable() == FragmentSize->isScalable() && + "Both sizes should agree on the scalable flag."); + return TypeSize::isKnownGE(ValueSize, *FragmentSize); + } // Could not determine size of variable. Conservatively return false. return false; } diff --git a/llvm/test/Transforms/InstCombine/debug-declare-no-warnings-on-scalable-vectors.ll b/llvm/test/Transforms/InstCombine/debug-declare-no-warnings-on-scalable-vectors.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/debug-declare-no-warnings-on-scalable-vectors.ll @@ -0,0 +1,42 @@ +; RUN: opt -mtriple aarch64-gnu-linux -mattr=+sve -instcombine -S < %s 2>%t | FileCheck %s +; RUN: FileCheck --check-prefix=WARN --allow-empty %s <%t + +; If this check fails please read +; clang/test/CodeGen/aarch64-sve-intrinsics/README for instructions on +; how to resolve it. + +; WARN-NOT: warning + +; CHECK-LABEL: @debug_local_scalable( +define @debug_local_scalable( %tostore) { + %vx = alloca , align 16 + call void @llvm.dbg.declare(metadata * %vx, metadata !5, metadata !DIExpression()), !dbg !15 + store %tostore, * %vx, align 16 + %ret = call @f(* %vx) + ret %ret +} + +declare @f(*) + +; Function Attrs: nofree nosync nounwind readnone speculatable willreturn +declare void @llvm.dbg.declare(metadata, metadata, metadata) + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 12.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "/tmp/test.c", directory: "/tmp/") +!2 = !{} +!3 = !{i32 7, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !DILocalVariable(name: "vx", scope: !6, file: !7, line: 26, type: !8) +!6 = distinct !DISubprogram(name: "debug_local_scalable", scope: null, file: !1, line: 25, scopeLine: 25, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0) +!7 = !DIFile(filename: "test.c", directory: "/tmp/") +!8 = !DIDerivedType(tag: DW_TAG_typedef, name: "svfloat64_t", file: !9, line: 56, baseType: !10) +!9 = !DIFile(filename: "arm_sve.h", directory: "/tmp/") +!10 = !DIDerivedType(tag: DW_TAG_typedef, name: "__SVFloat64_t", file: !1, baseType: !11) +!11 = !DICompositeType(tag: DW_TAG_array_type, baseType: !12, flags: DIFlagVector, elements: !13) +!12 = !DIBasicType(name: "double", size: 64, encoding: DW_ATE_float) +!13 = !{!14} +!14 = !DISubrange(lowerBound: 0, upperBound: !DIExpression(DW_OP_constu, 1, DW_OP_bregx, 46, 0, DW_OP_mul, DW_OP_constu, 1, DW_OP_minus)) +!15 = !DILocation(line: 26, column: 15, scope: !6)