File: machine-licm-vs-wineh.mir

package info (click to toggle)
llvm-toolchain-19 1%3A19.1.7-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,998,520 kB
  • sloc: cpp: 6,951,680; ansic: 1,486,157; asm: 913,598; python: 232,024; f90: 80,126; objc: 75,281; lisp: 37,276; pascal: 16,990; sh: 10,009; ml: 5,058; perl: 4,724; awk: 3,523; makefile: 3,167; javascript: 2,504; xml: 892; fortran: 664; cs: 573
file content (141 lines) | stat: -rw-r--r-- 4,936 bytes parent folder | download | duplicates (6)
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
# RUN: llc -o - %s -mtriple=x86_64-pc-windows-msvc -run-pass=machinelicm | FileCheck %s
#
# This test checks that MachineLICM doesn't hoist loads out of funclets.
# Manually modified from the IR of the following C++ function by running
# llc -stop-after=machine-cp.
#
# void may_throw();
# void use(int);
#
# void test(int n, int arg)
# {
#    for (int i = 0 ; i < n ; i++)
#        try {
#            may_throw();
#        }
#        catch (...) {
#            // Two uses to get 'arg' allocated to a register
#            use(arg);
#            use(arg);
#        }
# }

--- |
  target triple = "x86_64-pc-windows-msvc"

  define void @test(i32 %n, i32 %arg) personality ptr @__CxxFrameHandler3 {
  entry:
    %cmp3 = icmp sgt i32 %n, 0
    br i1 %cmp3, label %for.body.preheader, label %for.cond.cleanup

  for.body.preheader:                               ; preds = %entry
    br label %for.body

  for.cond.cleanup:                                 ; preds = %for.inc, %entry
    ret void

  for.body:                                         ; preds = %for.body.preheader, %for.inc
    %lsr.iv = phi i32 [ %n, %for.body.preheader ], [ %lsr.iv.next, %for.inc ]
    invoke void @may_throw()
            to label %for.inc unwind label %catch.dispatch

  catch.dispatch:                                   ; preds = %for.body
    %0 = catchswitch within none [label %catch] unwind to caller

  catch:                                            ; preds = %catch.dispatch
    %1 = catchpad within %0 [ptr null, i32 64, ptr null]
    call void @use(i32 %arg) [ "funclet"(token %1) ]
    call void @use(i32 %arg) [ "funclet"(token %1) ]
    catchret from %1 to label %for.inc

  for.inc:                                          ; preds = %catch, %for.body
    %lsr.iv.next = add i32 %lsr.iv, -1
    %exitcond.not = icmp eq i32 %lsr.iv.next, 0
    br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
  }

  declare i32 @__CxxFrameHandler3(...)

  declare void @may_throw()

  declare void @use(i32)

...
---
name:            test
alignment:       16
tracksRegLiveness: true
hasEHCatchret:   true
hasEHScopes:     true
hasEHFunclets:   true
debugInstrRef:   true
tracksDebugUserValues: true
liveins:
  - { reg: '$ecx' }
  - { reg: '$edx' }
frameInfo:
  maxAlignment:    8
  hasCalls:        true
  hasOpaqueSPAdjustment: true
stack:
  - { id: 0, type: spill-slot, size: 4, alignment: 4 }
  - { id: 1, type: spill-slot, size: 4, alignment: 4 }
machineFunctionInfo: {}
body:             |
  bb.0.entry:
    successors: %bb.1, %bb.2
    liveins: $ecx, $edx

    MOV32mr %stack.1, 1, $noreg, 0, $noreg, $edx :: (store (s32) into %stack.1)
    TEST32rr renamable $ecx, renamable $ecx, implicit-def $eflags
    JCC_1 %bb.2, 14, implicit killed $eflags

  bb.1:
    liveins: $ecx

    JMP_1 %bb.3

  bb.2.for.cond.cleanup:
    RET 0

  bb.3.for.body:
    successors: %bb.5, %bb.4
    liveins: $ecx

    EH_LABEL <mcsymbol .Leh1>
    MOV32mr %stack.0, 1, $noreg, 0, $noreg, killed renamable $ecx :: (store (s32) into %stack.0)
    ADJCALLSTACKDOWN64 32, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
    CALL64pcrel32 @may_throw, csr_win64, implicit $rsp, implicit $ssp, implicit-def $rsp, implicit-def $ssp
    ADJCALLSTACKUP64 32, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
    EH_LABEL <mcsymbol .Leh2>
    JMP_1 %bb.5

  bb.4.catch (landing-pad, ehfunclet-entry):
    successors: %bb.5

    ADJCALLSTACKDOWN64 32, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
    renamable $esi = MOV32rm %stack.1, 1, $noreg, 0, $noreg :: (load (s32) from %stack.1)
    $ecx = COPY renamable $esi
    CALL64pcrel32 @use, csr_win64, implicit $rsp, implicit $ssp, implicit $ecx, implicit-def $rsp, implicit-def $ssp
    ADJCALLSTACKUP64 32, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
    ADJCALLSTACKDOWN64 32, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
    $ecx = COPY killed renamable $esi
    CALL64pcrel32 @use, csr_win64, implicit $rsp, implicit $ssp, implicit $ecx, implicit-def $rsp, implicit-def $ssp
    ADJCALLSTACKUP64 32, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
    CATCHRET %bb.5, %bb.0

  bb.5.for.inc:
    successors: %bb.2, %bb.3

    renamable $ecx = MOV32rm %stack.0, 1, $noreg, 0, $noreg :: (load (s32) from %stack.0)
    renamable $ecx = DEC32r killed renamable $ecx, implicit-def $eflags
    JCC_1 %bb.2, 4, implicit killed $eflags
    JMP_1 %bb.3

...
#
# CHECK: bb.4.catch
# CHECK: ADJCALLSTACKDOWN64
# CHECK-NEXT: renamable [[REG:\$[a-z0-9]+]] = MOV32rm %stack.1
# CHECK-NEXT: $ecx = COPY renamable [[REG]]
# CHECK-NEXT: CALL64pcrel32 @use