[InstCombine] Update valueCoversEntireFragment to use TypeSize

* Update valueCoversEntireFragment to use TypeSize.
* Add a regression test.
* Assertions have been added to protect untested codepaths.

Reviewed By: sdesmalen

Differential Revision: https://reviews.llvm.org/D91806
This commit is contained in:
Francesco Petrogalli 2021-01-06 17:12:23 +00:00 committed by Peter Waller
parent 0a3cf7f476
commit dfd3384fee
2 changed files with 47 additions and 5 deletions

View File

@ -1340,16 +1340,22 @@ static bool PhiHasDebugValue(DILocalVariable *DIVar,
/// 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<uint64_t> 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<AllocaInst>(DII->getVariableLocation()))
if (auto FragmentSize = AI->getAllocationSizeInBits(DL))
return ValueSize >= *FragmentSize;
if (Optional<TypeSize> 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;
}

View File

@ -0,0 +1,36 @@
; RUN: opt -instcombine -S < %s 2>%t | FileCheck %s
; RUN: FileCheck --check-prefix=WARN --allow-empty %s <%t
; This test is defending against a TypeSize message raised in the method
; `valueCoversEntireFragment` in Local.cpp because of an implicit cast from
; `TypeSize` to `uint64_t`. This particular TypeSize message only occurred when
; debug info was available.
; If this check fails please read
; clang/test/CodeGen/aarch64-sve-intrinsics/README for instructions on
; how to resolve it.
; This test must not produce any warnings. Prior to this test being introduced,
; it produced a warning containing the text "TypeSize is not scalable".
; 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 !3, metadata !DIExpression()), !dbg !5
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>*)
declare void @llvm.dbg.declare(metadata, metadata, metadata)
!llvm.module.flags = !{!2}
!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1)
!1 = !DIFile(filename: "/tmp/test.c", directory: "/tmp/")
!2 = !{i32 2, !"Debug Info Version", i32 3}
!3 = !DILocalVariable(scope: !4)
!4 = distinct !DISubprogram(unit: !0)
!5 = !DILocation(scope: !4)