1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple thumbv6m-none-eabi -o - %s | FileCheck %s --check-prefix=CHECK-V6M 3; RUN: llc -mtriple thumbv7m-none-eabi -o - %s | FileCheck %s --check-prefix=CHECK-V7M 4; RUN: llc -mtriple thumbv8.1m.main-none-eabi -mattr=+mve,+lob -o - %s | FileCheck %s --check-prefix=CHECK-V81M 5; RUN: llc -mtriple armv7a-none-eabi -o - %s | FileCheck %s --check-prefix=CHECK-V7A 6 7define i32 @test_lshr(ptr nocapture %x, ptr nocapture readonly %y, i32 %n) { 8; CHECK-V6M-LABEL: test_lshr: 9; CHECK-V6M: @ %bb.0: @ %entry 10; CHECK-V6M-NEXT: lsrs r2, r2, #2 11; CHECK-V6M-NEXT: beq .LBB0_2 12; CHECK-V6M-NEXT: .LBB0_1: @ %while.body 13; CHECK-V6M-NEXT: @ =>This Inner Loop Header: Depth=1 14; CHECK-V6M-NEXT: ldm r1!, {r3} 15; CHECK-V6M-NEXT: lsls r3, r3, #1 16; CHECK-V6M-NEXT: stm r0!, {r3} 17; CHECK-V6M-NEXT: subs r2, r2, #1 18; CHECK-V6M-NEXT: bne .LBB0_1 19; CHECK-V6M-NEXT: .LBB0_2: @ %while.end 20; CHECK-V6M-NEXT: movs r0, #0 21; CHECK-V6M-NEXT: bx lr 22; 23; CHECK-V7M-LABEL: test_lshr: 24; CHECK-V7M: @ %bb.0: @ %entry 25; CHECK-V7M-NEXT: lsrs r2, r2, #2 26; CHECK-V7M-NEXT: beq .LBB0_3 27; CHECK-V7M-NEXT: @ %bb.1: @ %while.body.preheader 28; CHECK-V7M-NEXT: subs r1, #4 29; CHECK-V7M-NEXT: subs r0, #4 30; CHECK-V7M-NEXT: .LBB0_2: @ %while.body 31; CHECK-V7M-NEXT: @ =>This Inner Loop Header: Depth=1 32; CHECK-V7M-NEXT: ldr r3, [r1, #4]! 33; CHECK-V7M-NEXT: subs r2, #1 34; CHECK-V7M-NEXT: lsl.w r3, r3, #1 35; CHECK-V7M-NEXT: str r3, [r0, #4]! 36; CHECK-V7M-NEXT: bne .LBB0_2 37; CHECK-V7M-NEXT: .LBB0_3: @ %while.end 38; CHECK-V7M-NEXT: movs r0, #0 39; CHECK-V7M-NEXT: bx lr 40; 41; CHECK-V81M-LABEL: test_lshr: 42; CHECK-V81M: @ %bb.0: @ %entry 43; CHECK-V81M-NEXT: .save {r7, lr} 44; CHECK-V81M-NEXT: push {r7, lr} 45; CHECK-V81M-NEXT: lsrs r2, r2, #2 46; CHECK-V81M-NEXT: wls lr, r2, .LBB0_2 47; CHECK-V81M-NEXT: .LBB0_1: @ %while.body 48; CHECK-V81M-NEXT: @ =>This Inner Loop Header: Depth=1 49; CHECK-V81M-NEXT: ldr r2, [r1], #4 50; CHECK-V81M-NEXT: lsls r2, r2, #1 51; CHECK-V81M-NEXT: str r2, [r0], #4 52; CHECK-V81M-NEXT: le lr, .LBB0_1 53; CHECK-V81M-NEXT: .LBB0_2: @ %while.end 54; CHECK-V81M-NEXT: movs r0, #0 55; CHECK-V81M-NEXT: pop {r7, pc} 56; 57; CHECK-V7A-LABEL: test_lshr: 58; CHECK-V7A: @ %bb.0: @ %entry 59; CHECK-V7A-NEXT: lsrs r2, r2, #2 60; CHECK-V7A-NEXT: beq .LBB0_2 61; CHECK-V7A-NEXT: .LBB0_1: @ %while.body 62; CHECK-V7A-NEXT: @ =>This Inner Loop Header: Depth=1 63; CHECK-V7A-NEXT: ldr r3, [r1], #4 64; CHECK-V7A-NEXT: subs r2, r2, #1 65; CHECK-V7A-NEXT: lsl r3, r3, #1 66; CHECK-V7A-NEXT: str r3, [r0], #4 67; CHECK-V7A-NEXT: bne .LBB0_1 68; CHECK-V7A-NEXT: .LBB0_2: @ %while.end 69; CHECK-V7A-NEXT: mov r0, #0 70; CHECK-V7A-NEXT: bx lr 71entry: 72 %shr = lshr i32 %n, 2 73 %tobool.not4 = icmp eq i32 %shr, 0 74 br i1 %tobool.not4, label %while.end, label %while.body 75 76while.body: ; preds = %entry, %while.body 77 %c.07 = phi i32 [ %dec, %while.body ], [ %shr, %entry ] 78 %x.addr.06 = phi ptr [ %incdec.ptr1, %while.body ], [ %x, %entry ] 79 %y.addr.05 = phi ptr [ %incdec.ptr, %while.body ], [ %y, %entry ] 80 %incdec.ptr = getelementptr inbounds i32, ptr %y.addr.05, i32 1 81 %0 = load i32, ptr %y.addr.05, align 4 82 %mul = shl nsw i32 %0, 1 83 %incdec.ptr1 = getelementptr inbounds i32, ptr %x.addr.06, i32 1 84 store i32 %mul, ptr %x.addr.06, align 4 85 %dec = add nsw i32 %c.07, -1 86 %tobool.not = icmp eq i32 %dec, 0 87 br i1 %tobool.not, label %while.end, label %while.body 88 89while.end: ; preds = %while.body, %entry 90 ret i32 0 91} 92 93define i32 @test_lshr2(ptr nocapture %x, ptr nocapture readonly %y, i32 %n) { 94; CHECK-V6M-LABEL: test_lshr2: 95; CHECK-V6M: @ %bb.0: @ %entry 96; CHECK-V6M-NEXT: lsrs r2, r2, #2 97; CHECK-V6M-NEXT: beq .LBB1_2 98; CHECK-V6M-NEXT: .LBB1_1: @ %while.body 99; CHECK-V6M-NEXT: @ =>This Inner Loop Header: Depth=1 100; CHECK-V6M-NEXT: ldm r1!, {r3} 101; CHECK-V6M-NEXT: lsls r3, r3, #1 102; CHECK-V6M-NEXT: stm r0!, {r3} 103; CHECK-V6M-NEXT: subs r2, r2, #1 104; CHECK-V6M-NEXT: bne .LBB1_1 105; CHECK-V6M-NEXT: .LBB1_2: @ %while.end 106; CHECK-V6M-NEXT: movs r0, #0 107; CHECK-V6M-NEXT: bx lr 108; 109; CHECK-V7M-LABEL: test_lshr2: 110; CHECK-V7M: @ %bb.0: @ %entry 111; CHECK-V7M-NEXT: lsrs r2, r2, #2 112; CHECK-V7M-NEXT: beq .LBB1_3 113; CHECK-V7M-NEXT: @ %bb.1: @ %while.body.preheader 114; CHECK-V7M-NEXT: subs r1, #4 115; CHECK-V7M-NEXT: subs r0, #4 116; CHECK-V7M-NEXT: .LBB1_2: @ %while.body 117; CHECK-V7M-NEXT: @ =>This Inner Loop Header: Depth=1 118; CHECK-V7M-NEXT: ldr r3, [r1, #4]! 119; CHECK-V7M-NEXT: subs r2, #1 120; CHECK-V7M-NEXT: lsl.w r3, r3, #1 121; CHECK-V7M-NEXT: str r3, [r0, #4]! 122; CHECK-V7M-NEXT: bne .LBB1_2 123; CHECK-V7M-NEXT: .LBB1_3: @ %while.end 124; CHECK-V7M-NEXT: movs r0, #0 125; CHECK-V7M-NEXT: bx lr 126; 127; CHECK-V81M-LABEL: test_lshr2: 128; CHECK-V81M: @ %bb.0: @ %entry 129; CHECK-V81M-NEXT: .save {r7, lr} 130; CHECK-V81M-NEXT: push {r7, lr} 131; CHECK-V81M-NEXT: lsrs r2, r2, #2 132; CHECK-V81M-NEXT: wls lr, r2, .LBB1_2 133; CHECK-V81M-NEXT: .LBB1_1: @ %while.body 134; CHECK-V81M-NEXT: @ =>This Inner Loop Header: Depth=1 135; CHECK-V81M-NEXT: ldr r2, [r1], #4 136; CHECK-V81M-NEXT: lsls r2, r2, #1 137; CHECK-V81M-NEXT: str r2, [r0], #4 138; CHECK-V81M-NEXT: le lr, .LBB1_1 139; CHECK-V81M-NEXT: .LBB1_2: @ %while.end 140; CHECK-V81M-NEXT: movs r0, #0 141; CHECK-V81M-NEXT: pop {r7, pc} 142; 143; CHECK-V7A-LABEL: test_lshr2: 144; CHECK-V7A: @ %bb.0: @ %entry 145; CHECK-V7A-NEXT: lsrs r2, r2, #2 146; CHECK-V7A-NEXT: beq .LBB1_2 147; CHECK-V7A-NEXT: .LBB1_1: @ %while.body 148; CHECK-V7A-NEXT: @ =>This Inner Loop Header: Depth=1 149; CHECK-V7A-NEXT: ldr r3, [r1], #4 150; CHECK-V7A-NEXT: subs r2, r2, #1 151; CHECK-V7A-NEXT: lsl r3, r3, #1 152; CHECK-V7A-NEXT: str r3, [r0], #4 153; CHECK-V7A-NEXT: bne .LBB1_1 154; CHECK-V7A-NEXT: .LBB1_2: @ %while.end 155; CHECK-V7A-NEXT: mov r0, #0 156; CHECK-V7A-NEXT: bx lr 157entry: 158 %tobool.not4 = icmp ult i32 %n, 4 159 br i1 %tobool.not4, label %while.end, label %while.body.preheader 160 161while.body.preheader: ; preds = %entry 162 %shr = lshr i32 %n, 2 163 br label %while.body 164 165while.body: ; preds = %while.body.preheader, %while.body 166 %c.07 = phi i32 [ %dec, %while.body ], [ %shr, %while.body.preheader ] 167 %x.addr.06 = phi ptr [ %incdec.ptr1, %while.body ], [ %x, %while.body.preheader ] 168 %y.addr.05 = phi ptr [ %incdec.ptr, %while.body ], [ %y, %while.body.preheader ] 169 %incdec.ptr = getelementptr inbounds i32, ptr %y.addr.05, i32 1 170 %0 = load i32, ptr %y.addr.05, align 4 171 %mul = shl nsw i32 %0, 1 172 %incdec.ptr1 = getelementptr inbounds i32, ptr %x.addr.06, i32 1 173 store i32 %mul, ptr %x.addr.06, align 4 174 %dec = add nsw i32 %c.07, -1 175 %tobool.not = icmp eq i32 %dec, 0 176 br i1 %tobool.not, label %while.end, label %while.body 177 178while.end: ; preds = %while.body, %entry 179 ret i32 0 180} 181 182