Home | History | Annotate | Download | only in X86
      1 # RUN: llc -run-pass x86-flags-copy-lowering -verify-machineinstrs -o - %s | FileCheck %s
      2 #
      3 # Lower various interesting copy patterns of EFLAGS without using LAHF/SAHF.
      4 
      5 --- |
      6   target triple = "x86_64-unknown-unknown"
      7   
      8   declare void @foo()
      9   
     10   define i32 @test_branch(i64 %a, i64 %b) {
     11   entry:
     12     call void @foo()
     13     ret i32 0
     14   }
     15 
     16   define i32 @test_branch_fallthrough(i64 %a, i64 %b) {
     17   entry:
     18     call void @foo()
     19     ret i32 0
     20   }
     21 
     22   define void @test_setcc(i64 %a, i64 %b) {
     23   entry:
     24     call void @foo()
     25     ret void
     26   }
     27 
     28   define void @test_cmov(i64 %a, i64 %b) {
     29   entry:
     30     call void @foo()
     31     ret void
     32   }
     33 
     34   define void @test_adc(i64 %a, i64 %b) {
     35   entry:
     36     call void @foo()
     37     ret void
     38   }
     39 
     40   define void @test_sbb(i64 %a, i64 %b) {
     41   entry:
     42     call void @foo()
     43     ret void
     44   }
     45 
     46   define void @test_adcx(i64 %a, i64 %b) {
     47   entry:
     48     call void @foo()
     49     ret void
     50   }
     51 
     52   define void @test_adox(i64 %a, i64 %b) {
     53   entry:
     54     call void @foo()
     55     ret void
     56   }
     57 
     58   define void @test_rcl(i64 %a, i64 %b) {
     59   entry:
     60     call void @foo()
     61     ret void
     62   }
     63 
     64   define void @test_rcr(i64 %a, i64 %b) {
     65   entry:
     66     call void @foo()
     67     ret void
     68   }
     69 
     70   define void @test_setb_c(i64 %a, i64 %b) {
     71   entry:
     72     call void @foo()
     73     ret void
     74   }
     75 
     76   define i64 @test_branch_with_livein_and_kill(i64 %a, i64 %b) {
     77   entry:
     78     call void @foo()
     79     ret i64 0
     80   }
     81 
     82   define i64 @test_branch_with_interleaved_livein_and_kill(i64 %a, i64 %b) {
     83   entry:
     84     call void @foo()
     85     ret i64 0
     86   }
     87 
     88   define i64 @test_mid_cycle_copies(i64 %a, i64 %b) {
     89   entry:
     90     call void @foo()
     91     ret i64 0
     92   }
     93 
     94   define i32 @test_existing_setcc(i64 %a, i64 %b) {
     95   entry:
     96     call void @foo()
     97     ret i32 0
     98   }
     99 
    100   define i32 @test_existing_setcc_memory(i64 %a, i64 %b) {
    101   entry:
    102     call void @foo()
    103     ret i32 0
    104   }
    105 ...
    106 ---
    107 name:            test_branch
    108 # CHECK-LABEL: name: test_branch
    109 liveins:         
    110   - { reg: '$rdi', virtual-reg: '%0' }
    111   - { reg: '$rsi', virtual-reg: '%1' }
    112 body:             |
    113   bb.0:
    114     successors: %bb.1, %bb.2, %bb.3
    115     liveins: $rdi, $rsi
    116   
    117     %0:gr64 = COPY $rdi
    118     %1:gr64 = COPY $rsi
    119     CMP64rr %0, %1, implicit-def $eflags
    120     %2:gr64 = COPY $eflags
    121   ; CHECK-NOT:  COPY{{( killed)?}} $eflags
    122   ; CHECK:      %[[A_REG:[^:]*]]:gr8 = SETAr implicit $eflags
    123   ; CHECK-NEXT: %[[B_REG:[^:]*]]:gr8 = SETBr implicit $eflags
    124   ; CHECK-NOT:  COPY{{( killed)?}} $eflags
    125 
    126     ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
    127     CALL64pcrel32 @foo, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax
    128     ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
    129 
    130     $eflags = COPY %2
    131     JA_1 %bb.1, implicit $eflags
    132     JB_1 %bb.2, implicit $eflags
    133     JMP_1 %bb.3
    134   ; CHECK-NOT: $eflags =
    135   ;
    136   ; CHECK:        TEST8rr %[[A_REG]], %[[A_REG]], implicit-def $eflags
    137   ; CHECK-NEXT:   JNE_1 %bb.1, implicit killed $eflags
    138   ; CHECK-SAME: {{$[[:space:]]}}
    139   ; CHECK-NEXT: bb.4:
    140   ; CHECK-NEXT:   successors: {{.*$}}
    141   ; CHECK-SAME: {{$[[:space:]]}}
    142   ; CHECK-NEXT:   TEST8rr %[[B_REG]], %[[B_REG]], implicit-def $eflags
    143   ; CHECK-NEXT:   JNE_1 %bb.2, implicit killed $eflags
    144   ; CHECK-NEXT:   JMP_1 %bb.3
    145   
    146   bb.1:
    147     %3:gr32 = MOV32ri64 42
    148     $eax = COPY %3
    149     RET 0, $eax
    150   
    151   bb.2:
    152     %4:gr32 = MOV32ri64 43
    153     $eax = COPY %4
    154     RET 0, $eax
    155   
    156   bb.3:
    157     %5:gr32 = MOV32r0 implicit-def dead $eflags
    158     $eax = COPY %5
    159     RET 0, $eax
    160 
    161 ...
    162 ---
    163 name:            test_branch_fallthrough
    164 # CHECK-LABEL: name: test_branch_fallthrough
    165 liveins:         
    166   - { reg: '$rdi', virtual-reg: '%0' }
    167   - { reg: '$rsi', virtual-reg: '%1' }
    168 body:             |
    169   bb.0:
    170     successors: %bb.1, %bb.2, %bb.3
    171     liveins: $rdi, $rsi
    172   
    173     %0:gr64 = COPY $rdi
    174     %1:gr64 = COPY $rsi
    175     CMP64rr %0, %1, implicit-def $eflags
    176     %2:gr64 = COPY $eflags
    177   ; CHECK-NOT:  COPY{{( killed)?}} $eflags
    178   ; CHECK:      %[[A_REG:[^:]*]]:gr8 = SETAr implicit $eflags
    179   ; CHECK-NEXT: %[[B_REG:[^:]*]]:gr8 = SETBr implicit $eflags
    180   ; CHECK-NOT:  COPY{{( killed)?}} $eflags
    181 
    182     ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
    183     CALL64pcrel32 @foo, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax
    184     ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
    185 
    186     $eflags = COPY %2
    187     JA_1 %bb.2, implicit $eflags
    188     JB_1 %bb.3, implicit $eflags
    189   ; CHECK-NOT: $eflags =
    190   ;
    191   ; CHECK:        TEST8rr %[[A_REG]], %[[A_REG]], implicit-def $eflags
    192   ; CHECK-NEXT:   JNE_1 %bb.2, implicit killed $eflags
    193   ; CHECK-SAME: {{$[[:space:]]}}
    194   ; CHECK-NEXT: bb.4:
    195   ; CHECK-NEXT:   successors: {{.*$}}
    196   ; CHECK-SAME: {{$[[:space:]]}}
    197   ; CHECK-NEXT:   TEST8rr %[[B_REG]], %[[B_REG]], implicit-def $eflags
    198   ; CHECK-NEXT:   JNE_1 %bb.3, implicit killed $eflags
    199   ; CHECK-SAME: {{$[[:space:]]}}
    200   ; CHECK-NEXT:   bb.1:
    201 
    202   bb.1:
    203     %5:gr32 = MOV32r0 implicit-def dead $eflags
    204     $eax = COPY %5
    205     RET 0, $eax
    206   
    207   bb.2:
    208     %3:gr32 = MOV32ri64 42
    209     $eax = COPY %3
    210     RET 0, $eax
    211   
    212   bb.3:
    213     %4:gr32 = MOV32ri64 43
    214     $eax = COPY %4
    215     RET 0, $eax
    216   
    217 ...
    218 ---
    219 name:            test_setcc
    220 # CHECK-LABEL: name: test_setcc
    221 liveins:         
    222   - { reg: '$rdi', virtual-reg: '%0' }
    223   - { reg: '$rsi', virtual-reg: '%1' }
    224 body:             |
    225   bb.0:
    226     liveins: $rdi, $rsi
    227   
    228     %0:gr64 = COPY $rdi
    229     %1:gr64 = COPY $rsi
    230     CMP64rr %0, %1, implicit-def $eflags
    231     %2:gr64 = COPY $eflags
    232   ; CHECK-NOT:  COPY{{( killed)?}} $eflags
    233   ; CHECK:      %[[A_REG:[^:]*]]:gr8 = SETAr implicit $eflags
    234   ; CHECK-NEXT: %[[B_REG:[^:]*]]:gr8 = SETBr implicit $eflags
    235   ; CHECK-NEXT: %[[E_REG:[^:]*]]:gr8 = SETEr implicit $eflags
    236   ; CHECK-NEXT: %[[NE_REG:[^:]*]]:gr8 = SETNEr implicit $eflags
    237   ; CHECK-NOT:  COPY{{( killed)?}} $eflags
    238 
    239     ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
    240     CALL64pcrel32 @foo, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax
    241     ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
    242 
    243     $eflags = COPY %2
    244     %3:gr8 = SETAr implicit $eflags
    245     %4:gr8 = SETBr implicit $eflags
    246     %5:gr8 = SETEr implicit $eflags
    247     SETNEm $rsp, 1, $noreg, -16, $noreg, implicit killed $eflags
    248     MOV8mr $rsp, 1, $noreg, -16, $noreg, killed %3
    249     MOV8mr $rsp, 1, $noreg, -16, $noreg, killed %4
    250     MOV8mr $rsp, 1, $noreg, -16, $noreg, killed %5
    251   ; CHECK-NOT:     $eflags =
    252   ; CHECK-NOT:             = SET{{.*}}
    253   ; CHECK:         MOV8mr {{.*}}, killed %[[A_REG]]
    254   ; CHECK-NEXT:    MOV8mr {{.*}}, killed %[[B_REG]]
    255   ; CHECK-NEXT:    MOV8mr {{.*}}, killed %[[E_REG]]
    256   ; CHECK-NOT:     MOV8mr {{.*}}, killed %[[NE_REG]]
    257 
    258     RET 0
    259 
    260 ...
    261 ---
    262 name:            test_cmov
    263 # CHECK-LABEL: name: test_cmov
    264 liveins:         
    265   - { reg: '$rdi', virtual-reg: '%0' }
    266   - { reg: '$rsi', virtual-reg: '%1' }
    267 body:             |
    268   bb.0:
    269     liveins: $rdi, $rsi
    270   
    271     %0:gr64 = COPY $rdi
    272     %1:gr64 = COPY $rsi
    273     CMP64rr %0, %1, implicit-def $eflags
    274     %2:gr64 = COPY $eflags
    275   ; CHECK-NOT:  COPY{{( killed)?}} $eflags
    276   ; CHECK:      %[[A_REG:[^:]*]]:gr8 = SETAr implicit $eflags
    277   ; CHECK-NEXT: %[[B_REG:[^:]*]]:gr8 = SETBr implicit $eflags
    278   ; CHECK-NEXT: %[[E_REG:[^:]*]]:gr8 = SETEr implicit $eflags
    279   ; CHECK-NOT:  COPY{{( killed)?}} $eflags
    280 
    281     ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
    282     CALL64pcrel32 @foo, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax
    283     ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
    284 
    285     $eflags = COPY %2
    286     %3:gr64 = CMOVA64rr %0, %1, implicit $eflags
    287     %4:gr64 = CMOVB64rr %0, %1, implicit $eflags
    288     %5:gr64 = CMOVE64rr %0, %1, implicit $eflags
    289     %6:gr64 = CMOVNE64rr %0, %1, implicit killed $eflags
    290   ; CHECK-NOT:     $eflags =
    291   ; CHECK:         TEST8rr %[[A_REG]], %[[A_REG]], implicit-def $eflags
    292   ; CHECK-NEXT:    %3:gr64 = CMOVNE64rr %0, %1, implicit killed $eflags
    293   ; CHECK-NEXT:    TEST8rr %[[B_REG]], %[[B_REG]], implicit-def $eflags
    294   ; CHECK-NEXT:    %4:gr64 = CMOVNE64rr %0, %1, implicit killed $eflags
    295   ; CHECK-NEXT:    TEST8rr %[[E_REG]], %[[E_REG]], implicit-def $eflags
    296   ; CHECK-NEXT:    %5:gr64 = CMOVNE64rr %0, %1, implicit killed $eflags
    297   ; CHECK-NEXT:    TEST8rr %[[E_REG]], %[[E_REG]], implicit-def $eflags
    298   ; CHECK-NEXT:    %6:gr64 = CMOVE64rr %0, %1, implicit killed $eflags
    299     MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %3
    300     MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %4
    301     MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %5
    302     MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %6
    303 
    304     RET 0
    305 
    306 ...
    307 ---
    308 name:            test_adc
    309 # CHECK-LABEL: name: test_adc
    310 liveins:         
    311   - { reg: '$rdi', virtual-reg: '%0' }
    312   - { reg: '$rsi', virtual-reg: '%1' }
    313 body:             |
    314   bb.0:
    315     liveins: $rdi, $rsi
    316   
    317     %0:gr64 = COPY $rdi
    318     %1:gr64 = COPY $rsi
    319     %2:gr64 = ADD64rr %0, %1, implicit-def $eflags
    320     %3:gr64 = COPY $eflags
    321   ; CHECK-NOT:  COPY{{( killed)?}} $eflags
    322   ; CHECK:      %[[CF_REG:[^:]*]]:gr8 = SETBr implicit $eflags
    323   ; CHECK-NOT:  COPY{{( killed)?}} $eflags
    324 
    325     ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
    326     CALL64pcrel32 @foo, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax
    327     ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
    328 
    329     $eflags = COPY %3
    330     %4:gr64 = ADC64ri32 %2:gr64, 42, implicit-def $eflags, implicit $eflags
    331     %5:gr64 = ADC64ri32 %4:gr64, 42, implicit-def $eflags, implicit $eflags
    332   ; CHECK-NOT:     $eflags =
    333   ; CHECK:         dead %{{[^:]*}}:gr8 = ADD8ri %[[CF_REG]], 255, implicit-def $eflags
    334   ; CHECK-NEXT:    %4:gr64 = ADC64ri32 %2, 42, implicit-def $eflags, implicit killed $eflags
    335   ; CHECK-NEXT:    %5:gr64 = ADC64ri32 %4, 42, implicit-def{{( dead)?}} $eflags, implicit{{( killed)?}} $eflags
    336     MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %5
    337 
    338     RET 0
    339 
    340 ...
    341 ---
    342 name:            test_sbb
    343 # CHECK-LABEL: name: test_sbb
    344 liveins:         
    345   - { reg: '$rdi', virtual-reg: '%0' }
    346   - { reg: '$rsi', virtual-reg: '%1' }
    347 body:             |
    348   bb.0:
    349     liveins: $rdi, $rsi
    350   
    351     %0:gr64 = COPY $rdi
    352     %1:gr64 = COPY $rsi
    353     %2:gr64 = SUB64rr %0, %1, implicit-def $eflags
    354     %3:gr64 = COPY killed $eflags
    355   ; CHECK-NOT:  COPY{{( killed)?}} $eflags
    356   ; CHECK:      %[[CF_REG:[^:]*]]:gr8 = SETBr implicit $eflags
    357   ; CHECK-NOT:  COPY{{( killed)?}} $eflags
    358 
    359     ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
    360     CALL64pcrel32 @foo, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax
    361     ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
    362 
    363     $eflags = COPY %3
    364     %4:gr64 = SBB64ri32 %2:gr64, 42, implicit-def $eflags, implicit killed $eflags
    365     %5:gr64 = SBB64ri32 %4:gr64, 42, implicit-def dead $eflags, implicit killed $eflags
    366   ; CHECK-NOT:     $eflags =
    367   ; CHECK:         dead %{{[^:]*}}:gr8 = ADD8ri %[[CF_REG]], 255, implicit-def $eflags
    368   ; CHECK-NEXT:    %4:gr64 = SBB64ri32 %2, 42, implicit-def $eflags, implicit killed $eflags
    369   ; CHECK-NEXT:    %5:gr64 = SBB64ri32 %4, 42, implicit-def{{( dead)?}} $eflags, implicit{{( killed)?}} $eflags
    370     MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %5
    371 
    372     RET 0
    373 
    374 ...
    375 ---
    376 name:            test_adcx
    377 # CHECK-LABEL: name: test_adcx
    378 liveins:         
    379   - { reg: '$rdi', virtual-reg: '%0' }
    380   - { reg: '$rsi', virtual-reg: '%1' }
    381 body:             |
    382   bb.0:
    383     liveins: $rdi, $rsi
    384   
    385     %0:gr64 = COPY $rdi
    386     %1:gr64 = COPY $rsi
    387     %2:gr64 = ADD64rr %0, %1, implicit-def $eflags
    388     %3:gr64 = COPY $eflags
    389   ; CHECK-NOT:    COPY{{( killed)?}} $eflags
    390   ; CHECK:        %[[E_REG:[^:]*]]:gr8 = SETEr implicit $eflags
    391   ; CHECK-NEXT:   %[[CF_REG:[^:]*]]:gr8 = SETBr implicit $eflags
    392   ; CHECK-NOT:    COPY{{( killed)?}} $eflags
    393 
    394     ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
    395     CALL64pcrel32 @foo, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax
    396     ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
    397 
    398     $eflags = COPY %3
    399     %4:gr64 = CMOVE64rr %0, %1, implicit $eflags
    400     %5:gr64 = MOV64ri32 42
    401     %6:gr64 = ADCX64rr %2, %5, implicit-def $eflags, implicit $eflags
    402   ; CHECK-NOT:     $eflags =
    403   ; CHECK:         TEST8rr %[[E_REG]], %[[E_REG]], implicit-def $eflags
    404   ; CHECK-NEXT:    %4:gr64 = CMOVNE64rr %0, %1, implicit killed $eflags
    405   ; CHECK-NEXT:    %5:gr64 = MOV64ri32 42
    406   ; CHECK-NEXT:    dead %{{[^:]*}}:gr8 = ADD8ri %[[CF_REG]], 255, implicit-def $eflags
    407   ; CHECK-NEXT:    %6:gr64 = ADCX64rr %2, %5, implicit-def{{( dead)?}} $eflags, implicit killed $eflags
    408     MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %4
    409     MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %6
    410 
    411     RET 0
    412 
    413 ...
    414 ---
    415 name:            test_adox
    416 # CHECK-LABEL: name: test_adox
    417 liveins:         
    418   - { reg: '$rdi', virtual-reg: '%0' }
    419   - { reg: '$rsi', virtual-reg: '%1' }
    420 body:             |
    421   bb.0:
    422     liveins: $rdi, $rsi
    423   
    424     %0:gr64 = COPY $rdi
    425     %1:gr64 = COPY $rsi
    426     %2:gr64 = ADD64rr %0, %1, implicit-def $eflags
    427     %3:gr64 = COPY $eflags
    428   ; CHECK-NOT:    COPY{{( killed)?}} $eflags
    429   ; CHECK:        %[[E_REG:[^:]*]]:gr8 = SETEr implicit $eflags
    430   ; CHECK-NEXT:   %[[OF_REG:[^:]*]]:gr8 = SETOr implicit $eflags
    431   ; CHECK-NOT:    COPY{{( killed)?}} $eflags
    432 
    433     ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
    434     CALL64pcrel32 @foo, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax
    435     ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
    436 
    437     $eflags = COPY %3
    438     %4:gr64 = CMOVE64rr %0, %1, implicit $eflags
    439     %5:gr64 = MOV64ri32 42
    440     %6:gr64 = ADOX64rr %2, %5, implicit-def $eflags, implicit $eflags
    441   ; CHECK-NOT:     $eflags =
    442   ; CHECK:         TEST8rr %[[E_REG]], %[[E_REG]], implicit-def $eflags
    443   ; CHECK-NEXT:    %4:gr64 = CMOVNE64rr %0, %1, implicit killed $eflags
    444   ; CHECK-NEXT:    %5:gr64 = MOV64ri32 42
    445   ; CHECK-NEXT:    dead %{{[^:]*}}:gr8 = ADD8ri %[[OF_REG]], 127, implicit-def $eflags
    446   ; CHECK-NEXT:    %6:gr64 = ADOX64rr %2, %5, implicit-def{{( dead)?}} $eflags, implicit killed $eflags
    447     MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %4
    448     MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %6
    449 
    450     RET 0
    451 
    452 ...
    453 ---
    454 name:            test_rcl
    455 # CHECK-LABEL: name: test_rcl
    456 liveins:         
    457   - { reg: '$rdi', virtual-reg: '%0' }
    458   - { reg: '$rsi', virtual-reg: '%1' }
    459 body:             |
    460   bb.0:
    461     liveins: $rdi, $rsi
    462   
    463     %0:gr64 = COPY $rdi
    464     %1:gr64 = COPY $rsi
    465     %2:gr64 = ADD64rr %0, %1, implicit-def $eflags
    466     %3:gr64 = COPY $eflags
    467   ; CHECK-NOT:  COPY{{( killed)?}} $eflags
    468   ; CHECK:      %[[CF_REG:[^:]*]]:gr8 = SETBr implicit $eflags
    469   ; CHECK-NOT:  COPY{{( killed)?}} $eflags
    470 
    471     ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
    472     CALL64pcrel32 @foo, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax
    473     ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
    474 
    475     $eflags = COPY %3
    476     %4:gr64 = RCL64r1 %2:gr64, implicit-def $eflags, implicit $eflags
    477     %5:gr64 = RCL64r1 %4:gr64, implicit-def $eflags, implicit $eflags
    478   ; CHECK-NOT:     $eflags =
    479   ; CHECK:         dead %{{[^:]*}}:gr8 = ADD8ri %[[CF_REG]], 255, implicit-def $eflags
    480   ; CHECK-NEXT:    %4:gr64 = RCL64r1 %2, implicit-def $eflags, implicit killed $eflags
    481   ; CHECK-NEXT:    %5:gr64 = RCL64r1 %4, implicit-def{{( dead)?}} $eflags, implicit{{( killed)?}} $eflags
    482     MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %5
    483 
    484     RET 0
    485 
    486 ...
    487 ---
    488 name:            test_rcr
    489 # CHECK-LABEL: name: test_rcr
    490 liveins:         
    491   - { reg: '$rdi', virtual-reg: '%0' }
    492   - { reg: '$rsi', virtual-reg: '%1' }
    493 body:             |
    494   bb.0:
    495     liveins: $rdi, $rsi
    496   
    497     %0:gr64 = COPY $rdi
    498     %1:gr64 = COPY $rsi
    499     %2:gr64 = ADD64rr %0, %1, implicit-def $eflags
    500     %3:gr64 = COPY $eflags
    501   ; CHECK-NOT:  COPY{{( killed)?}} $eflags
    502   ; CHECK:      %[[CF_REG:[^:]*]]:gr8 = SETBr implicit $eflags
    503   ; CHECK-NOT:  COPY{{( killed)?}} $eflags
    504 
    505     ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
    506     CALL64pcrel32 @foo, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax
    507     ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
    508 
    509     $eflags = COPY %3
    510     %4:gr64 = RCR64r1 %2:gr64, implicit-def $eflags, implicit $eflags
    511     %5:gr64 = RCR64r1 %4:gr64, implicit-def $eflags, implicit $eflags
    512   ; CHECK-NOT:     $eflags =
    513   ; CHECK:         dead %{{[^:]*}}:gr8 = ADD8ri %[[CF_REG]], 255, implicit-def $eflags
    514   ; CHECK-NEXT:    %4:gr64 = RCR64r1 %2, implicit-def $eflags, implicit killed $eflags
    515   ; CHECK-NEXT:    %5:gr64 = RCR64r1 %4, implicit-def{{( dead)?}} $eflags, implicit{{( killed)?}} $eflags
    516     MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %5
    517 
    518     RET 0
    519 
    520 ...
    521 ---
    522 name:            test_setb_c
    523 # CHECK-LABEL: name: test_setb_c
    524 liveins:
    525   - { reg: '$rdi', virtual-reg: '%0' }
    526   - { reg: '$rsi', virtual-reg: '%1' }
    527 body:             |
    528   bb.0:
    529     liveins: $rdi, $rsi
    530 
    531     %0:gr64 = COPY $rdi
    532     %1:gr64 = COPY $rsi
    533     %2:gr64 = ADD64rr %0, %1, implicit-def $eflags
    534     %3:gr64 = COPY $eflags
    535   ; CHECK-NOT:  COPY{{( killed)?}} $eflags
    536   ; CHECK:      %[[CF_REG:[^:]*]]:gr8 = SETBr implicit $eflags
    537   ; CHECK-NOT:  COPY{{( killed)?}} $eflags
    538 
    539     ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
    540     CALL64pcrel32 @foo, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax
    541     ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
    542 
    543     $eflags = COPY %3
    544     %4:gr8 = SETB_C8r implicit-def $eflags, implicit $eflags
    545     MOV8mr $rsp, 1, $noreg, -16, $noreg, killed %4
    546   ; CHECK-NOT:     $eflags =
    547   ; CHECK:         %[[ZERO:[^:]*]]:gr32 = MOV32r0 implicit-def $eflags
    548   ; CHECK-NEXT:    %[[ZERO_SUBREG:[^:]*]]:gr8 = COPY %[[ZERO]].sub_8bit
    549   ; CHECK-NEXT:    %[[REPLACEMENT:[^:]*]]:gr8 = SUB8rr %[[ZERO_SUBREG]], %[[CF_REG]]
    550   ; CHECK-NEXT:    MOV8mr $rsp, 1, $noreg, -16, $noreg, killed %[[REPLACEMENT]]
    551 
    552     $eflags = COPY %3
    553     %5:gr16 = SETB_C16r implicit-def $eflags, implicit $eflags
    554     MOV16mr $rsp, 1, $noreg, -16, $noreg, killed %5
    555   ; CHECK-NOT:     $eflags =
    556   ; CHECK:         %[[CF_EXT:[^:]*]]:gr32 = MOVZX32rr8 %[[CF_REG]]
    557   ; CHECK-NEXT:    %[[CF_TRUNC:[^:]*]]:gr16 = COPY %[[CF_EXT]].sub_16bit
    558   ; CHECK-NEXT:    %[[ZERO:[^:]*]]:gr32 = MOV32r0 implicit-def $eflags
    559   ; CHECK-NEXT:    %[[ZERO_SUBREG:[^:]*]]:gr16 = COPY %[[ZERO]].sub_16bit
    560   ; CHECK-NEXT:    %[[REPLACEMENT:[^:]*]]:gr16 = SUB16rr %[[ZERO_SUBREG]], %[[CF_TRUNC]]
    561   ; CHECK-NEXT:    MOV16mr $rsp, 1, $noreg, -16, $noreg, killed %[[REPLACEMENT]]
    562 
    563     $eflags = COPY %3
    564     %6:gr32 = SETB_C32r implicit-def $eflags, implicit $eflags
    565     MOV32mr $rsp, 1, $noreg, -16, $noreg, killed %6
    566   ; CHECK-NOT:     $eflags =
    567   ; CHECK:         %[[CF_EXT:[^:]*]]:gr32 = MOVZX32rr8 %[[CF_REG]]
    568   ; CHECK-NEXT:    %[[ZERO:[^:]*]]:gr32 = MOV32r0 implicit-def $eflags
    569   ; CHECK-NEXT:    %[[REPLACEMENT:[^:]*]]:gr32 = SUB32rr %[[ZERO]], %[[CF_EXT]]
    570   ; CHECK-NEXT:    MOV32mr $rsp, 1, $noreg, -16, $noreg, killed %[[REPLACEMENT]]
    571 
    572     $eflags = COPY %3
    573     %7:gr64 = SETB_C64r implicit-def $eflags, implicit $eflags
    574     MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %7
    575   ; CHECK-NOT:     $eflags =
    576   ; CHECK:         %[[CF_EXT1:[^:]*]]:gr32 = MOVZX32rr8 %[[CF_REG]]
    577   ; CHECK-NEXT:    %[[CF_EXT2:[^:]*]]:gr64 = SUBREG_TO_REG 0, %[[CF_EXT1]], %subreg.sub_32bit
    578   ; CHECK-NEXT:    %[[ZERO:[^:]*]]:gr32 = MOV32r0 implicit-def $eflags
    579   ; CHECK-NEXT:    %[[ZERO_EXT:[^:]*]]:gr64 = SUBREG_TO_REG 0, %[[ZERO]], %subreg.sub_32bit
    580   ; CHECK-NEXT:    %[[REPLACEMENT:[^:]*]]:gr64 = SUB64rr %[[ZERO_EXT]], %[[CF_EXT2]]
    581   ; CHECK-NEXT:    MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %[[REPLACEMENT]]
    582 
    583     RET 0
    584 
    585 ...
    586 ---
    587 name:            test_branch_with_livein_and_kill
    588 # CHECK-LABEL: name: test_branch_with_livein_and_kill
    589 liveins:
    590   - { reg: '$rdi', virtual-reg: '%0' }
    591   - { reg: '$rsi', virtual-reg: '%1' }
    592 body:             |
    593   bb.0:
    594     successors: %bb.1, %bb.2, %bb.3
    595     liveins: $rdi, $rsi
    596 
    597     %0:gr64 = COPY $rdi
    598     %1:gr64 = COPY $rsi
    599     CMP64rr %0, %1, implicit-def $eflags
    600     %2:gr64 = COPY $eflags
    601   ; CHECK-NOT:  COPY{{( killed)?}} $eflags
    602   ; CHECK:      %[[S_REG:[^:]*]]:gr8 = SETSr implicit $eflags
    603   ; CHECK-NEXT: %[[NE_REG:[^:]*]]:gr8 = SETNEr implicit $eflags
    604   ; CHECK-NEXT: %[[A_REG:[^:]*]]:gr8 = SETAr implicit $eflags
    605   ; CHECK-NEXT: %[[B_REG:[^:]*]]:gr8 = SETBr implicit $eflags
    606   ; CHECK-NOT:  COPY{{( killed)?}} $eflags
    607 
    608     ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
    609     CALL64pcrel32 @foo, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax
    610     ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
    611 
    612     $eflags = COPY %2
    613     JA_1 %bb.1, implicit $eflags
    614     JB_1 %bb.2, implicit $eflags
    615     JMP_1 %bb.3
    616   ; CHECK-NOT: $eflags =
    617   ;
    618   ; CHECK:        TEST8rr %[[A_REG]], %[[A_REG]], implicit-def $eflags
    619   ; CHECK-NEXT:   JNE_1 %bb.1, implicit killed $eflags
    620   ; CHECK-SAME: {{$[[:space:]]}}
    621   ; CHECK-NEXT: bb.4:
    622   ; CHECK-NEXT:   successors: {{.*$}}
    623   ; CHECK-SAME: {{$[[:space:]]}}
    624   ; CHECK-NEXT:   TEST8rr %[[B_REG]], %[[B_REG]], implicit-def $eflags
    625   ; CHECK-NEXT:   JNE_1 %bb.2, implicit killed $eflags
    626   ; CHECK-NEXT:   JMP_1 %bb.3
    627 
    628   bb.1:
    629     liveins: $eflags
    630 
    631     %3:gr64 = CMOVE64rr %0, %1, implicit killed $eflags
    632   ; CHECK-NOT:     $eflags =
    633   ; CHECK:         TEST8rr %[[NE_REG]], %[[NE_REG]], implicit-def $eflags
    634   ; CHECK-NEXT:    %3:gr64 = CMOVE64rr %0, %1, implicit killed $eflags
    635     $rax = COPY %3
    636     RET 0, $rax
    637 
    638   bb.2:
    639     liveins: $eflags
    640 
    641     %4:gr64 = CMOVNE64rr %0, %1, implicit killed $eflags
    642   ; CHECK-NOT:     $eflags =
    643   ; CHECK:         TEST8rr %[[NE_REG]], %[[NE_REG]], implicit-def $eflags
    644   ; CHECK-NEXT:    %4:gr64 = CMOVNE64rr %0, %1, implicit killed $eflags
    645     $rax = COPY %4
    646     RET 0, $rax
    647 
    648   bb.3:
    649     liveins: $eflags
    650 
    651     %5:gr64 = CMOVS64rr %0, %1, implicit killed $eflags
    652   ; CHECK-NOT:     $eflags =
    653   ; CHECK:         TEST8rr %[[S_REG]], %[[S_REG]], implicit-def $eflags
    654   ; CHECK-NEXT:    %5:gr64 = CMOVNE64rr %0, %1, implicit killed $eflags
    655     $rax = COPY %5
    656     RET 0, $rax
    657 
    658 ...
    659 ---
    660 name:            test_branch_with_interleaved_livein_and_kill
    661 # CHECK-LABEL: name: test_branch_with_interleaved_livein_and_kill
    662 liveins:
    663   - { reg: '$rdi', virtual-reg: '%0' }
    664   - { reg: '$rsi', virtual-reg: '%1' }
    665 body:             |
    666   bb.0:
    667     successors: %bb.1, %bb.2, %bb.5
    668     liveins: $rdi, $rsi
    669 
    670     %0:gr64 = COPY $rdi
    671     %1:gr64 = COPY $rsi
    672     CMP64rr %0, %1, implicit-def $eflags
    673     %2:gr64 = COPY $eflags
    674   ; CHECK-NOT:  COPY{{( killed)?}} $eflags
    675   ; CHECK:      %[[S_REG:[^:]*]]:gr8 = SETSr implicit $eflags
    676   ; CHECK-NEXT: %[[P_REG:[^:]*]]:gr8 = SETPr implicit $eflags
    677   ; CHECK-NEXT: %[[NE_REG:[^:]*]]:gr8 = SETNEr implicit $eflags
    678   ; CHECK-NEXT: %[[A_REG:[^:]*]]:gr8 = SETAr implicit $eflags
    679   ; CHECK-NEXT: %[[B_REG:[^:]*]]:gr8 = SETBr implicit $eflags
    680   ; CHECK-NEXT: %[[O_REG:[^:]*]]:gr8 = SETOr implicit $eflags
    681   ; CHECK-NOT:  COPY{{( killed)?}} $eflags
    682 
    683     ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
    684     CALL64pcrel32 @foo, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax
    685     ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
    686 
    687     $eflags = COPY %2
    688     JA_1 %bb.1, implicit $eflags
    689     JB_1 %bb.2, implicit $eflags
    690     JMP_1 %bb.5
    691   ; CHECK-NOT: $eflags =
    692   ;
    693   ; CHECK:        TEST8rr %[[A_REG]], %[[A_REG]], implicit-def $eflags
    694   ; CHECK-NEXT:   JNE_1 %bb.1, implicit killed $eflags
    695   ; CHECK-SAME: {{$[[:space:]]}}
    696   ; CHECK-NEXT: bb.6:
    697   ; CHECK-NEXT:   successors: {{.*$}}
    698   ; CHECK-SAME: {{$[[:space:]]}}
    699   ; CHECK-NEXT:   TEST8rr %[[B_REG]], %[[B_REG]], implicit-def $eflags
    700   ; CHECK-NEXT:   JNE_1 %bb.2, implicit killed $eflags
    701   ; CHECK-NEXT:   JMP_1 %bb.5
    702 
    703   bb.1:
    704     liveins: $eflags
    705 
    706     %3:gr64 = CMOVE64rr %0, %1, implicit killed $eflags
    707   ; CHECK-NOT:     $eflags =
    708   ; CHECK:         TEST8rr %[[NE_REG]], %[[NE_REG]], implicit-def $eflags
    709   ; CHECK-NEXT:    %3:gr64 = CMOVE64rr %0, %1, implicit killed $eflags
    710     $rax = COPY %3
    711     RET 0, $rax
    712 
    713   bb.2:
    714     ; The goal is to have another batch of successors discovered in a block
    715     ; between two successors which kill $eflags. This ensures that neither of
    716     ; the surrounding kills impact recursing through this block.
    717     successors: %bb.3, %bb.4
    718     liveins: $eflags
    719 
    720     JO_1 %bb.3, implicit $eflags
    721     JMP_1 %bb.4
    722   ; CHECK-NOT: $eflags =
    723   ;
    724   ; CHECK:        TEST8rr %[[O_REG]], %[[O_REG]], implicit-def $eflags
    725   ; CHECK-NEXT:   JNE_1 %bb.3, implicit killed $eflags
    726   ; CHECK-NEXT:   JMP_1 %bb.4
    727 
    728   bb.3:
    729     liveins: $eflags
    730 
    731     %4:gr64 = CMOVNE64rr %0, %1, implicit $eflags
    732   ; CHECK-NOT:     $eflags =
    733   ; CHECK:         TEST8rr %[[NE_REG]], %[[NE_REG]], implicit-def $eflags
    734   ; CHECK-NEXT:    %4:gr64 = CMOVNE64rr %0, %1, implicit killed $eflags
    735     $rax = COPY %4
    736     RET 0, $rax
    737 
    738   bb.4:
    739     liveins: $eflags
    740 
    741     %5:gr64 = CMOVP64rr %0, %1, implicit $eflags
    742   ; CHECK-NOT:     $eflags =
    743   ; CHECK:         TEST8rr %[[P_REG]], %[[P_REG]], implicit-def $eflags
    744   ; CHECK-NEXT:    %5:gr64 = CMOVNE64rr %0, %1, implicit killed $eflags
    745     $rax = COPY %5
    746     RET 0, $rax
    747 
    748   bb.5:
    749     liveins: $eflags
    750 
    751     %6:gr64 = CMOVS64rr %0, %1, implicit killed $eflags
    752   ; CHECK-NOT:     $eflags =
    753   ; CHECK:         TEST8rr %[[S_REG]], %[[S_REG]], implicit-def $eflags
    754   ; CHECK-NEXT:    %6:gr64 = CMOVNE64rr %0, %1, implicit killed $eflags
    755     $rax = COPY %6
    756     RET 0, $rax
    757 
    758 ...
    759 ---
    760 # This test case is designed to exercise a particularly challenging situation:
    761 # when the flags are copied and restored *inside* of a complex and cyclic CFG
    762 # all of which have live-in flags. To correctly handle this case we have to walk
    763 # up the dominator tree and locate a viable reaching definition location,
    764 # checking for clobbers along any path. The CFG for this function looks like the
    765 # following diagram, control flowing out the bottom of blocks and in the top:
    766 #
    767 #  bb.0
    768 #   | __________________
    769 #   |/                  \
    770 #  bb.1                  |
    771 #   |\_________          |
    772 #   | __       \ ____    |
    773 #   |/  \      |/    \   |
    774 #  bb.2  |    bb.4    |  |
    775 #   |\__/     / \     |  |
    776 #   |        /   \    |  |
    777 #  bb.3    bb.5  bb.6 |  |
    778 #   |        \   /    |  |
    779 #   |         \ /     |  |
    780 #   |         bb.7    |  |
    781 #   | ________/ \____/   |
    782 #   |/                   |
    783 #  bb.8                  |
    784 #   |\__________________/
    785 #   |
    786 #  bb.9
    787 #
    788 # We set EFLAGS in bb.0, clobber them in bb.3, and copy them in bb.2 and bb.6.
    789 # Because of the cycles this requires hoisting the `SETcc` instructions to
    790 # capture the flags for the bb.6 copy to bb.1 and using them for the copy in
    791 # `bb.2` as well despite the clobber in `bb.3`. The clobber in `bb.3` also
    792 # prevents hoisting the `SETcc`s up to `bb.0`.
    793 #
    794 # Throughout the test we use branch instructions that are totally bogus (as the
    795 # flags are obviously not changing!) but this is just to allow us to send
    796 # a small but complex CFG structure through the backend and force it to choose
    797 # plausible lowering decisions based on the core CFG presented, regardless of
    798 # the futility of the actual branches.
    799 name:            test_mid_cycle_copies
    800 # CHECK-LABEL: name: test_mid_cycle_copies
    801 liveins:
    802   - { reg: '$rdi', virtual-reg: '%0' }
    803   - { reg: '$rsi', virtual-reg: '%1' }
    804 body:             |
    805   bb.0:
    806     successors: %bb.1
    807     liveins: $rdi, $rsi
    808 
    809     %0:gr64 = COPY $rdi
    810     %1:gr64 = COPY $rsi
    811     CMP64rr %0, %1, implicit-def $eflags
    812   ; CHECK:      bb.0:
    813   ; CHECK-NOT:    COPY{{( killed)?}} $eflags
    814   ; CHECK:        CMP64rr %0, %1, implicit-def $eflags
    815   ; CHECK-NOT:    COPY{{( killed)?}} $eflags
    816     JMP_1 %bb.1
    817 
    818   bb.1:
    819     successors: %bb.2, %bb.4
    820     liveins: $eflags
    821 
    822     ; Outer loop header, target for one set of hoisting.
    823     JE_1 %bb.2, implicit $eflags
    824     JMP_1 %bb.4
    825   ; CHECK:      bb.1:
    826   ; CHECK-NOT:    COPY{{( killed)?}} $eflags
    827   ; CHECK:        %[[A_REG:[^:]*]]:gr8 = SETAr implicit $eflags
    828   ; CHECK-NEXT:   %[[E_REG:[^:]*]]:gr8 = SETEr implicit $eflags
    829   ; CHECK-NEXT:   %[[B_REG:[^:]*]]:gr8 = SETBr implicit $eflags
    830   ; CHECK-NOT:    COPY{{( killed)?}} $eflags
    831 
    832   bb.2:
    833     successors: %bb.2, %bb.3
    834     liveins: $eflags
    835 
    836     ; Inner loop with a local copy. We should eliminate this but can't hoist.
    837     %2:gr64 = COPY $eflags
    838     $eflags = COPY %2
    839     JE_1 %bb.2, implicit $eflags
    840     JMP_1 %bb.3
    841   ; CHECK:      bb.2:
    842   ; CHECK-NOT:    COPY{{( killed)?}} $eflags
    843   ; CHECK:        TEST8rr %[[E_REG]], %[[E_REG]], implicit-def $eflags
    844   ; CHECK-NEXT:   JNE_1 %bb.2, implicit killed $eflags
    845   ; CHECK-NOT:    COPY{{( killed)?}} $eflags
    846 
    847   bb.3:
    848     successors: %bb.8
    849     liveins: $eflags
    850 
    851     ; Use and then clobber $eflags. Then hop to the outer loop latch.
    852     %3:gr64 = ADC64ri32 %0, 42, implicit-def dead $eflags, implicit $eflags
    853   ; CHECK:      bb.3:
    854   ; CHECK-NOT:    COPY{{( killed)?}} $eflags
    855   ; CHECK:        dead %{{[^:]*}}:gr8 = ADD8ri %[[B_REG]], 255, implicit-def $eflags
    856   ; CHECK-NEXT:   %3:gr64 = ADC64ri32 %0, 42, implicit-def{{( dead)?}} $eflags, implicit{{( killed)?}} $eflags
    857   ; CHECK-NOT:    COPY{{( killed)?}} $eflags
    858     MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %3
    859     JMP_1 %bb.8
    860 
    861   bb.4:
    862     successors: %bb.5, %bb.6
    863     liveins: $eflags
    864 
    865     ; Another inner loop, this one with a diamond.
    866     JE_1 %bb.5, implicit $eflags
    867     JMP_1 %bb.6
    868   ; CHECK:      bb.4:
    869   ; CHECK-NOT:    COPY{{( killed)?}} $eflags
    870   ; CHECK:        TEST8rr %[[E_REG]], %[[E_REG]], implicit-def $eflags
    871   ; CHECK-NEXT:   JNE_1 %bb.5, implicit killed $eflags
    872   ; CHECK-NOT:    COPY{{( killed)?}} $eflags
    873 
    874   bb.5:
    875     successors: %bb.7
    876     liveins: $eflags
    877 
    878     ; Just use $eflags on this side of the diamond.
    879     %4:gr64 = CMOVA64rr %0, %1, implicit $eflags
    880   ; CHECK:      bb.5:
    881   ; CHECK-NOT:    COPY{{( killed)?}} $eflags
    882   ; CHECK:         TEST8rr %[[A_REG]], %[[A_REG]], implicit-def $eflags
    883   ; CHECK-NEXT:    %4:gr64 = CMOVNE64rr %0, %1, implicit killed $eflags
    884   ; CHECK-NOT:    COPY{{( killed)?}} $eflags
    885     MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %4
    886     JMP_1 %bb.7
    887 
    888   bb.6:
    889     successors: %bb.7
    890     liveins: $eflags
    891 
    892     ; Use, copy, and then use $eflags again.
    893     %5:gr64 = CMOVA64rr %0, %1, implicit $eflags
    894   ; CHECK:      bb.6:
    895   ; CHECK-NOT:    COPY{{( killed)?}} $eflags
    896   ; CHECK:        TEST8rr %[[A_REG]], %[[A_REG]], implicit-def $eflags
    897   ; CHECK-NEXT:   %5:gr64 = CMOVNE64rr %0, %1, implicit killed $eflags
    898   ; CHECK-NOT:    COPY{{( killed)?}} $eflags
    899     MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %5
    900 
    901     %6:gr64 = COPY $eflags
    902     $eflags = COPY %6:gr64
    903 
    904     %7:gr64 = CMOVA64rr %0, %1, implicit $eflags
    905   ; CHECK-NOT:    COPY{{( killed)?}} $eflags
    906   ; CHECK:        TEST8rr %[[A_REG]], %[[A_REG]], implicit-def $eflags
    907   ; CHECK-NEXT:   %7:gr64 = CMOVNE64rr %0, %1, implicit killed $eflags
    908   ; CHECK-NOT:    COPY{{( killed)?}} $eflags
    909     MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %7
    910     JMP_1 %bb.7
    911 
    912   bb.7:
    913     successors: %bb.4, %bb.8
    914     liveins: $eflags
    915 
    916     ; Inner loop latch.
    917     JE_1 %bb.4, implicit $eflags
    918     JMP_1 %bb.8
    919   ; CHECK:      bb.7:
    920   ; CHECK-NOT:    COPY{{( killed)?}} $eflags
    921   ; CHECK:        TEST8rr %[[E_REG]], %[[E_REG]], implicit-def $eflags
    922   ; CHECK-NEXT:   JNE_1 %bb.4, implicit killed $eflags
    923   ; CHECK-NOT:    COPY{{( killed)?}} $eflags
    924 
    925   bb.8:
    926     successors: %bb.1, %bb.9
    927 
    928     ; Outer loop latch. Note that we cannot have EFLAGS live-in here as that
    929     ; immediately require PHIs.
    930     CMP64rr %0, %1, implicit-def $eflags
    931     JE_1 %bb.1, implicit $eflags
    932     JMP_1 %bb.9
    933   ; CHECK:      bb.8:
    934   ; CHECK-NOT:    COPY{{( killed)?}} $eflags
    935   ; CHECK:        CMP64rr %0, %1, implicit-def $eflags
    936   ; CHECK-NEXT:   JE_1 %bb.1, implicit $eflags
    937   ; CHECK-NOT:    COPY{{( killed)?}} $eflags
    938 
    939   bb.9:
    940     liveins: $eflags
    941 
    942     ; And we're done.
    943     %8:gr64 = CMOVE64rr %0, %1, implicit killed $eflags
    944     $rax = COPY %8
    945     RET 0, $rax
    946   ; CHECK:      bb.9:
    947   ; CHECK-NOT:     $eflags
    948   ; CHECK:         %8:gr64 = CMOVE64rr %0, %1, implicit killed $eflags
    949 
    950 ...
    951 ---
    952 name:            test_existing_setcc
    953 # CHECK-LABEL: name: test_existing_setcc
    954 liveins:
    955   - { reg: '$rdi', virtual-reg: '%0' }
    956   - { reg: '$rsi', virtual-reg: '%1' }
    957 body:             |
    958   bb.0:
    959     successors: %bb.1, %bb.2, %bb.3
    960     liveins: $rdi, $rsi
    961 
    962     %0:gr64 = COPY $rdi
    963     %1:gr64 = COPY $rsi
    964     CMP64rr %0, %1, implicit-def $eflags
    965     %2:gr8 = SETAr implicit $eflags
    966     %3:gr8 = SETAEr implicit $eflags
    967     %4:gr64 = COPY $eflags
    968   ; CHECK:      CMP64rr %0, %1, implicit-def $eflags
    969   ; CHECK-NEXT: %[[A_REG:[^:]*]]:gr8 = SETAr implicit $eflags
    970   ; CHECK-NEXT: %[[AE_REG:[^:]*]]:gr8 = SETAEr implicit $eflags
    971   ; CHECK-NOT:  COPY{{( killed)?}} $eflags
    972 
    973     ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
    974     CALL64pcrel32 @foo, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax
    975     ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
    976 
    977     $eflags = COPY %4
    978     JA_1 %bb.1, implicit $eflags
    979     JB_1 %bb.2, implicit $eflags
    980     JMP_1 %bb.3
    981   ; CHECK-NOT: $eflags =
    982   ;
    983   ; CHECK:        TEST8rr %[[A_REG]], %[[A_REG]], implicit-def $eflags
    984   ; CHECK-NEXT:   JNE_1 %bb.1, implicit killed $eflags
    985   ; CHECK-SAME: {{$[[:space:]]}}
    986   ; CHECK-NEXT: bb.4:
    987   ; CHECK-NEXT:   successors: {{.*$}}
    988   ; CHECK-SAME: {{$[[:space:]]}}
    989   ; CHECK-NEXT:   TEST8rr %[[AE_REG]], %[[AE_REG]], implicit-def $eflags
    990   ; CHECK-NEXT:   JE_1 %bb.2, implicit killed $eflags
    991   ; CHECK-NEXT:   JMP_1 %bb.3
    992 
    993   bb.1:
    994     %5:gr32 = MOV32ri64 42
    995     $eax = COPY %5
    996     RET 0, $eax
    997 
    998   bb.2:
    999     %6:gr32 = MOV32ri64 43
   1000     $eax = COPY %6
   1001     RET 0, $eax
   1002 
   1003   bb.3:
   1004     %7:gr32 = MOV32r0 implicit-def dead $eflags
   1005     $eax = COPY %7
   1006     RET 0, $eax
   1007 
   1008 ...
   1009 ---
   1010 name:            test_existing_setcc_memory
   1011 # CHECK-LABEL: name: test_existing_setcc_memory
   1012 liveins:
   1013   - { reg: '$rdi', virtual-reg: '%0' }
   1014   - { reg: '$rsi', virtual-reg: '%1' }
   1015 body:             |
   1016   bb.0:
   1017     successors: %bb.1, %bb.2
   1018     liveins: $rdi, $rsi
   1019 
   1020     %0:gr64 = COPY $rdi
   1021     %1:gr64 = COPY $rsi
   1022     CMP64rr %0, %1, implicit-def $eflags
   1023     SETEm %0, 1, $noreg, -16, $noreg, implicit $eflags
   1024     %2:gr64 = COPY $eflags
   1025   ; CHECK:      CMP64rr %0, %1, implicit-def $eflags
   1026   ; We cannot reuse this SETE because it stores the flag directly to memory,
   1027   ; so we have two SETEs here. FIXME: It'd be great if something could fold
   1028   ; these automatically. If not, maybe we want to unfold SETcc instructions
   1029   ; writing to memory so we can reuse them.
   1030   ; CHECK-NEXT: SETEm {{.*}} implicit $eflags
   1031   ; CHECK-NEXT: %[[E_REG:[^:]*]]:gr8 = SETEr implicit $eflags
   1032   ; CHECK-NOT:  COPY{{( killed)?}} $eflags
   1033 
   1034     ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
   1035     CALL64pcrel32 @foo, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax
   1036     ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
   1037 
   1038     $eflags = COPY %2
   1039     JE_1 %bb.1, implicit $eflags
   1040     JMP_1 %bb.2
   1041   ; CHECK-NOT: $eflags =
   1042   ;
   1043   ; CHECK:        TEST8rr %[[E_REG]], %[[E_REG]], implicit-def $eflags
   1044   ; CHECK-NEXT:   JNE_1 %bb.1, implicit killed $eflags
   1045   ; CHECK-NEXT:   JMP_1 %bb.2
   1046 
   1047   bb.1:
   1048     %3:gr32 = MOV32ri64 42
   1049     $eax = COPY %3
   1050     RET 0, $eax
   1051 
   1052   bb.2:
   1053     %4:gr32 = MOV32ri64 43
   1054     $eax = COPY %4
   1055     RET 0, $eax
   1056 
   1057 ...
   1058