; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 ; RUN: llc -O3 -mtriple=arm64-apple-macosx -o - %s | FileCheck %s ; RUN: llc -O3 -mtriple=arm64-apple-macosx -global-isel -o - %s | FileCheck --check-prefix=GISEL %s define i32 @switch_with_matching_dests_0_and_pow2_3_cases(i8 %v) { ; CHECK-LABEL: switch_with_matching_dests_0_and_pow2_3_cases: ; CHECK: ; %bb.0: ; %entry ; CHECK-NEXT: mov w9, #100 ; =0x64 ; CHECK-NEXT: mov w8, #20 ; =0x14 ; CHECK-NEXT: LBB0_1: ; %loop.header ; CHECK-NEXT: ; =>This Inner Loop Header: Depth=1 ; CHECK-NEXT: ands w10, w0, #0xff ; CHECK-NEXT: b.eq LBB0_6 ; CHECK-NEXT: ; %bb.2: ; %loop.header ; CHECK-NEXT: ; in Loop: Header=BB0_1 Depth=1 ; CHECK-NEXT: cmp w10, #32 ; CHECK-NEXT: b.eq LBB0_6 ; CHECK-NEXT: ; %bb.3: ; %loop.header ; CHECK-NEXT: ; in Loop: Header=BB0_1 Depth=1 ; CHECK-NEXT: cmp w10, #124 ; CHECK-NEXT: b.eq LBB0_7 ; CHECK-NEXT: ; %bb.4: ; %loop.latch ; CHECK-NEXT: ; in Loop: Header=BB0_1 Depth=1 ; CHECK-NEXT: subs w9, w9, #1 ; CHECK-NEXT: b.ne LBB0_1 ; CHECK-NEXT: ; %bb.5: ; CHECK-NEXT: mov w8, #20 ; =0x14 ; CHECK-NEXT: LBB0_6: ; %common.ret ; CHECK-NEXT: mov w0, w8 ; CHECK-NEXT: ret ; CHECK-NEXT: LBB0_7: ; %e2 ; CHECK-NEXT: mov w0, #30 ; =0x1e ; CHECK-NEXT: ret ; ; GISEL-LABEL: switch_with_matching_dests_0_and_pow2_3_cases: ; GISEL: ; %bb.0: ; %entry ; GISEL-NEXT: mov w8, w0 ; GISEL-NEXT: mov w0, #20 ; =0x14 ; GISEL-NEXT: mov w9, #100 ; =0x64 ; GISEL-NEXT: LBB0_1: ; %loop.header ; GISEL-NEXT: ; =>This Inner Loop Header: Depth=1 ; GISEL-NEXT: ands w10, w8, #0xff ; GISEL-NEXT: b.eq LBB0_5 ; GISEL-NEXT: ; %bb.2: ; %loop.header ; GISEL-NEXT: ; in Loop: Header=BB0_1 Depth=1 ; GISEL-NEXT: cmp w10, #32 ; GISEL-NEXT: b.eq LBB0_5 ; GISEL-NEXT: ; %bb.3: ; %loop.header ; GISEL-NEXT: ; in Loop: Header=BB0_1 Depth=1 ; GISEL-NEXT: cmp w10, #124 ; GISEL-NEXT: b.eq LBB0_6 ; GISEL-NEXT: ; %bb.4: ; %loop.latch ; GISEL-NEXT: ; in Loop: Header=BB0_1 Depth=1 ; GISEL-NEXT: subs w9, w9, #1 ; GISEL-NEXT: b.ne LBB0_1 ; GISEL-NEXT: LBB0_5: ; %common.ret ; GISEL-NEXT: ret ; GISEL-NEXT: LBB0_6: ; %e2 ; GISEL-NEXT: mov w0, #30 ; =0x1e ; GISEL-NEXT: ret entry: br label %loop.header loop.header: %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] switch i8 %v, label %loop.latch [ i8 32, label %e1 i8 0, label %e1 i8 124, label %e2 ] loop.latch: %iv.next = add i32 %iv, 1 %c = icmp eq i32 %iv.next, 100 br i1 %c, label %e1, label %loop.header e1: ret i32 20 e2: ret i32 30 } define i32 @switch_with_matching_dests_0_and_pow2_3_cases_swapped(i8 %v) { ; CHECK-LABEL: switch_with_matching_dests_0_and_pow2_3_cases_swapped: ; CHECK: ; %bb.0: ; %entry ; CHECK-NEXT: mov w9, #100 ; =0x64 ; CHECK-NEXT: mov w8, #20 ; =0x14 ; CHECK-NEXT: LBB1_1: ; %loop.header ; CHECK-NEXT: ; =>This Inner Loop Header: Depth=1 ; CHECK-NEXT: ands w10, w0, #0xff ; CHECK-NEXT: b.eq LBB1_6 ; CHECK-NEXT: ; %bb.2: ; %loop.header ; CHECK-NEXT: ; in Loop: Header=BB1_1 Depth=1 ; CHECK-NEXT: cmp w10, #32 ; CHECK-NEXT: b.eq LBB1_6 ; CHECK-NEXT: ; %bb.3: ; %loop.header ; CHECK-NEXT: ; in Loop: Header=BB1_1 Depth=1 ; CHECK-NEXT: cmp w10, #124 ; CHECK-NEXT: b.eq LBB1_7 ; CHECK-NEXT: ; %bb.4: ; %loop.latch ; CHECK-NEXT: ; in Loop: Header=BB1_1 Depth=1 ; CHECK-NEXT: subs w9, w9, #1 ; CHECK-NEXT: b.ne LBB1_1 ; CHECK-NEXT: ; %bb.5: ; CHECK-NEXT: mov w8, #10 ; =0xa ; CHECK-NEXT: LBB1_6: ; %common.ret ; CHECK-NEXT: mov w0, w8 ; CHECK-NEXT: ret ; CHECK-NEXT: LBB1_7: ; %e2 ; CHECK-NEXT: mov w0, #30 ; =0x1e ; CHECK-NEXT: ret ; ; GISEL-LABEL: switch_with_matching_dests_0_and_pow2_3_cases_swapped: ; GISEL: ; %bb.0: ; %entry ; GISEL-NEXT: mov w9, #100 ; =0x64 ; GISEL-NEXT: mov w8, #20 ; =0x14 ; GISEL-NEXT: LBB1_1: ; %loop.header ; GISEL-NEXT: ; =>This Inner Loop Header: Depth=1 ; GISEL-NEXT: ands w10, w0, #0xff ; GISEL-NEXT: b.eq LBB1_6 ; GISEL-NEXT: ; %bb.2: ; %loop.header ; GISEL-NEXT: ; in Loop: Header=BB1_1 Depth=1 ; GISEL-NEXT: cmp w10, #32 ; GISEL-NEXT: b.eq LBB1_6 ; GISEL-NEXT: ; %bb.3: ; %loop.header ; GISEL-NEXT: ; in Loop: Header=BB1_1 Depth=1 ; GISEL-NEXT: cmp w10, #124 ; GISEL-NEXT: b.eq LBB1_7 ; GISEL-NEXT: ; %bb.4: ; %loop.latch ; GISEL-NEXT: ; in Loop: Header=BB1_1 Depth=1 ; GISEL-NEXT: subs w9, w9, #1 ; GISEL-NEXT: b.ne LBB1_1 ; GISEL-NEXT: ; %bb.5: ; GISEL-NEXT: mov w8, #10 ; =0xa ; GISEL-NEXT: LBB1_6: ; %common.ret ; GISEL-NEXT: mov w0, w8 ; GISEL-NEXT: ret ; GISEL-NEXT: LBB1_7: ; %e2 ; GISEL-NEXT: mov w0, #30 ; =0x1e ; GISEL-NEXT: ret entry: br label %loop.header loop.header: %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] switch i8 %v, label %loop.latch [ i8 0, label %e1 i8 32, label %e1 i8 124, label %e2 ] loop.latch: %iv.next = add i32 %iv, 1 %c = icmp eq i32 %iv.next, 100 br i1 %c, label %e0, label %loop.header e0: ret i32 10 e1: ret i32 20 e2: ret i32 30 } define i32 @switch_with_matching_dests_0_and_pow2_3_cases_with_phi(i8 %v, i1 %c) { ; CHECK-LABEL: switch_with_matching_dests_0_and_pow2_3_cases_with_phi: ; CHECK: ; %bb.0: ; %entry ; CHECK-NEXT: tbz w1, #0, LBB2_8 ; CHECK-NEXT: ; %bb.1: ; %loop.header.preheader ; CHECK-NEXT: mov w9, #100 ; =0x64 ; CHECK-NEXT: mov w8, #20 ; =0x14 ; CHECK-NEXT: LBB2_2: ; %loop.header ; CHECK-NEXT: ; =>This Inner Loop Header: Depth=1 ; CHECK-NEXT: ands w10, w0, #0xff ; CHECK-NEXT: b.eq LBB2_7 ; CHECK-NEXT: ; %bb.3: ; %loop.header ; CHECK-NEXT: ; in Loop: Header=BB2_2 Depth=1 ; CHECK-NEXT: cmp w10, #32 ; CHECK-NEXT: b.eq LBB2_7 ; CHECK-NEXT: ; %bb.4: ; %loop.header ; CHECK-NEXT: ; in Loop: Header=BB2_2 Depth=1 ; CHECK-NEXT: cmp w10, #124 ; CHECK-NEXT: b.eq LBB2_9 ; CHECK-NEXT: ; %bb.5: ; %loop.latch ; CHECK-NEXT: ; in Loop: Header=BB2_2 Depth=1 ; CHECK-NEXT: subs w9, w9, #1 ; CHECK-NEXT: b.ne LBB2_2 ; CHECK-NEXT: ; %bb.6: ; CHECK-NEXT: mov w8, #10 ; =0xa ; CHECK-NEXT: LBB2_7: ; %common.ret ; CHECK-NEXT: mov w0, w8 ; CHECK-NEXT: ret ; CHECK-NEXT: LBB2_8: ; CHECK-NEXT: mov w0, wzr ; CHECK-NEXT: ret ; CHECK-NEXT: LBB2_9: ; %e2 ; CHECK-NEXT: mov w0, #30 ; =0x1e ; CHECK-NEXT: ret ; ; GISEL-LABEL: switch_with_matching_dests_0_and_pow2_3_cases_with_phi: ; GISEL: ; %bb.0: ; %entry ; GISEL-NEXT: mov w8, wzr ; GISEL-NEXT: tbz w1, #0, LBB2_7 ; GISEL-NEXT: ; %bb.1: ; %loop.header.preheader ; GISEL-NEXT: mov w9, #100 ; =0x64 ; GISEL-NEXT: mov w8, #20 ; =0x14 ; GISEL-NEXT: LBB2_2: ; %loop.header ; GISEL-NEXT: ; =>This Inner Loop Header: Depth=1 ; GISEL-NEXT: ands w10, w0, #0xff ; GISEL-NEXT: b.eq LBB2_7 ; GISEL-NEXT: ; %bb.3: ; %loop.header ; GISEL-NEXT: ; in Loop: Header=BB2_2 Depth=1 ; GISEL-NEXT: cmp w10, #32 ; GISEL-NEXT: b.eq LBB2_7 ; GISEL-NEXT: ; %bb.4: ; %loop.header ; GISEL-NEXT: ; in Loop: Header=BB2_2 Depth=1 ; GISEL-NEXT: cmp w10, #124 ; GISEL-NEXT: b.eq LBB2_8 ; GISEL-NEXT: ; %bb.5: ; %loop.latch ; GISEL-NEXT: ; in Loop: Header=BB2_2 Depth=1 ; GISEL-NEXT: subs w9, w9, #1 ; GISEL-NEXT: b.ne LBB2_2 ; GISEL-NEXT: ; %bb.6: ; GISEL-NEXT: mov w8, #10 ; =0xa ; GISEL-NEXT: LBB2_7: ; %common.ret ; GISEL-NEXT: mov w0, w8 ; GISEL-NEXT: ret ; GISEL-NEXT: LBB2_8: ; %e2 ; GISEL-NEXT: mov w0, #30 ; =0x1e ; GISEL-NEXT: ret entry: br i1 %c, label %then, label %e1 then: br label %loop.header loop.header: %iv = phi i32 [ 0, %then], [ %iv.next, %loop.latch ] switch i8 %v, label %loop.latch [ i8 32, label %e1 i8 0, label %e1 i8 124, label %e2 ] loop.latch: %iv.next = add i32 %iv, 1 %ec = icmp eq i32 %iv.next, 100 br i1 %ec, label %e0, label %loop.header e0: ret i32 10 e1: %p = phi i32 [ 0, %entry ], [ 20, %loop.header ], [ 20, %loop.header ] ret i32 %p e2: ret i32 30 } define i32 @switch_with_matching_dests_0_and_pow2_3_cases_all_different_succs(i8 %v) { ; CHECK-LABEL: switch_with_matching_dests_0_and_pow2_3_cases_all_different_succs: ; CHECK: ; %bb.0: ; %entry ; CHECK-NEXT: mov w8, #100 ; =0x64 ; CHECK-NEXT: LBB3_1: ; %loop.header ; CHECK-NEXT: ; =>This Inner Loop Header: Depth=1 ; CHECK-NEXT: ands w9, w0, #0xff ; CHECK-NEXT: b.eq LBB3_6 ; CHECK-NEXT: ; %bb.2: ; %loop.header ; CHECK-NEXT: ; in Loop: Header=BB3_1 Depth=1 ; CHECK-NEXT: cmp w9, #32 ; CHECK-NEXT: b.eq LBB3_8 ; CHECK-NEXT: ; %bb.3: ; %loop.header ; CHECK-NEXT: ; in Loop: Header=BB3_1 Depth=1 ; CHECK-NEXT: cmp w9, #124 ; CHECK-NEXT: b.eq LBB3_7 ; CHECK-NEXT: ; %bb.4: ; %loop.latch ; CHECK-NEXT: ; in Loop: Header=BB3_1 Depth=1 ; CHECK-NEXT: subs w8, w8, #1 ; CHECK-NEXT: b.ne LBB3_1 ; CHECK-NEXT: ; %bb.5: ; CHECK-NEXT: mov w0, #10 ; =0xa ; CHECK-NEXT: ret ; CHECK-NEXT: LBB3_6: ; %e2 ; CHECK-NEXT: mov w0, #30 ; =0x1e ; CHECK-NEXT: ret ; CHECK-NEXT: LBB3_7: ; %e3 ; CHECK-NEXT: mov w0, #40 ; =0x28 ; CHECK-NEXT: ret ; CHECK-NEXT: LBB3_8: ; CHECK-NEXT: mov w0, #20 ; =0x14 ; CHECK-NEXT: ret ; ; GISEL-LABEL: switch_with_matching_dests_0_and_pow2_3_cases_all_different_succs: ; GISEL: ; %bb.0: ; %entry ; GISEL-NEXT: mov w8, #100 ; =0x64 ; GISEL-NEXT: LBB3_1: ; %loop.header ; GISEL-NEXT: ; =>This Inner Loop Header: Depth=1 ; GISEL-NEXT: ands w9, w0, #0xff ; GISEL-NEXT: b.eq LBB3_6 ; GISEL-NEXT: ; %bb.2: ; %loop.header ; GISEL-NEXT: ; in Loop: Header=BB3_1 Depth=1 ; GISEL-NEXT: cmp w9, #32 ; GISEL-NEXT: b.eq LBB3_8 ; GISEL-NEXT: ; %bb.3: ; %loop.header ; GISEL-NEXT: ; in Loop: Header=BB3_1 Depth=1 ; GISEL-NEXT: cmp w9, #124 ; GISEL-NEXT: b.eq LBB3_7 ; GISEL-NEXT: ; %bb.4: ; %loop.latch ; GISEL-NEXT: ; in Loop: Header=BB3_1 Depth=1 ; GISEL-NEXT: subs w8, w8, #1 ; GISEL-NEXT: b.ne LBB3_1 ; GISEL-NEXT: ; %bb.5: ; GISEL-NEXT: mov w0, #10 ; =0xa ; GISEL-NEXT: ret ; GISEL-NEXT: LBB3_6: ; %e2 ; GISEL-NEXT: mov w0, #30 ; =0x1e ; GISEL-NEXT: ret ; GISEL-NEXT: LBB3_7: ; %e3 ; GISEL-NEXT: mov w0, #40 ; =0x28 ; GISEL-NEXT: ret ; GISEL-NEXT: LBB3_8: ; GISEL-NEXT: mov w0, #20 ; =0x14 ; GISEL-NEXT: ret entry: br label %loop.header loop.header: %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] switch i8 %v, label %loop.latch [ i8 32, label %e1 i8 0, label %e2 i8 124, label %e3 ] loop.latch: %iv.next = add i32 %iv, 1 %ec = icmp eq i32 %iv.next, 100 br i1 %ec, label %e0, label %loop.header e0: ret i32 10 e1: ret i32 20 e2: ret i32 30 e3: ret i32 40 } define i32 @switch_in_loop_with_matching_dests_0_and_pow2_3_cases(ptr %start) { ; CHECK-LABEL: switch_in_loop_with_matching_dests_0_and_pow2_3_cases: ; CHECK: ; %bb.0: ; %entry ; CHECK-NEXT: add x8, x0, #1 ; CHECK-NEXT: LBB4_1: ; %loop ; CHECK-NEXT: ; =>This Inner Loop Header: Depth=1 ; CHECK-NEXT: ldrb w9, [x8], #1 ; CHECK-NEXT: cbz w9, LBB4_4 ; CHECK-NEXT: ; %bb.2: ; %loop ; CHECK-NEXT: ; in Loop: Header=BB4_1 Depth=1 ; CHECK-NEXT: cmp w9, #124 ; CHECK-NEXT: b.eq LBB4_5 ; CHECK-NEXT: ; %bb.3: ; %loop ; CHECK-NEXT: ; in Loop: Header=BB4_1 Depth=1 ; CHECK-NEXT: cmp w9, #32 ; CHECK-NEXT: b.ne LBB4_1 ; CHECK-NEXT: LBB4_4: ; %e1 ; CHECK-NEXT: mov w0, #-1 ; =0xffffffff ; CHECK-NEXT: ret ; CHECK-NEXT: LBB4_5: ; %e2.loopexit ; CHECK-NEXT: mov w0, wzr ; CHECK-NEXT: ret ; ; GISEL-LABEL: switch_in_loop_with_matching_dests_0_and_pow2_3_cases: ; GISEL: ; %bb.0: ; %entry ; GISEL-NEXT: add x8, x0, #1 ; GISEL-NEXT: LBB4_1: ; %loop ; GISEL-NEXT: ; =>This Inner Loop Header: Depth=1 ; GISEL-NEXT: ldrb w9, [x8], #1 ; GISEL-NEXT: cbz w9, LBB4_4 ; GISEL-NEXT: ; %bb.2: ; %loop ; GISEL-NEXT: ; in Loop: Header=BB4_1 Depth=1 ; GISEL-NEXT: cmp w9, #124 ; GISEL-NEXT: b.eq LBB4_5 ; GISEL-NEXT: ; %bb.3: ; %loop ; GISEL-NEXT: ; in Loop: Header=BB4_1 Depth=1 ; GISEL-NEXT: cmp w9, #32 ; GISEL-NEXT: b.ne LBB4_1 ; GISEL-NEXT: LBB4_4: ; %e1 ; GISEL-NEXT: mov w0, #-1 ; =0xffffffff ; GISEL-NEXT: ret ; GISEL-NEXT: LBB4_5: ; %e2.loopexit ; GISEL-NEXT: mov w0, wzr ; GISEL-NEXT: ret entry: br label %loop loop: %p = phi ptr [ %start, %entry ], [ %4, %loop ] %4 = getelementptr inbounds nuw i8, ptr %p, i64 1 %l = load i8, ptr %4, align 1 switch i8 %l, label %loop [ i8 32, label %e1 i8 0, label %e1 i8 124, label %e2 ] e1: br label %e2 e2: %8 = phi i32 [ -1, %e1 ], [ 0, %loop ] ret i32 %8 } define i32 @switch_in_loop_with_matching_dests_0_and_pow2_4_cases(ptr %start) { ; CHECK-LABEL: switch_in_loop_with_matching_dests_0_and_pow2_4_cases: ; CHECK: ; %bb.0: ; %entry ; CHECK-NEXT: mov x10, #32769 ; =0x8001 ; CHECK-NEXT: mov w8, #1 ; =0x1 ; CHECK-NEXT: add x9, x0, #1 ; CHECK-NEXT: movk x10, #1, lsl #32 ; CHECK-NEXT: b LBB5_2 ; CHECK-NEXT: LBB5_1: ; %loop ; CHECK-NEXT: ; in Loop: Header=BB5_2 Depth=1 ; CHECK-NEXT: cmp w11, #124 ; CHECK-NEXT: b.eq LBB5_5 ; CHECK-NEXT: LBB5_2: ; %loop ; CHECK-NEXT: ; =>This Inner Loop Header: Depth=1 ; CHECK-NEXT: ldrb w11, [x9], #1 ; CHECK-NEXT: cmp w11, #32 ; CHECK-NEXT: b.hi LBB5_1 ; CHECK-NEXT: ; %bb.3: ; %loop ; CHECK-NEXT: ; in Loop: Header=BB5_2 Depth=1 ; CHECK-NEXT: lsl x12, x8, x11 ; CHECK-NEXT: tst x12, x10 ; CHECK-NEXT: b.eq LBB5_1 ; CHECK-NEXT: ; %bb.4: ; %e1 ; CHECK-NEXT: mov w0, #-1 ; =0xffffffff ; CHECK-NEXT: ret ; CHECK-NEXT: LBB5_5: ; %e2.loopexit ; CHECK-NEXT: mov w0, wzr ; CHECK-NEXT: ret ; ; GISEL-LABEL: switch_in_loop_with_matching_dests_0_and_pow2_4_cases: ; GISEL: ; %bb.0: ; %entry ; GISEL-NEXT: mov x10, #32769 ; =0x8001 ; GISEL-NEXT: mov w8, #1 ; =0x1 ; GISEL-NEXT: add x9, x0, #1 ; GISEL-NEXT: movk x10, #1, lsl #32 ; GISEL-NEXT: b LBB5_2 ; GISEL-NEXT: LBB5_1: ; %loop ; GISEL-NEXT: ; in Loop: Header=BB5_2 Depth=1 ; GISEL-NEXT: cmp w11, #124 ; GISEL-NEXT: b.eq LBB5_5 ; GISEL-NEXT: LBB5_2: ; %loop ; GISEL-NEXT: ; =>This Inner Loop Header: Depth=1 ; GISEL-NEXT: ldrb w11, [x9], #1 ; GISEL-NEXT: cmp w11, #32 ; GISEL-NEXT: b.hi LBB5_1 ; GISEL-NEXT: ; %bb.3: ; %loop ; GISEL-NEXT: ; in Loop: Header=BB5_2 Depth=1 ; GISEL-NEXT: lsl x12, x8, x11 ; GISEL-NEXT: tst x12, x10 ; GISEL-NEXT: b.eq LBB5_1 ; GISEL-NEXT: ; %bb.4: ; %e1 ; GISEL-NEXT: mov w0, #-1 ; =0xffffffff ; GISEL-NEXT: ret ; GISEL-NEXT: LBB5_5: ; %e2.loopexit ; GISEL-NEXT: mov w0, wzr ; GISEL-NEXT: ret entry: br label %loop loop: %p = phi ptr [ %start, %entry ], [ %4, %loop ] %4 = getelementptr inbounds nuw i8, ptr %p, i64 1 %l = load i8, ptr %4, align 1 switch i8 %l, label %loop [ i8 0, label %e1 i8 15, label %e1 i8 32, label %e1 i8 124, label %e2 ] e1: br label %e2 e2: %8 = phi i32 [ -1, %e1 ], [ 0, %loop ] ret i32 %8 } define i32 @switch_in_loop_with_matching_dests_0_and_non_pow2(ptr %start) { ; CHECK-LABEL: switch_in_loop_with_matching_dests_0_and_non_pow2: ; CHECK: ; %bb.0: ; %entry ; CHECK-NEXT: add x8, x0, #1 ; CHECK-NEXT: LBB6_1: ; %loop ; CHECK-NEXT: ; =>This Inner Loop Header: Depth=1 ; CHECK-NEXT: ldrb w9, [x8], #1 ; CHECK-NEXT: cmp w9, #35 ; CHECK-NEXT: b.eq LBB6_4 ; CHECK-NEXT: ; %bb.2: ; %loop ; CHECK-NEXT: ; in Loop: Header=BB6_1 Depth=1 ; CHECK-NEXT: cmp w9, #33 ; CHECK-NEXT: b.eq LBB6_5 ; CHECK-NEXT: ; %bb.3: ; %loop ; CHECK-NEXT: ; in Loop: Header=BB6_1 Depth=1 ; CHECK-NEXT: cbnz w9, LBB6_1 ; CHECK-NEXT: LBB6_4: ; %common.ret.loopexit ; CHECK-NEXT: mov w0, #-1 ; =0xffffffff ; CHECK-NEXT: ret ; CHECK-NEXT: LBB6_5: ; %e2 ; CHECK-NEXT: mov w0, #10 ; =0xa ; CHECK-NEXT: ret ; ; GISEL-LABEL: switch_in_loop_with_matching_dests_0_and_non_pow2: ; GISEL: ; %bb.0: ; %entry ; GISEL-NEXT: add x8, x0, #1 ; GISEL-NEXT: LBB6_1: ; %loop ; GISEL-NEXT: ; =>This Inner Loop Header: Depth=1 ; GISEL-NEXT: ldrb w9, [x8], #1 ; GISEL-NEXT: cmp w9, #35 ; GISEL-NEXT: b.eq LBB6_4 ; GISEL-NEXT: ; %bb.2: ; %loop ; GISEL-NEXT: ; in Loop: Header=BB6_1 Depth=1 ; GISEL-NEXT: cmp w9, #33 ; GISEL-NEXT: b.eq LBB6_5 ; GISEL-NEXT: ; %bb.3: ; %loop ; GISEL-NEXT: ; in Loop: Header=BB6_1 Depth=1 ; GISEL-NEXT: cbnz w9, LBB6_1 ; GISEL-NEXT: LBB6_4: ; %common.ret.loopexit ; GISEL-NEXT: mov w0, #-1 ; =0xffffffff ; GISEL-NEXT: ret ; GISEL-NEXT: LBB6_5: ; %e2 ; GISEL-NEXT: mov w0, #10 ; =0xa ; GISEL-NEXT: ret entry: br label %loop loop: %p = phi ptr [ %start, %entry ], [ %4, %loop ] %4 = getelementptr inbounds nuw i8, ptr %p, i64 1 %l = load i8, ptr %4, align 1 switch i8 %l, label %loop [ i8 0, label %e1 i8 35, label %e1 i8 33, label %e2 ] e1: ret i32 -1 e2: ret i32 10 } define void @test_successor_with_loop_phi(ptr %A, ptr %B) { ; CHECK-LABEL: test_successor_with_loop_phi: ; CHECK: ; %bb.0: ; %entry ; CHECK-NEXT: LBB7_1: ; %loop ; CHECK-NEXT: ; =>This Inner Loop Header: Depth=1 ; CHECK-NEXT: ldr w8, [x0] ; CHECK-NEXT: str wzr, [x0] ; CHECK-NEXT: mov x0, x1 ; CHECK-NEXT: tst w8, #0xfffffffb ; CHECK-NEXT: b.eq LBB7_1 ; CHECK-NEXT: ; %bb.2: ; %exit ; CHECK-NEXT: ret ; ; GISEL-LABEL: test_successor_with_loop_phi: ; GISEL: ; %bb.0: ; %entry ; GISEL-NEXT: LBB7_1: ; %loop ; GISEL-NEXT: ; =>This Inner Loop Header: Depth=1 ; GISEL-NEXT: ldr w8, [x0] ; GISEL-NEXT: str wzr, [x0] ; GISEL-NEXT: mov x0, x1 ; GISEL-NEXT: cbz w8, LBB7_1 ; GISEL-NEXT: ; %bb.2: ; %loop ; GISEL-NEXT: ; in Loop: Header=BB7_1 Depth=1 ; GISEL-NEXT: cmp w8, #4 ; GISEL-NEXT: mov x0, x1 ; GISEL-NEXT: b.eq LBB7_1 ; GISEL-NEXT: ; %bb.3: ; %exit ; GISEL-NEXT: ret entry: br label %loop loop: %p = phi ptr [ %A, %entry ], [ %B , %loop ], [ %B, %loop ] %l = load i32, ptr %p store i32 0, ptr %p switch i32 %l, label %exit [ i32 4, label %loop i32 0, label %loop ] exit: ret void } define i64 @consecutive_match_both(ptr %p, i32 %param) { ; CHECK-LABEL: consecutive_match_both: ; CHECK: ; %bb.0: ; %entry ; CHECK-NEXT: mov w8, #1 ; =0x1 ; CHECK-NEXT: mov w9, #100 ; =0x64 ; CHECK-NEXT: mov w10, #249 ; =0xf9 ; CHECK-NEXT: lsl w8, w8, w1 ; CHECK-NEXT: b LBB8_2 ; CHECK-NEXT: LBB8_1: ; %loop.latch ; CHECK-NEXT: ; in Loop: Header=BB8_2 Depth=1 ; CHECK-NEXT: subs w9, w9, #1 ; CHECK-NEXT: b.eq LBB8_5 ; CHECK-NEXT: LBB8_2: ; %loop.header ; CHECK-NEXT: ; =>This Inner Loop Header: Depth=1 ; CHECK-NEXT: cmp w1, #7 ; CHECK-NEXT: b.hi LBB8_1 ; CHECK-NEXT: ; %bb.3: ; %loop.header ; CHECK-NEXT: ; in Loop: Header=BB8_2 Depth=1 ; CHECK-NEXT: tst w8, w10 ; CHECK-NEXT: b.eq LBB8_1 ; CHECK-NEXT: ; %bb.4: ; %e0 ; CHECK-NEXT: mov x0, xzr ; CHECK-NEXT: ret ; CHECK-NEXT: LBB8_5: ; CHECK-NEXT: mov x0, #-42 ; =0xffffffffffffffd6 ; CHECK-NEXT: ret ; ; GISEL-LABEL: consecutive_match_both: ; GISEL: ; %bb.0: ; %entry ; GISEL-NEXT: mov w8, #1 ; =0x1 ; GISEL-NEXT: mov w9, #100 ; =0x64 ; GISEL-NEXT: mov w10, #249 ; =0xf9 ; GISEL-NEXT: lsl w8, w8, w1 ; GISEL-NEXT: b LBB8_2 ; GISEL-NEXT: LBB8_1: ; %loop.latch ; GISEL-NEXT: ; in Loop: Header=BB8_2 Depth=1 ; GISEL-NEXT: subs w9, w9, #1 ; GISEL-NEXT: b.eq LBB8_5 ; GISEL-NEXT: LBB8_2: ; %loop.header ; GISEL-NEXT: ; =>This Inner Loop Header: Depth=1 ; GISEL-NEXT: cmp w1, #7 ; GISEL-NEXT: b.hi LBB8_1 ; GISEL-NEXT: ; %bb.3: ; %loop.header ; GISEL-NEXT: ; in Loop: Header=BB8_2 Depth=1 ; GISEL-NEXT: tst w8, w10 ; GISEL-NEXT: b.eq LBB8_1 ; GISEL-NEXT: ; %bb.4: ; %e0 ; GISEL-NEXT: mov x0, xzr ; GISEL-NEXT: ret ; GISEL-NEXT: LBB8_5: ; GISEL-NEXT: mov x0, #-42 ; =0xffffffffffffffd6 ; GISEL-NEXT: ret entry: br label %loop.header loop.header: %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] switch i32 %param, label %loop.latch [ i32 7, label %e0 i32 6, label %e0 i32 5, label %e0 i32 4, label %e0 i32 3, label %e0 i32 0, label %e0 ] loop.latch: %iv.next = add i32 %iv, 1 %ec = icmp eq i32 %iv.next, 100 br i1 %ec, label %e1, label %loop.header e0: %m = getelementptr i8, ptr %p, i64 20 br label %e1 e1: %res = phi i64 [ 0, %e0 ], [ -42, %loop.latch ] ret i64 %res } define i64 @consecutive_match_before(ptr %p, i32 %param) { ; CHECK-LABEL: consecutive_match_before: ; CHECK: ; %bb.0: ; %entry ; CHECK-NEXT: mov w8, #1 ; =0x1 ; CHECK-NEXT: mov w9, #100 ; =0x64 ; CHECK-NEXT: mov w10, #25 ; =0x19 ; CHECK-NEXT: lsl w8, w8, w1 ; CHECK-NEXT: b LBB9_2 ; CHECK-NEXT: LBB9_1: ; %loop.latch ; CHECK-NEXT: ; in Loop: Header=BB9_2 Depth=1 ; CHECK-NEXT: subs w9, w9, #1 ; CHECK-NEXT: b.eq LBB9_5 ; CHECK-NEXT: LBB9_2: ; %loop.header ; CHECK-NEXT: ; =>This Inner Loop Header: Depth=1 ; CHECK-NEXT: cmp w1, #4 ; CHECK-NEXT: b.hi LBB9_1 ; CHECK-NEXT: ; %bb.3: ; %loop.header ; CHECK-NEXT: ; in Loop: Header=BB9_2 Depth=1 ; CHECK-NEXT: tst w8, w10 ; CHECK-NEXT: b.eq LBB9_1 ; CHECK-NEXT: ; %bb.4: ; %e0 ; CHECK-NEXT: mov x0, xzr ; CHECK-NEXT: ret ; CHECK-NEXT: LBB9_5: ; CHECK-NEXT: mov x0, #-42 ; =0xffffffffffffffd6 ; CHECK-NEXT: ret ; ; GISEL-LABEL: consecutive_match_before: ; GISEL: ; %bb.0: ; %entry ; GISEL-NEXT: mov w8, #1 ; =0x1 ; GISEL-NEXT: mov w9, #100 ; =0x64 ; GISEL-NEXT: mov w10, #25 ; =0x19 ; GISEL-NEXT: lsl w8, w8, w1 ; GISEL-NEXT: b LBB9_2 ; GISEL-NEXT: LBB9_1: ; %loop.latch ; GISEL-NEXT: ; in Loop: Header=BB9_2 Depth=1 ; GISEL-NEXT: subs w9, w9, #1 ; GISEL-NEXT: b.eq LBB9_5 ; GISEL-NEXT: LBB9_2: ; %loop.header ; GISEL-NEXT: ; =>This Inner Loop Header: Depth=1 ; GISEL-NEXT: cmp w1, #4 ; GISEL-NEXT: b.hi LBB9_1 ; GISEL-NEXT: ; %bb.3: ; %loop.header ; GISEL-NEXT: ; in Loop: Header=BB9_2 Depth=1 ; GISEL-NEXT: tst w8, w10 ; GISEL-NEXT: b.eq LBB9_1 ; GISEL-NEXT: ; %bb.4: ; %e0 ; GISEL-NEXT: mov x0, xzr ; GISEL-NEXT: ret ; GISEL-NEXT: LBB9_5: ; GISEL-NEXT: mov x0, #-42 ; =0xffffffffffffffd6 ; GISEL-NEXT: ret entry: br label %loop.header loop.header: %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] switch i32 %param, label %loop.latch [ i32 4, label %e0 i32 3, label %e0 i32 0, label %e0 ] loop.latch: %iv.next = add i32 %iv, 1 %ec = icmp eq i32 %iv.next, 100 br i1 %ec, label %e1, label %loop.header e0: %m = getelementptr i8, ptr %p, i64 20 br label %e1 e1: %res = phi i64 [ 0, %e0 ], [ -42, %loop.latch ] ret i64 %res } define i64 @consecutive_match_after(ptr %p, i32 %param) { ; CHECK-LABEL: consecutive_match_after: ; CHECK: ; %bb.0: ; %entry ; CHECK-NEXT: mov w8, #1 ; =0x1 ; CHECK-NEXT: mov w9, #100 ; =0x64 ; CHECK-NEXT: mov w10, #49 ; =0x31 ; CHECK-NEXT: lsl w8, w8, w1 ; CHECK-NEXT: b LBB10_2 ; CHECK-NEXT: LBB10_1: ; %loop.latch ; CHECK-NEXT: ; in Loop: Header=BB10_2 Depth=1 ; CHECK-NEXT: subs w9, w9, #1 ; CHECK-NEXT: b.eq LBB10_5 ; CHECK-NEXT: LBB10_2: ; %loop.header ; CHECK-NEXT: ; =>This Inner Loop Header: Depth=1 ; CHECK-NEXT: cmp w1, #5 ; CHECK-NEXT: b.hi LBB10_1 ; CHECK-NEXT: ; %bb.3: ; %loop.header ; CHECK-NEXT: ; in Loop: Header=BB10_2 Depth=1 ; CHECK-NEXT: tst w8, w10 ; CHECK-NEXT: b.eq LBB10_1 ; CHECK-NEXT: ; %bb.4: ; %e0 ; CHECK-NEXT: mov x0, xzr ; CHECK-NEXT: ret ; CHECK-NEXT: LBB10_5: ; CHECK-NEXT: mov x0, #-42 ; =0xffffffffffffffd6 ; CHECK-NEXT: ret ; ; GISEL-LABEL: consecutive_match_after: ; GISEL: ; %bb.0: ; %entry ; GISEL-NEXT: mov w8, #1 ; =0x1 ; GISEL-NEXT: mov w9, #100 ; =0x64 ; GISEL-NEXT: mov w10, #49 ; =0x31 ; GISEL-NEXT: lsl w8, w8, w1 ; GISEL-NEXT: b LBB10_2 ; GISEL-NEXT: LBB10_1: ; %loop.latch ; GISEL-NEXT: ; in Loop: Header=BB10_2 Depth=1 ; GISEL-NEXT: subs w9, w9, #1 ; GISEL-NEXT: b.eq LBB10_5 ; GISEL-NEXT: LBB10_2: ; %loop.header ; GISEL-NEXT: ; =>This Inner Loop Header: Depth=1 ; GISEL-NEXT: cmp w1, #5 ; GISEL-NEXT: b.hi LBB10_1 ; GISEL-NEXT: ; %bb.3: ; %loop.header ; GISEL-NEXT: ; in Loop: Header=BB10_2 Depth=1 ; GISEL-NEXT: tst w8, w10 ; GISEL-NEXT: b.eq LBB10_1 ; GISEL-NEXT: ; %bb.4: ; %e0 ; GISEL-NEXT: mov x0, xzr ; GISEL-NEXT: ret ; GISEL-NEXT: LBB10_5: ; GISEL-NEXT: mov x0, #-42 ; =0xffffffffffffffd6 ; GISEL-NEXT: ret entry: br label %loop.header loop.header: %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] switch i32 %param, label %loop.latch [ i32 5, label %e0 i32 4, label %e0 i32 0, label %e0 ] loop.latch: %iv.next = add i32 %iv, 1 %ec = icmp eq i32 %iv.next, 100 br i1 %ec, label %e1, label %loop.header e0: %m = getelementptr i8, ptr %p, i64 20 br label %e1 e1: %res = phi i64 [ 0, %e0 ], [ -42, %loop.latch ] ret i64 %res } define void @merge_with_stores(ptr %A, i16 %v) { ; CHECK-LABEL: merge_with_stores: ; CHECK: ; %bb.0: ; %entry ; CHECK-NEXT: and w8, w1, #0xffff ; CHECK-NEXT: sub w9, w8, #10 ; CHECK-NEXT: cmp w9, #2 ; CHECK-NEXT: b.lo LBB11_4 ; CHECK-NEXT: ; %bb.1: ; %entry ; CHECK-NEXT: cbz w8, LBB11_5 ; CHECK-NEXT: ; %bb.2: ; %entry ; CHECK-NEXT: cmp w8, #2 ; CHECK-NEXT: b.eq LBB11_5 ; CHECK-NEXT: ; %bb.3: ; %default.dst ; CHECK-NEXT: strh wzr, [x0] ; CHECK-NEXT: ret ; CHECK-NEXT: LBB11_4: ; %other.dst ; CHECK-NEXT: mov w8, #1 ; =0x1 ; CHECK-NEXT: strh w8, [x0, #36] ; CHECK-NEXT: LBB11_5: ; %pow2.dst ; CHECK-NEXT: ret ; ; GISEL-LABEL: merge_with_stores: ; GISEL: ; %bb.0: ; %entry ; GISEL-NEXT: and w8, w1, #0xffff ; GISEL-NEXT: sub w9, w8, #10 ; GISEL-NEXT: cmp w9, #1 ; GISEL-NEXT: b.ls LBB11_4 ; GISEL-NEXT: ; %bb.1: ; %entry ; GISEL-NEXT: cbz w8, LBB11_5 ; GISEL-NEXT: ; %bb.2: ; %entry ; GISEL-NEXT: cmp w8, #2 ; GISEL-NEXT: b.eq LBB11_5 ; GISEL-NEXT: ; %bb.3: ; %default.dst ; GISEL-NEXT: strh wzr, [x0] ; GISEL-NEXT: ret ; GISEL-NEXT: LBB11_4: ; %other.dst ; GISEL-NEXT: mov w8, #1 ; =0x1 ; GISEL-NEXT: strh w8, [x0, #36] ; GISEL-NEXT: LBB11_5: ; %pow2.dst ; GISEL-NEXT: ret entry: switch i16 %v, label %default.dst [ i16 10, label %other.dst i16 0, label %pow2.dst i16 2, label %pow2.dst i16 11, label %other.dst ] default.dst: store i16 0, ptr %A, align 8 br label %pow2.dst other.dst: %gep = getelementptr i8, ptr %A, i64 36 store i16 1, ptr %gep, align 8 br label %pow2.dst pow2.dst: ret void }