Currently, ArgPromotion may leave metadata uses of promoted values, which will end up in the wrong function, creating invalid IR. PR33641 fixed this for dead arguments, but it can be also be triggered arguments with users that are promoted (see the updated test case). We also have to drop uses to them after promoting them. We need to do this after dealing with the non-metadata uses, so I also moved the empty use case to the loop that deals with updating the arguments of the new function. Reviewed By: aprantl Differential Revision: https://reviews.llvm.org/D85127
93 lines
3.3 KiB
LLVM
93 lines
3.3 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
|
|
; RUN: opt -argpromotion -verify -dse -S %s -o - | FileCheck %s
|
|
|
|
; Fix for PR33641. ArgumentPromotion removed the argument to bar but left the call to
|
|
; dbg.value which still used the removed argument.
|
|
|
|
; The %p argument should be removed, and the use of it in dbg.value should be
|
|
; changed to undef.
|
|
|
|
%p_t = type i16*
|
|
%fun_t = type void (%p_t)*
|
|
|
|
define void @foo() {
|
|
; CHECK-LABEL: define {{[^@]+}}@foo()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
%tmp = alloca %fun_t
|
|
store %fun_t @bar, %fun_t* %tmp
|
|
ret void
|
|
}
|
|
|
|
define internal void @bar(%p_t %p) {
|
|
; CHECK-LABEL: define {{[^@]+}}@bar()
|
|
; CHECK-NEXT: call void @llvm.dbg.value(metadata i16* undef, metadata !3, metadata !DIExpression()), !dbg !5
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
call void @llvm.dbg.value(metadata %p_t %p, metadata !4, metadata !5), !dbg !6
|
|
ret void
|
|
}
|
|
|
|
declare void @llvm.dbg.value(metadata, metadata, metadata)
|
|
|
|
|
|
; Test case where the promoted argument has uses in @callee and we need to
|
|
; retain a reference to the original function, because it is stored in @storer.
|
|
define void @storer({i32, i32}* %ptr) {
|
|
; CHECK-LABEL: define {{[^@]+}}@storer
|
|
; CHECK-SAME: ({ i32, i32 }* [[PTR:%.*]])
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
%tmp = alloca i32 ({i32, i32}*)*
|
|
store i32 ({i32, i32}*)* @callee, i32 ({i32, i32}*)** %tmp
|
|
ret void
|
|
}
|
|
|
|
define i32 @caller() {
|
|
; CHECK-LABEL: define {{[^@]+}}@caller()
|
|
; CHECK-NEXT: [[TMP:%.*]] = alloca { i32, i32 }, align 8
|
|
; CHECK-NEXT: [[F_1:%.*]] = getelementptr { i32, i32 }, { i32, i32 }* [[TMP]], i32 0, i32 1
|
|
; CHECK-NEXT: store i32 10, i32* [[F_1]], align 4
|
|
; CHECK-NEXT: [[TMP_IDX:%.*]] = getelementptr { i32, i32 }, { i32, i32 }* [[TMP]], i64 0, i32 1
|
|
; CHECK-NEXT: [[TMP_IDX_VAL:%.*]] = load i32, i32* [[TMP_IDX]], align 4
|
|
; CHECK-NEXT: [[RES:%.*]] = call i32 @callee(i32 [[TMP_IDX_VAL]])
|
|
; CHECK-NEXT: ret i32 [[RES]]
|
|
;
|
|
%tmp = alloca {i32, i32}
|
|
%f.1 = getelementptr {i32, i32}, {i32, i32}* %tmp, i32 0, i32 1
|
|
store i32 10, i32* %f.1
|
|
%res = call i32 @callee({i32, i32}* %tmp)
|
|
ret i32 %res
|
|
}
|
|
|
|
define internal i32 @callee({i32, i32}* %ptr) !dbg !7 {
|
|
; CHECK-LABEL: define {{[^@]+}}@callee
|
|
; CHECK-SAME: (i32 [[PTR_0_1_VAL:%.*]]) !dbg !6
|
|
; CHECK-NEXT: call void @llvm.dbg.value(metadata { i32, i32 }* undef, metadata !7, metadata !DIExpression()), !dbg !8
|
|
; CHECK-NEXT: call void @llvm.dbg.value(metadata i32 [[PTR_0_1_VAL]], metadata !7, metadata !DIExpression()), !dbg !8
|
|
; CHECK-NEXT: ret i32 [[PTR_0_1_VAL]]
|
|
;
|
|
call void @llvm.dbg.value(metadata {i32, i32}* %ptr, metadata !8, metadata !9), !dbg !10
|
|
%f.1 = getelementptr {i32, i32}, {i32, i32}* %ptr, i32 0, i32 1
|
|
%l.1 = load i32, i32* %f.1
|
|
call void @llvm.dbg.value(metadata i32 %l.1, metadata !8, metadata !9), !dbg !10
|
|
ret i32 %l.1
|
|
}
|
|
|
|
|
|
|
|
!llvm.dbg.cu = !{!0}
|
|
!llvm.module.flags = !{!2}
|
|
|
|
!0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1)
|
|
!1 = !DIFile(filename: "test.c", directory: "")
|
|
!2 = !{i32 2, !"Debug Info Version", i32 3}
|
|
!3 = distinct !DISubprogram(name: "bar", unit: !0)
|
|
!4 = !DILocalVariable(name: "p", scope: !3)
|
|
!5 = !DIExpression()
|
|
!6 = !DILocation(line: 1, column: 1, scope: !3)
|
|
!7 = distinct !DISubprogram(name: "callee", unit: !0)
|
|
!8 = !DILocalVariable(name: "c", scope: !7)
|
|
!9 = !DIExpression()
|
|
!10 = !DILocation(line: 2, column: 2, scope: !7)
|