# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py # RUN: llc -o - %s -mtriple=x86_64-- -run-pass peephole-opt | FileCheck %s --- name: opt_zerocmp_0 body: | bb.0: ; CHECK-LABEL: name: opt_zerocmp_0 ; CHECK: [[COPY:%[0-9]+]]:gr32 = COPY $esi ; CHECK-NEXT: [[XOR32ri:%[0-9]+]]:gr32 = XOR32ri [[COPY]], i32 1234, implicit-def $eflags ; CHECK-NEXT: $al = SETCCr 5, implicit $eflags %0:gr32 = COPY $esi %1:gr32 = XOR32ri %0, i32 1234, implicit-def $eflags ; TEST should be removed. TEST32rr %1, %1, implicit-def $eflags $al = SETCCr 5, implicit $eflags ... --- name: opt_zerocmp_1 body: | bb.0: ; CHECK-LABEL: name: opt_zerocmp_1 ; CHECK: [[COPY:%[0-9]+]]:gr64 = COPY $rsi ; CHECK-NEXT: [[DEC64r:%[0-9]+]]:gr64 = DEC64r [[COPY]], implicit-def $eflags ; CHECK-NEXT: [[LEA64r:%[0-9]+]]:gr64 = LEA64r [[DEC64r]], 5, $noreg, 12, $noreg ; CHECK-NEXT: $al = SETCCr 4, implicit $eflags %0:gr64 = COPY $rsi %1:gr64 = DEC64r %0, implicit-def $eflags ; CMP should be removed. CMP64ri8 %1, 0, implicit-def $eflags %2:gr64 = LEA64r %1, 5, $noreg, 12, $noreg $al = SETCCr 4, implicit $eflags ... --- name: opt_multiple_blocks tracksRegLiveness: true body: | ; CHECK-LABEL: name: opt_multiple_blocks ; CHECK: bb.0: ; CHECK-NEXT: successors: %bb.1(0x80000000) ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64 = COPY undef $rsi ; CHECK-NEXT: [[INC64r:%[0-9]+]]:gr64 = INC64r [[COPY]], implicit-def $eflags ; CHECK-NEXT: PUSH64r undef $rcx, implicit-def $rsp, implicit $rsp ; CHECK-NEXT: $rcx = POP64r implicit-def $rsp, implicit $rsp ; CHECK-NEXT: JMP_1 %bb.1 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.1: ; CHECK-NEXT: liveins: $eflags ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[LEA64r:%[0-9]+]]:gr64 = LEA64r [[INC64r]], 5, $noreg, 12, $noreg ; CHECK-NEXT: $al = SETCCr 4, implicit $eflags bb.0: %0:gr64 = COPY undef $rsi %1:gr64 = INC64r %0, implicit-def $eflags PUSH64r undef $rcx, implicit-def $rsp, implicit $rsp $rcx = POP64r implicit-def $rsp, implicit $rsp JMP_1 %bb.1 bb.1: ; TEST should be removed. TEST64rr %1, %1, implicit-def $eflags %2:gr64 = LEA64r %1, 5, $noreg, 12, $noreg $al = SETCCr 4, implicit $eflags ... --- name: opt_multiple_blocks_noopt_0 body: | ; CHECK-LABEL: name: opt_multiple_blocks_noopt_0 ; CHECK: bb.0: ; CHECK-NEXT: successors: %bb.1(0x80000000) ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64 = COPY undef $rsi ; CHECK-NEXT: [[INC64r:%[0-9]+]]:gr64 = INC64r [[COPY]], implicit-def $eflags ; CHECK-NEXT: JMP_1 %bb.1 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.1: ; CHECK-NEXT: successors: %bb.1(0x40000000), %bb.2(0x40000000) ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: TEST64rr [[INC64r]], [[INC64r]], implicit-def $eflags ; CHECK-NEXT: [[LEA64r:%[0-9]+]]:gr64 = LEA64r [[INC64r]], 5, $noreg, 12, $noreg ; CHECK-NEXT: $al = SETCCr 4, implicit $eflags ; CHECK-NEXT: JCC_1 %bb.1, 2, implicit $eflags ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.2: bb.0: %0:gr64 = COPY undef $rsi %1:gr64 = INC64r %0, implicit-def $eflags JMP_1 %bb.1 bb.1: ; The TEST64rr should not be removed, since there are multiple preds. TEST64rr %1, %1, implicit-def $eflags %2:gr64 = LEA64r %1, 5, $noreg, 12, $noreg $al = SETCCr 4, implicit $eflags JCC_1 %bb.1, 2, implicit $eflags bb.2: ... --- name: opt_multiple_blocks_noopt_1 body: | ; CHECK-LABEL: name: opt_multiple_blocks_noopt_1 ; CHECK: bb.0: ; CHECK-NEXT: successors: %bb.1(0x80000000) ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: JMP_1 %bb.1 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.1: ; CHECK-NEXT: successors: %bb.1(0x40000000), %bb.2(0x40000000) ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64 = COPY undef $rsi ; CHECK-NEXT: TEST64rr [[COPY]], [[COPY]], implicit-def $eflags ; CHECK-NEXT: JCC_1 %bb.1, 2, implicit $eflags ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.2: ; CHECK-NEXT: [[MOV32r0_:%[0-9]+]]:gr32 = MOV32r0 implicit-def $eflags ; CHECK-NEXT: TEST64rr [[COPY]], [[COPY]], implicit-def $eflags ; CHECK-NEXT: $al = SETCCr 4, implicit $eflags bb.0: JMP_1 %bb.1 bb.1: %0:gr64 = COPY undef $rsi TEST64rr %0, %0, implicit-def $eflags JCC_1 %bb.1, 2, implicit $eflags bb.2: ; We should not move MOV32r0 up into the loop (that would be correct but ; slow). %1:gr32 = MOV32r0 implicit-def $eflags ; TEST should not be removed because of MOV32r0. TEST64rr %0, %0, implicit-def $eflags $al = SETCCr 4, implicit $eflags ... --- name: opt_zerocmp_user_0 body: | bb.0: ; CHECK-LABEL: name: opt_zerocmp_user_0 ; CHECK: [[COPY:%[0-9]+]]:gr32 = COPY $esi ; CHECK-NEXT: [[NEG32r:%[0-9]+]]:gr32 = NEG32r [[COPY]], implicit-def $eflags ; CHECK-NEXT: $al = SETCCr 3, implicit $eflags %0:gr32 = COPY $esi %1:gr32 = NEG32r %0, implicit-def dead $eflags ; TEST should be removed. TEST32rr %0, %0, implicit-def $eflags $al = SETCCr 4, implicit $eflags ... --- name: opt_redundant_flags_0 body: | bb.0: ; CHECK-LABEL: name: opt_redundant_flags_0 ; CHECK: [[COPY:%[0-9]+]]:gr32 = COPY $esi ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr32 = COPY $edi ; CHECK-NEXT: [[SUB32rr:%[0-9]+]]:gr32 = SUB32rr [[COPY]], [[COPY1]], implicit-def $eflags ; CHECK-NEXT: $eax = COPY [[SUB32rr]] ; CHECK-NEXT: $bl = SETCCr 2, implicit $eflags %0:gr32 = COPY $esi %1:gr32 = COPY $edi %2:gr32 = SUB32rr %0, %1, implicit-def dead $eflags $eax = COPY %2 ; CMP should be removed. CMP32rr %0, %1, implicit-def $eflags $bl = SETCCr 2, implicit $eflags ... --- name: opt_redundant_flags_1 body: | bb.0: ; CHECK-LABEL: name: opt_redundant_flags_1 ; CHECK: [[COPY:%[0-9]+]]:gr32 = COPY $esi ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr32 = COPY $edi ; CHECK-NEXT: [[SUB32rr:%[0-9]+]]:gr32 = SUB32rr [[COPY]], [[COPY1]], implicit-def $eflags ; CHECK-NEXT: $eax = COPY [[SUB32rr]] ; CHECK-NEXT: $bl = SETCCr 6, implicit $eflags %0:gr32 = COPY $esi %1:gr32 = COPY $edi %2:gr32 = SUB32rr %0, %1, implicit-def dead $eflags $eax = COPY %2 ; CMP should be removed. CMP32rr %1, %0, implicit-def $eflags $bl = SETCCr 3, implicit $eflags ... --- name: opt_redundant_flags_2 body: | bb.0: ; CHECK-LABEL: name: opt_redundant_flags_2 ; CHECK: [[COPY:%[0-9]+]]:gr32 = COPY $esi ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr32 = COPY $edi ; CHECK-NEXT: [[SUB32rr:%[0-9]+]]:gr32 = SUB32rr [[COPY]], [[COPY1]], implicit-def $eflags ; CHECK-NEXT: $cl = SETCCr 2, implicit $eflags ; CHECK-NEXT: $eax = COPY [[SUB32rr]] ; CHECK-NEXT: $bl = SETCCr 2, implicit $eflags %0:gr32 = COPY $esi %1:gr32 = COPY $edi %2:gr32 = SUB32rr %0, %1, implicit-def $eflags ; an extra eflags reader shouldn't stop optimization. $cl = SETCCr 2, implicit $eflags $eax = COPY %2 CMP32rr %0, %1, implicit-def $eflags $bl = SETCCr 2, implicit $eflags ... --- name: opt_redundant_flags_cmp_cmp body: | bb.0: ; CHECK-LABEL: name: opt_redundant_flags_cmp_cmp ; CHECK: [[COPY:%[0-9]+]]:gr32 = COPY $esi ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr32 = COPY $edi ; CHECK-NEXT: CMP32rr [[COPY]], [[COPY1]], implicit-def $eflags ; CHECK-NEXT: $cl = SETCCr 2, implicit $eflags ; CHECK-NEXT: $bl = SETCCr 7, implicit $eflags %0:gr32 = COPY $esi %1:gr32 = COPY $edi CMP32rr %0, %1, implicit-def $eflags $cl = SETCCr 2, implicit $eflags ; 2nd CMP should be removed. CMP32rr %1, %0, implicit-def $eflags $bl = SETCCr 2, implicit $eflags ... --- name: opt_redundant_flags_cmp_cmp_2 body: | bb.0: ; CHECK-LABEL: name: opt_redundant_flags_cmp_cmp_2 ; CHECK: [[COPY:%[0-9]+]]:gr64 = COPY $rsi ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr64 = COPY $rdi ; CHECK-NEXT: CMP64ri8 [[COPY]], 15, implicit-def $eflags ; CHECK-NEXT: $cl = SETCCr 2, implicit $eflags ; CHECK-NEXT: $bl = SETCCr 2, implicit $eflags %0:gr64 = COPY $rsi %1:gr64 = COPY $rdi CMP64ri8 %0, 15, implicit-def $eflags $cl = SETCCr 2, implicit $eflags ; 2nd CMP should be removed. CMP64ri8 %0, 15, implicit-def $eflags $bl = SETCCr 2, implicit $eflags ... --- name: opt_redundant_flags_test_test body: | bb.0: ; CHECK-LABEL: name: opt_redundant_flags_test_test ; CHECK: [[COPY:%[0-9]+]]:gr16 = COPY $ax ; CHECK-NEXT: TEST16rr [[COPY]], [[COPY]], implicit-def $eflags ; CHECK-NEXT: $cl = SETCCr 2, implicit $eflags ; CHECK-NEXT: $bl = SETCCr 2, implicit $eflags %0:gr16 = COPY $ax TEST16rr %0, %0, implicit-def $eflags $cl = SETCCr 2, implicit $eflags ; 2nd CMP should be removed. TEST16rr %0, %0, implicit-def $eflags $bl = SETCCr 2, implicit $eflags ... --- name: opt_redundant_flags_cmp_sub body: | bb.0: ; CHECK-LABEL: name: opt_redundant_flags_cmp_sub ; CHECK: [[COPY:%[0-9]+]]:gr32 = COPY $esi ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr32 = COPY $edi ; CHECK-NEXT: CMP32rr [[COPY]], [[COPY1]], implicit-def $eflags ; CHECK-NEXT: $cl = SETCCr 2, implicit $eflags ; CHECK-NEXT: $bl = SETCCr 7, implicit $eflags %0:gr32 = COPY $esi %1:gr32 = COPY $edi CMP32rr %0, %1, implicit-def $eflags $cl = SETCCr 2, implicit $eflags ; SUB should be removed. dead %2:gr32 = SUB32rr %1, %0, implicit-def $eflags $bl = SETCCr 2, implicit $eflags ... --- name: opt_redundant_flags_cmp_sub_2 body: | bb.0: ; CHECK-LABEL: name: opt_redundant_flags_cmp_sub_2 ; CHECK: [[COPY:%[0-9]+]]:gr32 = COPY $esi ; CHECK-NEXT: CMP32ri [[COPY]], -12345, implicit-def $eflags ; CHECK-NEXT: $cl = SETCCr 2, implicit $eflags ; CHECK-NEXT: $bl = SETCCr 2, implicit $eflags %0:gr32 = COPY $esi CMP32ri %0, -12345, implicit-def $eflags $cl = SETCCr 2, implicit $eflags ; SUB should be removed dead %2:gr32 = SUB32ri %0, -12345, implicit-def $eflags $bl = SETCCr 2, implicit $eflags ... --- name: opt_redundant_flags_cmp_sub_noopt body: | bb.0: ; CHECK-LABEL: name: opt_redundant_flags_cmp_sub_noopt ; CHECK: [[COPY:%[0-9]+]]:gr32 = COPY $esi ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr32 = COPY $edi ; CHECK-NEXT: CMP32rr [[COPY]], [[COPY1]], implicit-def $eflags ; CHECK-NEXT: $cl = SETCCr 2, implicit $eflags ; CHECK-NEXT: [[SUB32rr:%[0-9]+]]:gr32 = SUB32rr [[COPY]], [[COPY1]], implicit-def $eflags ; CHECK-NEXT: $rdx = COPY [[SUB32rr]] ; CHECK-NEXT: $bl = SETCCr 2, implicit $eflags %0:gr32 = COPY $esi %1:gr32 = COPY $edi CMP32rr %0, %1, implicit-def $eflags $cl = SETCCr 2, implicit $eflags ; cannot optimize the SUB because the result value is used. %2:gr32 = SUB32rr %0, %1, implicit-def $eflags $rdx = COPY %2 $bl = SETCCr 2, implicit $eflags ... --- name: opt_redundant_flags_cmp_test body: | bb.0: ; CHECK-LABEL: name: opt_redundant_flags_cmp_test ; CHECK: [[COPY:%[0-9]+]]:gr32 = COPY $esi ; CHECK-NEXT: CMP32ri8 [[COPY]], 0, implicit-def $eflags ; CHECK-NEXT: $cl = SETCCr 2, implicit $eflags ; CHECK-NEXT: $bl = SETCCr 2, implicit $eflags %0:gr32 = COPY $esi CMP32ri8 %0, 0, implicit-def $eflags $cl = SETCCr 2, implicit $eflags ; TEST should be removed TEST32rr %0, %0, implicit-def $eflags $bl = SETCCr 2, implicit $eflags ... --- name: opt_redundant_flags_test_cmp body: | bb.0: ; CHECK-LABEL: name: opt_redundant_flags_test_cmp ; CHECK: [[COPY:%[0-9]+]]:gr32 = COPY $esi ; CHECK-NEXT: TEST32rr [[COPY]], [[COPY]], implicit-def $eflags ; CHECK-NEXT: $cl = SETCCr 2, implicit $eflags ; CHECK-NEXT: $bl = SETCCr 2, implicit $eflags %0:gr32 = COPY $esi TEST32rr %0, %0, implicit-def $eflags $cl = SETCCr 2, implicit $eflags ; TEST should be removed CMP32ri8 %0, 0, implicit-def $eflags $bl = SETCCr 2, implicit $eflags ... --- name: opt_redundant_flags_cmp_addr stack: - { id: 0, size: 4, alignment: 4 } body: | bb.0: ; CHECK-LABEL: name: opt_redundant_flags_cmp_addr ; CHECK: [[COPY:%[0-9]+]]:gr64 = COPY $rsi ; CHECK-NEXT: CMP64ri32 [[COPY]], @opt_redundant_flags_cmp_addr + 4, implicit-def $eflags ; CHECK-NEXT: $cl = SETCCr 7, implicit $eflags ; CHECK-NEXT: $cl = SETCCr 3, implicit $eflags %0:gr64 = COPY $rsi CMP64ri32 %0, @opt_redundant_flags_cmp_addr + 4, implicit-def $eflags $cl = SETCCr 7, implicit $eflags ; CMP should be removed CMP64ri32 %0, @opt_redundant_flags_cmp_addr + 4, implicit-def $eflags $cl = SETCCr 3, implicit $eflags ... --- name: opt_redundant_flags_cmp_addr_noopt stack: - { id: 0, size: 4, alignment: 4 } body: | bb.0: ; CHECK-LABEL: name: opt_redundant_flags_cmp_addr_noopt ; CHECK: [[COPY:%[0-9]+]]:gr64 = COPY $rsi ; CHECK-NEXT: CMP64ri32 [[COPY]], @opt_redundant_flags_cmp_addr_noopt + 24, implicit-def $eflags ; CHECK-NEXT: $cl = SETCCr 7, implicit $eflags ; CHECK-NEXT: CMP64ri32 [[COPY]], 24, implicit-def $eflags ; CHECK-NEXT: $cl = SETCCr 3, implicit $eflags %0:gr64 = COPY $rsi CMP64ri32 %0, @opt_redundant_flags_cmp_addr_noopt + 24, implicit-def $eflags $cl = SETCCr 7, implicit $eflags ; CMP should not be removed CMP64ri32 %0, 24, implicit-def $eflags $cl = SETCCr 3, implicit $eflags ...