| # 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. | |
| CMP64ri32 %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: CMP64ri32 [[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 | |
| CMP64ri32 %0, 15, implicit-def $eflags | |
| $cl = SETCCr 2, implicit $eflags | |
| ; 2nd CMP should be removed. | |
| CMP64ri32 %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: CMP32ri [[COPY]], 0, implicit-def $eflags | |
| ; CHECK-NEXT: $cl = SETCCr 2, implicit $eflags | |
| ; CHECK-NEXT: $bl = SETCCr 2, implicit $eflags | |
| %0:gr32 = COPY $esi | |
| CMP32ri %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 | |
| CMP32ri %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 | |
| ... | |
| --- | |
| name: opt_redundant_flags_adjusted_imm_0 | |
| body: | | |
| bb.0: | |
| ; CHECK-LABEL: name: opt_redundant_flags_adjusted_imm_0 | |
| ; CHECK: [[COPY:%[0-9]+]]:gr64 = COPY $rsi | |
| ; CHECK-NEXT: CMP64ri32 [[COPY]], 1, implicit-def $eflags | |
| ; CHECK-NEXT: $cl = SETCCr 4, implicit $eflags | |
| ; CHECK-NEXT: $bl = SETCCr 15, implicit $eflags | |
| ; CHECK-NEXT: $bl = SETCCr 7, implicit $eflags | |
| ; CHECK-NEXT: $bl = SETCCr 14, implicit $eflags | |
| ; CHECK-NEXT: $bl = SETCCr 6, implicit $eflags | |
| %0:gr64 = COPY $rsi | |
| ; CMP+SETCC %0 == 1 | |
| CMP64ri32 %0, 1, implicit-def $eflags | |
| $cl = SETCCr 4, implicit $eflags | |
| ; CMP+SETCC %0 >= 2; CMP can be removed. | |
| CMP64ri32 %0, 2, implicit-def $eflags | |
| ; %0 >=s 2 --> %0 >s 1 | |
| $bl = SETCCr 13, implicit $eflags | |
| ; %0 >=u 2 --> %0 >u 1 | |
| $bl = SETCCr 3, implicit $eflags | |
| ; %0 <s 2 --> %0 <=s 1 | |
| $bl = SETCCr 12, implicit $eflags | |
| ; %0 <u 2 --> %0 <=u 1 | |
| $bl = SETCCr 2, implicit $eflags | |
| ... | |
| --- | |
| name: opt_redundant_flags_adjusted_imm_1 | |
| body: | | |
| bb.0: | |
| ; CHECK-LABEL: name: opt_redundant_flags_adjusted_imm_1 | |
| ; CHECK: [[COPY:%[0-9]+]]:gr64 = COPY $rsi | |
| ; CHECK-NEXT: CMP64ri32 [[COPY]], 42, implicit-def $eflags | |
| ; CHECK-NEXT: $cl = SETCCr 5, implicit $eflags | |
| ; CHECK-NEXT: $bl = SETCCr 13, implicit $eflags | |
| ; CHECK-NEXT: $bl = SETCCr 3, implicit $eflags | |
| ; CHECK-NEXT: $bl = SETCCr 12, implicit $eflags | |
| ; CHECK-NEXT: $bl = SETCCr 2, implicit $eflags | |
| %0:gr64 = COPY $rsi | |
| ; CMP+SETCC %0 != 42 | |
| CMP64ri32 %0, 42, implicit-def $eflags | |
| $cl = SETCCr 5, implicit $eflags | |
| ; CMP+SETCC %0 >= 2; CMP can be removed. | |
| CMP64ri32 %0, 41, implicit-def $eflags | |
| ; %0 >s 41 --> %0 >=s 42 | |
| $bl = SETCCr 15, implicit $eflags | |
| ; %0 >u 41 --> %0 >=u 42 | |
| $bl = SETCCr 7, implicit $eflags | |
| ; %0 <=s 41 --> %0 <s 42 | |
| $bl = SETCCr 14, implicit $eflags | |
| ; %0 <=u 41 --> %0 <u 42 | |
| $bl = SETCCr 6, implicit $eflags | |
| ... | |
| --- | |
| name: opt_redundant_flags_adjusted_imm_test_cmp | |
| body: | | |
| bb.0: | |
| ; CHECK-LABEL: name: opt_redundant_flags_adjusted_imm_test_cmp | |
| ; CHECK: [[COPY:%[0-9]+]]:gr8 = COPY $bl | |
| ; CHECK-NEXT: TEST8rr [[COPY]], [[COPY]], implicit-def $eflags | |
| ; CHECK-NEXT: $cl = SETCCr 14, implicit $eflags | |
| ; CHECK-NEXT: $cl = SETCCr 7, implicit $eflags | |
| ; CHECK-NEXT: $cl = SETCCr 12, implicit $eflags | |
| %0:gr8 = COPY $bl | |
| TEST8rr %0, %0, implicit-def $eflags | |
| ; SET %0 <=s 0 | |
| $cl = SETCCr 14, implicit $eflags | |
| ; CMP should be removed (%0 >=u 1) | |
| CMP8ri %0, 1, implicit-def $eflags | |
| $cl = SETCCr 3, implicit $eflags | |
| ; CMP should be removed (%0 <=s -1) | |
| CMP8ri %0, -1, implicit-def $eflags | |
| $cl = SETCCr 14, implicit $eflags | |
| ... | |
| --- | |
| name: opt_redundant_flags_adjusted_imm_cmp_test | |
| body: | | |
| bb.0: | |
| ; CHECK-LABEL: name: opt_redundant_flags_adjusted_imm_cmp_test | |
| ; CHECK: [[COPY:%[0-9]+]]:gr64 = COPY $rsi | |
| ; CHECK-NEXT: CMP64ri32 [[COPY]], 1, implicit-def $eflags | |
| ; CHECK-NEXT: $cl = SETCCr 13, implicit $eflags | |
| ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr64 = COPY $edi | |
| ; CHECK-NEXT: CMP64ri32 [[COPY1]], -1, implicit-def $eflags | |
| ; CHECK-NEXT: $cl = SETCCr 14, implicit $eflags | |
| %0:gr64 = COPY $rsi | |
| CMP64ri32 %0, 1, implicit-def $eflags | |
| ; TEST should be removed | |
| TEST64rr %0, %0, implicit-def $eflags | |
| $cl = SETCCr 15, implicit $eflags | |
| %1:gr64 = COPY $edi | |
| CMP64ri32 %1, -1, implicit-def $eflags | |
| ; TEST should be removed | |
| TEST64rr %1, %1, implicit-def $eflags | |
| $cl = SETCCr 12, implicit $eflags | |
| ... | |
| --- | |
| name: opt_redundant_flags_adjusted_imm_noopt_0 | |
| body: | | |
| bb.0: | |
| ; CHECK-LABEL: name: opt_redundant_flags_adjusted_imm_noopt_0 | |
| ; CHECK: [[COPY:%[0-9]+]]:gr64 = COPY $rsi | |
| ; CHECK-NEXT: CMP64ri32 [[COPY]], 42, implicit-def $eflags | |
| ; CHECK-NEXT: $cl = SETCCr 4, implicit $eflags | |
| ; CHECK-NEXT: CMP64ri32 [[COPY]], 41, implicit-def $eflags | |
| ; CHECK-NEXT: $bl = SETCCr 4, implicit $eflags | |
| %0:gr64 = COPY $rsi | |
| ; CMP+SETCC %0 <s 1 | |
| CMP64ri32 %0, 42, implicit-def $eflags | |
| $cl = SETCCr 4, implicit $eflags | |
| ; CMP should not be removed. | |
| CMP64ri32 %0, 41, implicit-def $eflags | |
| ; %0 == 41 | |
| $bl = SETCCr 4, implicit $eflags | |
| ... | |
| --- | |
| name: opt_redundant_flags_adjusted_imm_noopt_1 | |
| body: | | |
| bb.0: | |
| ; CHECK-LABEL: name: opt_redundant_flags_adjusted_imm_noopt_1 | |
| ; CHECK: [[COPY:%[0-9]+]]:gr32 = COPY $esi | |
| ; CHECK-NEXT: CMP32ri [[COPY]], 2147483647, implicit-def $eflags | |
| ; CHECK-NEXT: CMP32ri [[COPY]], -2147483648, implicit-def $eflags | |
| ; CHECK-NEXT: $bl = SETCCr 12, implicit $eflags | |
| ; CHECK-NEXT: CMP32ri [[COPY]], 4294967295, implicit-def $eflags | |
| ; CHECK-NEXT: CMP32ri [[COPY]], -2147483648, implicit-def $eflags | |
| ; CHECK-NEXT: $bl = SETCCr 12, implicit $eflags | |
| ; CHECK-NEXT: CMP32ri [[COPY]], 2147483647, implicit-def $eflags | |
| ; CHECK-NEXT: CMP32ri [[COPY]], -2147483648, implicit-def $eflags | |
| ; CHECK-NEXT: $bl = SETCCr 13, implicit $eflags | |
| ; CHECK-NEXT: CMP32ri [[COPY]], 4294967295, implicit-def $eflags | |
| ; CHECK-NEXT: CMP32ri [[COPY]], 0, implicit-def $eflags | |
| ; CHECK-NEXT: $bl = SETCCr 2, implicit $eflags | |
| ; CHECK-NEXT: CMP32ri [[COPY]], 4294967295, implicit-def $eflags | |
| ; CHECK-NEXT: CMP32ri [[COPY]], 0, implicit-def $eflags | |
| ; CHECK-NEXT: $bl = SETCCr 3, implicit $eflags | |
| %0:gr32 = COPY $esi | |
| ; CMP+SETCC %0 == INT32_MAX | |
| CMP32ri %0, 2147483647, implicit-def $eflags | |
| ; CMP should not be removed. | |
| CMP32ri %0, -2147483648, implicit-def $eflags | |
| ; %0 <s INT32_MIN | |
| $bl = SETCCr 12, implicit $eflags | |
| CMP32ri %0, 4294967295, implicit-def $eflags | |
| ; CMP should not be removed. | |
| CMP32ri %0, -2147483648, implicit-def $eflags | |
| $bl = SETCCr 12, implicit $eflags | |
| CMP32ri %0, 2147483647, implicit-def $eflags | |
| ; CMP should not be removed. | |
| CMP32ri %0, -2147483648, implicit-def $eflags | |
| $bl = SETCCr 13, implicit $eflags | |
| CMP32ri %0, 4294967295, implicit-def $eflags | |
| ; should not be removed | |
| CMP32ri %0, 0, implicit-def $eflags | |
| $bl = SETCCr 2, implicit $eflags | |
| CMP32ri %0, 4294967295, implicit-def $eflags | |
| ; should not be removed | |
| CMP32ri %0, 0, implicit-def $eflags | |
| $bl = SETCCr 3, implicit $eflags | |
| ... | |
| --- | |
| name: opt_redundant_flags_adjusted_imm_noopt_2 | |
| body: | | |
| bb.0: | |
| ; CHECK-LABEL: name: opt_redundant_flags_adjusted_imm_noopt_2 | |
| ; CHECK: [[COPY:%[0-9]+]]:gr16 = COPY $cx | |
| ; CHECK-NEXT: CMP16ri [[COPY]], -32768, implicit-def $eflags | |
| ; CHECK-NEXT: CMP16ri [[COPY]], 32767, implicit-def $eflags | |
| ; CHECK-NEXT: $bl = SETCCr 15, implicit $eflags | |
| ; CHECK-NEXT: CMP16ri [[COPY]], 65535, implicit-def $eflags | |
| ; CHECK-NEXT: CMP16ri [[COPY]], 32767, implicit-def $eflags | |
| ; CHECK-NEXT: $bl = SETCCr 15, implicit $eflags | |
| ; CHECK-NEXT: CMP16ri [[COPY]], -32768, implicit-def $eflags | |
| ; CHECK-NEXT: CMP16ri [[COPY]], 32767, implicit-def $eflags | |
| ; CHECK-NEXT: $bl = SETCCr 14, implicit $eflags | |
| ; CHECK-NEXT: CMP16ri [[COPY]], 0, implicit-def $eflags | |
| ; CHECK-NEXT: CMP16ri [[COPY]], 65535, implicit-def $eflags | |
| ; CHECK-NEXT: $bl = SETCCr 4, implicit $eflags | |
| ; CHECK-NEXT: CMP16ri [[COPY]], 0, implicit-def $eflags | |
| ; CHECK-NEXT: CMP16ri [[COPY]], 65535, implicit-def $eflags | |
| ; CHECK-NEXT: $bl = SETCCr 6, implicit $eflags | |
| %0:gr16 = COPY $cx | |
| ; CMP+SETCC %0 == INT16_MIN | |
| CMP16ri %0, -32768, implicit-def $eflags | |
| ; CMP should not be removed. | |
| CMP16ri %0, 32767, implicit-def $eflags | |
| ; %0 >s INT16_MAX | |
| $bl = SETCCr 15, implicit $eflags | |
| CMP16ri %0, 65535, implicit-def $eflags | |
| ; CMP should not be removed. | |
| CMP16ri %0, 32767, implicit-def $eflags | |
| $bl = SETCCr 15, implicit $eflags | |
| CMP16ri %0, -32768, implicit-def $eflags | |
| ; CMP should not be removed. | |
| CMP16ri %0, 32767, implicit-def $eflags | |
| $bl = SETCCr 14, implicit $eflags | |
| CMP16ri %0, 0, implicit-def $eflags | |
| ; should not be removed | |
| CMP16ri %0, 65535, implicit-def $eflags | |
| $bl = SETCCr 4, implicit $eflags | |
| CMP16ri %0, 0, implicit-def $eflags | |
| ; should not be removed | |
| CMP16ri %0, 65535, implicit-def $eflags | |
| $bl = SETCCr 6, implicit $eflags | |
| ... | |
| --- | |
| name: opt_adjusted_imm_multiple_blocks | |
| body: | | |
| ; CHECK-LABEL: name: opt_adjusted_imm_multiple_blocks | |
| ; CHECK: bb.0: | |
| ; CHECK-NEXT: successors: %bb.1(0x40000000), %bb.3(0x40000000) | |
| ; CHECK-NEXT: {{ $}} | |
| ; CHECK-NEXT: [[COPY:%[0-9]+]]:gr32 = COPY $eax | |
| ; CHECK-NEXT: CMP32ri [[COPY]], 20, implicit-def $eflags | |
| ; CHECK-NEXT: JCC_1 %bb.1, 4, implicit $eflags | |
| ; CHECK-NEXT: JMP_1 %bb.3 | |
| ; CHECK-NEXT: {{ $}} | |
| ; CHECK-NEXT: bb.1: | |
| ; CHECK-NEXT: successors: %bb.2(0x40000000), %bb.3(0x40000000) | |
| ; CHECK-NEXT: liveins: $eflags | |
| ; CHECK-NEXT: {{ $}} | |
| ; CHECK-NEXT: JCC_1 %bb.2, 15, implicit $eflags | |
| ; CHECK-NEXT: JMP_1 %bb.3 | |
| ; CHECK-NEXT: {{ $}} | |
| ; CHECK-NEXT: bb.2: | |
| ; CHECK-NEXT: successors: %bb.3(0x80000000) | |
| ; CHECK-NEXT: {{ $}} | |
| ; CHECK-NEXT: JMP_1 %bb.3 | |
| ; CHECK-NEXT: {{ $}} | |
| ; CHECK-NEXT: bb.3: | |
| ; CHECK-NEXT: RET 0 | |
| bb.0: | |
| %0:gr32 = COPY $eax | |
| CMP32ri %0, 20, implicit-def $eflags | |
| JCC_1 %bb.1, 4, implicit $eflags | |
| JMP_1 %bb.3 | |
| bb.1: | |
| ; CMP can be removed when adjusting the JCC. | |
| CMP32ri %0, 21, implicit-def $eflags | |
| JCC_1 %bb.2, 13, implicit $eflags | |
| JMP_1 %bb.3 | |
| bb.2: | |
| JMP_1 %bb.3 | |
| bb.3: | |
| RET 0 | |
| ... | |
| --- | |
| name: opt_adjusted_imm_multiple_blocks_noopt | |
| body: | | |
| ; CHECK-LABEL: name: opt_adjusted_imm_multiple_blocks_noopt | |
| ; CHECK: bb.0: | |
| ; CHECK-NEXT: successors: %bb.1(0x40000000), %bb.3(0x40000000) | |
| ; CHECK-NEXT: {{ $}} | |
| ; CHECK-NEXT: [[COPY:%[0-9]+]]:gr32 = COPY $eax | |
| ; CHECK-NEXT: CMP32ri [[COPY]], 20, implicit-def $eflags | |
| ; CHECK-NEXT: JCC_1 %bb.1, 4, implicit $eflags | |
| ; CHECK-NEXT: JMP_1 %bb.3 | |
| ; CHECK-NEXT: {{ $}} | |
| ; CHECK-NEXT: bb.1: | |
| ; CHECK-NEXT: successors: %bb.2(0x40000000), %bb.3(0x40000000) | |
| ; CHECK-NEXT: {{ $}} | |
| ; CHECK-NEXT: CMP32ri [[COPY]], 21, implicit-def $eflags | |
| ; CHECK-NEXT: JCC_1 %bb.2, 13, implicit $eflags | |
| ; CHECK-NEXT: JMP_1 %bb.3 | |
| ; CHECK-NEXT: {{ $}} | |
| ; CHECK-NEXT: bb.2: | |
| ; CHECK-NEXT: successors: %bb.3(0x80000000) | |
| ; CHECK-NEXT: liveins: $eflags | |
| ; CHECK-NEXT: {{ $}} | |
| ; CHECK-NEXT: $al = SETCCr 4, implicit $eflags | |
| ; CHECK-NEXT: {{ $}} | |
| ; CHECK-NEXT: bb.3: | |
| ; CHECK-NEXT: RET 0 | |
| bb.0: | |
| %0:gr32 = COPY $eax | |
| CMP32ri %0, 20, implicit-def $eflags | |
| JCC_1 %bb.1, 4, implicit $eflags | |
| JMP_1 %bb.3 | |
| bb.1: | |
| ; The following CMP should not be optimized because $eflags is live-out | |
| CMP32ri %0, 21, implicit-def $eflags | |
| JCC_1 %bb.2, 13, implicit $eflags | |
| JMP_1 %bb.3 | |
| bb.2: | |
| liveins: $eflags | |
| $al = SETCCr 4, implicit $eflags | |
| bb.3: | |
| RET 0 | |
| ... | |
| --- | |
| name: opt_shift_cmp_zero | |
| body: | | |
| bb.0: | |
| ; CHECK-LABEL: name: opt_shift_cmp_zero | |
| ; CHECK: [[COPY:%[0-9]+]]:gr64 = COPY $rsi | |
| ; CHECK-NEXT: [[SHL64ri:%[0-9]+]]:gr64 = SHL64ri [[COPY]], 7, implicit-def $eflags | |
| ; CHECK-NEXT: $al = SETCCr 4, implicit $eflags | |
| %0:gr64 = COPY $rsi | |
| %1:gr64 = SHL64ri %0, 7, implicit-def dead $eflags | |
| ; TEST should be removed. | |
| TEST64rr %1, %1, implicit-def $eflags | |
| $al = SETCCr 4, implicit $eflags | |
| ... | |
| --- | |
| name: noopt_shift_cmp_zero | |
| body: | | |
| bb.0: | |
| ; CHECK-LABEL: name: noopt_shift_cmp_zero | |
| ; CHECK: [[COPY:%[0-9]+]]:gr64 = COPY $rsi | |
| ; CHECK-NEXT: [[SHL64ri:%[0-9]+]]:gr64 = SHL64ri [[COPY]], 9, implicit-def dead $eflags | |
| ; CHECK-NEXT: TEST64rr [[SHL64ri]], [[SHL64ri]], implicit-def $eflags | |
| ; CHECK-NEXT: $al = SETCCr 14, implicit $eflags | |
| %0:gr64 = COPY $rsi | |
| %1:gr64 = SHL64ri %0, 9, implicit-def dead $eflags | |
| ; TEST cannot be removed if a user relies on the OF flag. | |
| TEST64rr %1, %1, implicit-def $eflags | |
| $al = SETCCr 14, implicit $eflags | |
| ... | |
| --- | |
| name: noopt_shift_cmp_zero_multiblock | |
| body: | | |
| ; CHECK-LABEL: name: noopt_shift_cmp_zero_multiblock | |
| ; CHECK: bb.0: | |
| ; CHECK-NEXT: successors: %bb.1(0x80000000) | |
| ; CHECK-NEXT: {{ $}} | |
| ; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64 = COPY $rsi | |
| ; CHECK-NEXT: [[SHL64ri:%[0-9]+]]:gr64 = SHL64ri [[COPY]], 9, implicit-def dead $eflags | |
| ; CHECK-NEXT: TEST64rr [[SHL64ri]], [[SHL64ri]], implicit-def $eflags | |
| ; CHECK-NEXT: JMP_1 %bb.1 | |
| ; CHECK-NEXT: {{ $}} | |
| ; CHECK-NEXT: bb.1: | |
| ; CHECK-NEXT: liveins: $eflags | |
| ; CHECK-NEXT: {{ $}} | |
| ; CHECK-NEXT: $al = SETCCr 14, implicit $eflags | |
| bb.0: | |
| %0:gr64 = COPY $rsi | |
| %1:gr64 = SHL64ri %0, 9, implicit-def dead $eflags | |
| ; TEST cannot be removed if a user relies on the OF flag. | |
| TEST64rr %1, %1, implicit-def $eflags | |
| JMP_1 %bb.1 | |
| bb.1: | |
| liveins: $eflags | |
| $al = SETCCr 14, implicit $eflags | |
| ... | |
| --- | |
| name: opt_shift_cmp_zero_lea_count_one_use | |
| body: | | |
| bb.0: | |
| ; CHECK-LABEL: name: opt_shift_cmp_zero_lea_count_one_use | |
| ; CHECK: [[COPY:%[0-9]+]]:gr64 = COPY $rsi | |
| ; CHECK-NEXT: [[SHL64ri:%[0-9]+]]:gr64 = SHL64ri [[COPY]], 3, implicit-def $eflags | |
| ; CHECK-NEXT: $al = SETCCr 4, implicit $eflags | |
| %0:gr64 = COPY $rsi | |
| ; %0 has no other use, so the shift will never become an LEA and can | |
| ; provide the flags itself. | |
| %1:gr64 = SHL64ri %0, 3, implicit-def dead $eflags | |
| TEST64rr %1, %1, implicit-def $eflags | |
| $al = SETCCr 4, implicit $eflags | |
| ... | |
| --- | |
| name: opt_shift_cmp_zero_shl_one_one_use | |
| body: | | |
| bb.0: | |
| ; CHECK-LABEL: name: opt_shift_cmp_zero_shl_one_one_use | |
| ; CHECK: [[COPY:%[0-9]+]]:gr64 = COPY $rsi | |
| ; CHECK-NEXT: [[SHL64ri:%[0-9]+]]:gr64 = SHL64ri [[COPY]], 1, implicit-def $eflags | |
| ; CHECK-NEXT: $al = SETCCr 4, implicit $eflags | |
| %0:gr64 = COPY $rsi | |
| ; %0 has no other use, so the shift will never become an LEA and can | |
| ; provide the flags itself. | |
| %1:gr64 = SHL64ri %0, 1, implicit-def dead $eflags | |
| TEST64rr %1, %1, implicit-def $eflags | |
| $al = SETCCr 4, implicit $eflags | |
| ... | |
| --- | |
| name: noopt_shift_cmp_zero_lea_count_reused | |
| body: | | |
| bb.0: | |
| ; CHECK-LABEL: name: noopt_shift_cmp_zero_lea_count_reused | |
| ; CHECK: [[COPY:%[0-9]+]]:gr64 = COPY $rsi | |
| ; CHECK-NEXT: [[SHL64ri:%[0-9]+]]:gr64 = SHL64ri [[COPY]], 3, implicit-def dead $eflags | |
| ; CHECK-NEXT: TEST64rr [[SHL64ri]], [[SHL64ri]], implicit-def $eflags | |
| ; CHECK-NEXT: $al = SETCCr 4, implicit $eflags | |
| ; CHECK-NEXT: $rbx = COPY [[COPY]] | |
| %0:gr64 = COPY $rsi | |
| ; %0 is used again below, so the shift may still be converted to an LEA | |
| ; (which sets no flags) to avoid a register copy; the TEST must stay. | |
| %1:gr64 = SHL64ri %0, 3, implicit-def dead $eflags | |
| TEST64rr %1, %1, implicit-def $eflags | |
| $al = SETCCr 4, implicit $eflags | |
| $rbx = COPY %0 | |
| ... |