1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
|
# RUN: llc %s -o - -experimental-debug-variable-locations \
# RUN: -start-before=x86-flags-copy-lowering -stop-after=virtregrewriter \
# RUN: -mtriple x86_64-unknown-unknown \
# RUN: | FileCheck %s
#
# This test is for stack spill folding -- the INC32r near the end of the MIR
# below show be morphed into an INC32m by the register allocator, making it
# load-operate-store to %stack.0. We should track this fact in the substitution
# table, by adding a substitution to the memory-operand operand number.
#
# The INC32r is a tied-def instruction.
#
# NB: This test would more ideally start at phi-node-elimination, where
# register allocation begins, however for some reason the INC32r gets
# transformed into a different instruction if we do that. Start at the last
# optimisation pass before regalloc instead.
#
# CHECK: debugValueSubstitutions:
# CHECK-NEXT: - { srcinst: 1, srcop: 0, dstinst: 2, dstop: 1000000, subreg: 0 }
# CHECK-LABEL: bb.5:
# CHECK: INC32m %stack.0, {{.*}} debug-instr-number 2,
--- |
; ModuleID = 'reduced.ll'
source_filename = "reduced.ll"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
%"class.llvm::APInt" = type { i32, %union.anon }
%union.anon = type { i64 }
define void @_ZNK4llvm5APInt5magicEv() local_unnamed_addr align 2 !dbg !7 {
ret void
}
!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!3, !4, !5}
!llvm.ident = !{!6}
!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None)
!1 = !DIFile(filename: "test.c", directory: ".")
!2 = !{}
!3 = !{i32 7, !"Dwarf Version", i32 4}
!4 = !{i32 2, !"Debug Info Version", i32 3}
!5 = !{i32 1, !"wchar_size", i32 4}
!6 = !{!"clang"}
!7 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 3, type: !8, scopeLine: 3, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2)
!8 = !DISubroutineType(types: !9)
!9 = !{!10, !11, !11}
!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
!11 = !DIBasicType(name: "short", size: 16, encoding: DW_ATE_signed)
!12 = !DILocalVariable(name: "bar", arg: 1, scope: !7, file: !1, line: 3, type: !11)
!13 = !DILocation(line: 0, scope: !7)
!14 = !DILocalVariable(name: "baz", arg: 2, scope: !7, file: !1, line: 3, type: !11)
!15 = distinct !DILexicalBlock(scope: !7, file: !1, line: 8, column: 7)
...
---
name: _ZNK4llvm5APInt5magicEv
alignment: 16
tracksRegLiveness: true
registers:
- { id: 0, class: gr64 }
- { id: 1, class: gr32 }
- { id: 2, class: gr64 }
- { id: 3, class: gr32 }
- { id: 4, class: gr64 }
- { id: 5, class: gr32 }
- { id: 6, class: gr32 }
- { id: 7, class: gr32 }
- { id: 8, class: gr64 }
- { id: 9, class: gr32 }
- { id: 10, class: gr64 }
- { id: 11, class: gr32 }
- { id: 12, class: gr64 }
- { id: 13, class: gr32 }
- { id: 14, class: gr64 }
- { id: 15, class: gr32 }
- { id: 16, class: gr64 }
- { id: 17, class: gr64 }
- { id: 18, class: gr64 }
- { id: 19, class: gr32 }
- { id: 20, class: gr8 }
- { id: 21, class: gr32 }
- { id: 22, class: gr64 }
- { id: 23, class: gr64 }
- { id: 24, class: gr64 }
- { id: 25, class: gr64 }
- { id: 26, class: gr64 }
- { id: 27, class: gr32 }
- { id: 28, class: gr8 }
- { id: 29, class: gr64 }
- { id: 30, class: gr64 }
- { id: 31, class: gr64 }
- { id: 32, class: gr64 }
- { id: 33, class: gr64 }
- { id: 34, class: gr64 }
- { id: 35, class: gr64 }
- { id: 36, class: gr64 }
- { id: 37, class: gr64 }
- { id: 38, class: gr8 }
frameInfo:
maxAlignment: 1
hasCalls: true
machineFunctionInfo: {}
body: |
bb.0:
%15:gr32 = IMPLICIT_DEF
%14:gr64 = IMPLICIT_DEF
%17:gr64 = IMPLICIT_DEF
%18:gr64 = IMPLICIT_DEF
%19:gr32 = MOV32r0 implicit-def dead $eflags
%22:gr64 = IMPLICIT_DEF
%23:gr64 = IMPLICIT_DEF
%24:gr64 = IMPLICIT_DEF
%25:gr64 = IMPLICIT_DEF
%26:gr64 = IMPLICIT_DEF
%30:gr64 = IMPLICIT_DEF
%31:gr64 = IMPLICIT_DEF
%32:gr64 = IMPLICIT_DEF
%33:gr64 = IMPLICIT_DEF
%34:gr64 = IMPLICIT_DEF
%35:gr64 = IMPLICIT_DEF
%36:gr64 = IMPLICIT_DEF
%37:gr64 = IMPLICIT_DEF
%21:gr32 = IMPLICIT_DEF
bb.1:
%0:gr64 = PHI %14, %bb.0, %12, %bb.5
%1:gr32 = PHI %15, %bb.0, %11, %bb.5
%2:gr64 = PHI %14, %bb.0, %10, %bb.5
%3:gr32 = PHI %15, %bb.0, %9, %bb.5
%4:gr64 = PHI %14, %bb.0, %8, %bb.5
%5:gr32 = PHI %15, %bb.0, %7, %bb.5, debug-location !13
%6:gr32 = PHI %15, %bb.0, %13, %bb.5, debug-location !13
%16:gr64 = ADD64rr %4, %4, implicit-def dead $eflags, debug-location !13
MOV32mr %17, 1, $noreg, 0, $noreg, %5, debug-location !13 :: (store (s32) into `i32* undef`, align 8)
MOV64mr %18, 1, $noreg, 0, $noreg, killed %16, debug-location !13 :: (store (s64) into `i64* undef`)
%20:gr8 = COPY %19.sub_8bit
TEST8rr %20, %20, implicit-def $eflags, debug-location !13
JCC_1 %bb.3, 5, implicit $eflags, debug-location !13
JMP_1 %bb.2, debug-location !13
bb.2:
bb.3:
successors: %bb.4, %bb.5
%7:gr32 = PHI %5, %bb.1, %21, %bb.2, debug-location !13
MOV32mr %22, 1, $noreg, 0, $noreg, %7, debug-location !13 :: (store (s32) into `i32* undef`, align 8)
%8:gr64 = MOV64rm %23, 1, $noreg, 0, $noreg, debug-location !13 :: (load (s64) from `i64* undef`)
MOV32mr %24, 1, $noreg, 0, $noreg, %3, debug-location !13 :: (store (s32) into `i32* undef`, align 8)
MOV64mi32 %25, 1, $noreg, 0, $noreg, 0, debug-location !13 :: (store (s64) into `i64* undef`)
%28:gr8 = COPY %19.sub_8bit
TEST8rr %28, %28, implicit-def $eflags, debug-location !13
JCC_1 %bb.5, 5, implicit $eflags, debug-location !13
JMP_1 %bb.4, debug-location !13
bb.4:
%29:gr64 = ADD64rr %2, %2, implicit-def dead $eflags, debug-location !13
MOV64mr %30, 1, $noreg, 0, $noreg, killed %29, debug-location !13 :: (store (s64) into `i64* undef`)
bb.5:
%9:gr32 = MOV32rm %26, 1, $noreg, 0, $noreg, debug-location !13 :: (load (s32) from `i32* undef`, align 8)
%10:gr64 = MOV64rm %31, 1, $noreg, 0, $noreg, debug-location !13 :: (load (s64) from `i64* undef`)
%12:gr64 = ADD64rr %0, %0, implicit-def dead $eflags, debug-location !13
MOV32mr %32, 1, $noreg, 0, $noreg, %1, debug-location !13 :: (store (s32) into `i32* undef`, align 8)
MOV64mr %33, 1, $noreg, 0, $noreg, %12, debug-location !13 :: (store (s64) into `i64* undef`)
%11:gr32 = MOV32rm %34, 1, $noreg, 0, $noreg, debug-location !13 :: (load (s32) from `i32* undef`, align 8)
ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp, debug-location !13
$rdi = COPY %35, debug-location !13
$rsi = COPY %36, debug-location !13
CALL64r %37, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit $rsi, implicit-def $rsp, implicit-def $ssp, implicit-def $al, debug-location !13
ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp, debug-location !13
%13:gr32 = INC32r %6, implicit-def dead $eflags, debug-instr-number 1, debug-location !13
DBG_INSTR_REF 1, 0, !12, !DIExpression(), debug-location !13
JMP_1 %bb.1, debug-location !13
...
|