146 lines
4.5 KiB
YAML
146 lines
4.5 KiB
YAML
# RUN: llc -mtriple=x86_64-unknown-unknown %s -o - -run-pass=simple-register-coalescing | FileCheck %s
|
|
# PR40010: DBG_VALUEs do not contribute to the liveness of virtual registers,
|
|
# and the register coalescer would merge new live values on top of DBG_VALUEs,
|
|
# leading to them presenting new (wrong) values to the debugger. Test that
|
|
# when out of liveness, coalescing will mark DBG_VALUEs in non-live locations
|
|
# as undef.
|
|
--- |
|
|
; ModuleID = './test.ll'
|
|
source_filename = "./test.ll"
|
|
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
|
|
|
; Function Attrs: nounwind readnone speculatable
|
|
declare void @llvm.dbg.value(metadata, metadata, metadata) #0
|
|
|
|
; Original IR source here:
|
|
define i32 @test(i32* %pin) {
|
|
entry:
|
|
br label %start.test1
|
|
|
|
start.test1: ; preds = %start, %entry
|
|
%foo = phi i32 [ 0, %entry ], [ %bar, %start.test1 ]
|
|
%baz = load i32, i32* %pin, align 1
|
|
%qux = xor i32 %baz, 1234
|
|
%bar = add i32 %qux, %foo
|
|
call void @llvm.dbg.value(metadata i32 %foo, metadata !3, metadata !DIExpression()), !dbg !5
|
|
%cmp = icmp ugt i32 %bar, 1000000
|
|
br i1 %cmp, label %leave, label %start.test1
|
|
|
|
leave: ; preds = %start
|
|
ret i32 %bar
|
|
}
|
|
|
|
; Stubs to appease the MIR parser
|
|
define i32 @test2(i32* %pin) {
|
|
entry:
|
|
ret i32 0
|
|
start.test2:
|
|
ret i32 0
|
|
leave:
|
|
ret i32 0
|
|
}
|
|
|
|
; Function Attrs: nounwind
|
|
declare void @llvm.stackprotector(i8*, i8**) #1
|
|
|
|
attributes #0 = { nounwind readnone speculatable }
|
|
attributes #1 = { nounwind }
|
|
|
|
!llvm.module.flags = !{!0}
|
|
!llvm.dbg.cu = !{!1}
|
|
|
|
!0 = !{i32 2, !"Debug Info Version", i32 3}
|
|
!1 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !2, producer: "beards", isOptimized: true, runtimeVersion: 4, emissionKind: FullDebug)
|
|
!2 = !DIFile(filename: "bees.cpp", directory: "")
|
|
!3 = !DILocalVariable(name: "bees", scope: !4)
|
|
!4 = distinct !DISubprogram(name: "nope", scope: !1, file: !2, line: 1, spFlags: DISPFlagDefinition, unit: !1)
|
|
!5 = !DILocation(line: 0, scope: !4)
|
|
|
|
...
|
|
---
|
|
name: test
|
|
tracksRegLiveness: true
|
|
body: |
|
|
bb.0.entry:
|
|
successors: %bb.1(0x80000000)
|
|
liveins: $rdi
|
|
|
|
%2:gr64 = COPY killed $rdi
|
|
%3:gr32 = MOV32r0 implicit-def dead $eflags
|
|
%4:gr32 = MOV32ri 1234
|
|
%7:gr32 = COPY killed %3
|
|
|
|
bb.1.start.test1:
|
|
successors: %bb.2(0x04000000), %bb.1(0x7c000000)
|
|
|
|
; CHECK-LABEL: name: test
|
|
;
|
|
; We currently expect %1 and %0 to merge into %7
|
|
;
|
|
; CHECK: %[[REG1:[0-9]+]]:gr32 = MOV32rm
|
|
; CHECK-NEXT: %[[REG2:[0-9]+]]:gr32 = XOR32rr %[[REG1]]
|
|
; CHECK-NEXT: %[[REG3:[0-9]+]]:gr32 = ADD32rr %[[REG3]], %[[REG2]]
|
|
; CHECK-NEXT: DBG_VALUE $noreg
|
|
|
|
%0:gr32 = COPY killed %7
|
|
%8:gr32 = MOV32rm %2, 1, $noreg, 0, $noreg :: (load 4 from %ir.pin, align 1)
|
|
%5:gr32 = COPY killed %8
|
|
%5:gr32 = XOR32rr %5, %4, implicit-def dead $eflags
|
|
%1:gr32 = COPY killed %0
|
|
%1:gr32 = ADD32rr %1, killed %5, implicit-def dead $eflags
|
|
DBG_VALUE %0, $noreg, !3, !DIExpression(), debug-location !5
|
|
CMP32ri %1, 1000001, implicit-def $eflags
|
|
%7:gr32 = COPY %1
|
|
JCC_1 %bb.1, 2, implicit killed $eflags
|
|
JMP_1 %bb.2
|
|
|
|
bb.2.leave:
|
|
$eax = COPY killed %1
|
|
RET 0, killed $eax
|
|
|
|
...
|
|
---
|
|
name: test2
|
|
tracksRegLiveness: true
|
|
body: |
|
|
bb.0.entry:
|
|
successors: %bb.1(0x80000000)
|
|
liveins: $rdi
|
|
|
|
%2:gr64 = COPY killed $rdi
|
|
%3:gr32 = MOV32r0 implicit-def dead $eflags
|
|
%4:gr32 = MOV32ri 1234
|
|
%7:gr32 = COPY killed %3
|
|
|
|
bb.1.start.test2:
|
|
successors: %bb.2(0x04000000), %bb.1(0x7c000000)
|
|
|
|
; CHECK-LABEL: name: test2
|
|
;
|
|
; %0 should be merged into %7, but as %0 is live at this location the
|
|
; DBG_VALUE should be preserved and point at the operand of ADD32rr.
|
|
; RegisterCoalescer resolves %0 as CR_Erase: %0 is a redundant copy and
|
|
; can be erased.
|
|
;
|
|
; CHECK: %[[REG11:[0-9]+]]:gr32 = MOV32rm
|
|
; CHECK-NEXT: %[[REG12:[0-9]+]]:gr32 = XOR32rr %[[REG11]]
|
|
; CHECK-NEXT: DBG_VALUE %[[REG13:[0-9]+]]
|
|
; CHECK-NEXT: %[[REG13]]:gr32 = ADD32rr %[[REG13]], %[[REG12]]
|
|
|
|
%0:gr32 = COPY killed %7
|
|
%8:gr32 = MOV32rm %2, 1, $noreg, 0, $noreg :: (load 4 from %ir.pin, align 1)
|
|
%8:gr32 = XOR32rr %8, %4, implicit-def dead $eflags
|
|
DBG_VALUE %0, $noreg, !3, !DIExpression(), debug-location !5
|
|
%0:gr32 = ADD32rr %0, killed %8, implicit-def dead $eflags
|
|
CMP32ri %0, 1000001, implicit-def $eflags
|
|
%7:gr32 = COPY %0
|
|
JCC_1 %bb.1, 2, implicit killed $eflags
|
|
JMP_1 %bb.2
|
|
|
|
bb.2.leave:
|
|
$eax = COPY killed %7
|
|
RET 0, killed $eax
|
|
|
|
...
|
|
|