fpetrogalli updated this revision to Diff 306643. fpetrogalli added a comment.
This last change is trying to remove the failure at https://reviews.llvm.org/harbormaster/unit/view/196974/ I haven’t been able to reproduce such failure on my dev machine, so I just changed the RUN lines in the test (added `-c`, used `2>%t`) to see if the bot is going to be happy with the new invocation. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D91806/new/ https://reviews.llvm.org/D91806 Files: clang/test/CodeGen/aarch64-sve-acle-rel-note.c llvm/include/llvm/IR/Instructions.h llvm/include/llvm/IR/IntrinsicInst.h llvm/lib/IR/Instructions.cpp llvm/lib/IR/IntrinsicInst.cpp llvm/lib/Transforms/Coroutines/CoroFrame.cpp llvm/lib/Transforms/Utils/Debugify.cpp llvm/lib/Transforms/Utils/Local.cpp llvm/test/Transforms/InstCombine/debug-declare-no-warnings-on-scalable-vectors.ll
Index: llvm/test/Transforms/InstCombine/debug-declare-no-warnings-on-scalable-vectors.ll =================================================================== --- /dev/null +++ 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 <vscale x 2 x double> @debug_local_scalable(<vscale x 2 x double> %tostore) { + %vx = alloca <vscale x 2 x double>, align 16 + call void @llvm.dbg.declare(metadata <vscale x 2 x double>* %vx, metadata !5, metadata !DIExpression()), !dbg !15 + store <vscale x 2 x double> %tostore, <vscale x 2 x double>* %vx, align 16 + %ret = call <vscale x 2 x double> @f(<vscale x 2 x double>* %vx) + ret <vscale x 2 x double> %ret +} + +declare <vscale x 2 x double> @f(<vscale x 2 x double>*) + +; 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) Index: llvm/lib/Transforms/Utils/Local.cpp =================================================================== --- llvm/lib/Transforms/Utils/Local.cpp +++ llvm/lib/Transforms/Utils/Local.cpp @@ -1368,16 +1368,16 @@ /// 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<TypeSize> FragmentSize = DII->getFragmentSizeInBits()) + return TypeSize::isKnownGE(ValueSize, *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<AllocaInst>(DII->getVariableLocation())) - if (auto FragmentSize = AI->getAllocationSizeInBits(DL)) - return ValueSize >= *FragmentSize; + if (Optional<TypeSize> FragmentSize = AI->getAllocationSizeInBits(DL)) + return TypeSize::isKnownGE(ValueSize, *FragmentSize); // Could not determine size of variable. Conservatively return false. return false; } Index: llvm/lib/Transforms/Utils/Debugify.cpp =================================================================== --- llvm/lib/Transforms/Utils/Debugify.cpp +++ 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,8 +277,8 @@ return false; Type *Ty = V->getType(); - uint64_t ValueOperandSize = getAllocSizeInBits(M, Ty); - Optional<uint64_t> DbgVarSize = DVI->getFragmentSizeInBits(); + TypeSize ValueOperandSize = getAllocSizeInBits(M, Ty); + Optional<TypeSize> 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 = TypeSize::isKnownLT(ValueOperandSize, *DbgVarSize); } else { HasBadSize = ValueOperandSize != *DbgVarSize; } Index: llvm/lib/Transforms/Coroutines/CoroFrame.cpp =================================================================== --- llvm/lib/Transforms/Coroutines/CoroFrame.cpp +++ llvm/lib/Transforms/Coroutines/CoroFrame.cpp @@ -576,8 +576,9 @@ StackLifetimeAnalyzer.getLiveRange(AI2)); }; auto GetAllocaSize = [&](const AllocaInfo &A) { - Optional<uint64_t> RetSize = A.Alloca->getAllocationSizeInBits(DL); - assert(RetSize && "We can't handle scalable type now.\n"); + Optional<TypeSize> RetSize = A.Alloca->getAllocationSizeInBits(DL); + assert(RetSize && "Variable Length Arrays (VLA) are not supported.\n"); + assert(!RetSize->isScalable() && "Scalable vectors are not yet supported"); return RetSize.getValue(); }; // Put larger allocas in the front. So the larger allocas have higher @@ -585,7 +586,7 @@ // AllocaSet would be ordered. So we can get the largest Alloca in one // AllocaSet easily. sort(FrameData.Allocas, [&](const auto &Iter1, const auto &Iter2) { - return GetAllocaSize(Iter1) > GetAllocaSize(Iter2); + return TypeSize::isKnownGT(GetAllocaSize(Iter1), GetAllocaSize(Iter2)); }); for (const auto &A : FrameData.Allocas) { AllocaInst *Alloca = A.Alloca; Index: llvm/lib/IR/IntrinsicInst.cpp =================================================================== --- llvm/lib/IR/IntrinsicInst.cpp +++ llvm/lib/IR/IntrinsicInst.cpp @@ -52,10 +52,13 @@ return nullptr; } -Optional<uint64_t> DbgVariableIntrinsic::getFragmentSizeInBits() const { - if (auto Fragment = getExpression()->getFragmentInfo()) - return Fragment->SizeInBits; - return getVariable()->getSizeInBits(); +Optional<TypeSize> DbgVariableIntrinsic::getFragmentSizeInBits() const { + if (Optional<DIExpression::FragmentInfo> Fragment = + getExpression()->getFragmentInfo()) + return TypeSize::getFixed(Fragment->SizeInBits); + if (Optional<uint64_t> Size = getVariable()->getSizeInBits()) + return TypeSize::getFixed(Size.getValue()); + return None; } int llvm::Intrinsic::lookupLLVMIntrinsicByName(ArrayRef<const char *> NameTable, Index: llvm/lib/IR/Instructions.cpp =================================================================== --- llvm/lib/IR/Instructions.cpp +++ llvm/lib/IR/Instructions.cpp @@ -49,13 +49,14 @@ // AllocaInst Class //===----------------------------------------------------------------------===// -Optional<uint64_t> +Optional<TypeSize> AllocaInst::getAllocationSizeInBits(const DataLayout &DL) const { - uint64_t Size = DL.getTypeAllocSizeInBits(getAllocatedType()); + TypeSize Size = DL.getTypeAllocSizeInBits(getAllocatedType()); if (isArrayAllocation()) { auto *C = dyn_cast<ConstantInt>(getArraySize()); if (!C) return None; + assert(!Size.isScalable() && "Array elements cannot have a scalable size"); Size *= C->getZExtValue(); } return Size; Index: llvm/include/llvm/IR/IntrinsicInst.h =================================================================== --- llvm/include/llvm/IR/IntrinsicInst.h +++ llvm/include/llvm/IR/IntrinsicInst.h @@ -152,7 +152,7 @@ /// Get the size (in bits) of the variable, or fragment of the variable that /// is described. - Optional<uint64_t> getFragmentSizeInBits() const; + Optional<TypeSize> getFragmentSizeInBits() const; /// \name Casting methods /// @{ Index: llvm/include/llvm/IR/Instructions.h =================================================================== --- llvm/include/llvm/IR/Instructions.h +++ llvm/include/llvm/IR/Instructions.h @@ -106,7 +106,7 @@ /// Get allocation size in bits. Returns None if size can't be determined, /// e.g. in case of a VLA. - Optional<uint64_t> getAllocationSizeInBits(const DataLayout &DL) const; + Optional<TypeSize> getAllocationSizeInBits(const DataLayout &DL) const; /// Return the type that is being allocated by the instruction. Type *getAllocatedType() const { return AllocatedType; } Index: clang/test/CodeGen/aarch64-sve-acle-rel-note.c =================================================================== --- /dev/null +++ clang/test/CodeGen/aarch64-sve-acle-rel-note.c @@ -0,0 +1,35 @@ +// REQUIRES: aarch64-registered-target +// RUN: %clang --target=aarch64-linux-gnu -march=armv8-a+sve -S -emit-llvm -o - -c %s -Werror -Wall -g -O0 2>%t | FileCheck %s +// RUN: FileCheck --check-prefix=WARN --allow-empty %s <%t +// RUN: %clang --target=aarch64-linux-gnu -march=armv8-a+sve -S -emit-llvm -o - -c %s -Werror -Wall -g -O1 2>%t | FileCheck %s +// RUN: FileCheck --check-prefix=WARN --allow-empty %s <%t +// RUN: %clang --target=aarch64-linux-gnu -march=armv8-a+sve -S -emit-llvm -o - -c %s -Werror -Wall -g -O3 2>%t | FileCheck %s +// RUN: FileCheck --check-prefix=WARN --allow-empty %s <%t +// RUN: %clang --target=aarch64-linux-gnu -march=armv8-a+sve -S -o - -c %s -Werror -Wall -g -O3 2>%t | FileCheck %s --check-prefix=ASM +// RUN: FileCheck --check-prefix=WARN --allow-empty %s <%t + +// This test makes sure that the SVE ACLE example in the release notes +// of CLANG 11 does not generate warning like the following: +// +// "warning: Compiler has made implicit assumption that TypeSize is +// not scalable. This may or may not lead to broken code." + +// If this check fails please read +// clang/test/CodeGen/aarch64-sve-intrinsics/README for instructions +// on how to resolve it. +// +// WARN-NOT: warning + +#include <arm_sve.h> + +// CHECK-LABEL: @VLA_add_arrays( +// ASM-LABEL: VLA_add_arrays: +void VLA_add_arrays(double *x, double *y, double *out, unsigned N) { + for (unsigned i = 0; i < N; i += svcntd()) { + svbool_t Pg = svwhilelt_b64(i, N); + svfloat64_t vx = svld1(Pg, &x[i]); + svfloat64_t vy = svld1(Pg, &y[i]); + svfloat64_t vout = svadd_x(Pg, vx, vy); + svst1(Pg, &out[i], vout); + } +}
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits