331 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc --arm-memtransfer-tploop=allow -mtriple=thumbv8.1m.main-none-none-eabi -mattr=+mve.fp -verify-machineinstrs -tail-predication=enabled -o - %s | FileCheck %s3 4define void @test_memcpy(ptr nocapture %x, ptr nocapture readonly %y, i32 %n, i32 %m) {5; CHECK-LABEL: test_memcpy:6; CHECK: @ %bb.0: @ %entry7; CHECK-NEXT: cmp r2, #18; CHECK-NEXT: it lt9; CHECK-NEXT: bxlt lr10; CHECK-NEXT: .LBB0_1: @ %for.body.preheader11; CHECK-NEXT: .save {r4, r5, r6, r7, lr}12; CHECK-NEXT: push {r4, r5, r6, r7, lr}13; CHECK-NEXT: lsl.w r12, r3, #214; CHECK-NEXT: movs r7, #015; CHECK-NEXT: b .LBB0_216; CHECK-NEXT: .LBB0_2: @ %for.body17; CHECK-NEXT: @ =>This Loop Header: Depth=118; CHECK-NEXT: @ Child Loop BB0_4 Depth 219; CHECK-NEXT: adds r4, r1, r720; CHECK-NEXT: adds r5, r0, r721; CHECK-NEXT: wlstp.8 lr, r3, .LBB0_322; CHECK-NEXT: b .LBB0_423; CHECK-NEXT: .LBB0_3: @ %for.body24; CHECK-NEXT: @ in Loop: Header=BB0_2 Depth=125; CHECK-NEXT: add r7, r1226; CHECK-NEXT: subs r2, #127; CHECK-NEXT: beq .LBB0_528; CHECK-NEXT: b .LBB0_229; CHECK-NEXT: .LBB0_4: @ Parent Loop BB0_2 Depth=130; CHECK-NEXT: @ => This Inner Loop Header: Depth=231; CHECK-NEXT: vldrb.u8 q0, [r4], #1632; CHECK-NEXT: vstrb.8 q0, [r5], #1633; CHECK-NEXT: letp lr, .LBB0_434; CHECK-NEXT: b .LBB0_335; CHECK-NEXT: .LBB0_5:36; CHECK-NEXT: pop.w {r4, r5, r6, r7, lr}37; CHECK-NEXT: bx lr38entry:39 %cmp8 = icmp sgt i32 %n, 040 br i1 %cmp8, label %for.body, label %for.cond.cleanup41 42for.cond.cleanup: ; preds = %for.body, %entry43 ret void44 45for.body: ; preds = %entry, %for.body46 %i.011 = phi i32 [ %inc, %for.body ], [ 0, %entry ]47 %x.addr.010 = phi ptr [ %add.ptr, %for.body ], [ %x, %entry ]48 %y.addr.09 = phi ptr [ %add.ptr1, %for.body ], [ %y, %entry ]49 tail call void @llvm.memcpy.p0.p0.i32(ptr align 4 %x.addr.010, ptr align 4 %y.addr.09, i32 %m, i1 false)50 %add.ptr = getelementptr inbounds i32, ptr %x.addr.010, i32 %m51 %add.ptr1 = getelementptr inbounds i32, ptr %y.addr.09, i32 %m52 %inc = add nuw nsw i32 %i.011, 153 %exitcond.not = icmp eq i32 %inc, %n54 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body55}56 57define void @test_memset(ptr nocapture %x, i32 %n, i32 %m) {58; CHECK-LABEL: test_memset:59; CHECK: @ %bb.0: @ %entry60; CHECK-NEXT: cmp r1, #161; CHECK-NEXT: it lt62; CHECK-NEXT: bxlt lr63; CHECK-NEXT: .LBB1_1: @ %for.body.preheader64; CHECK-NEXT: .save {r4, lr}65; CHECK-NEXT: push {r4, lr}66; CHECK-NEXT: lsl.w r12, r2, #267; CHECK-NEXT: vmov.i32 q0, #0x068; CHECK-NEXT: b .LBB1_269; CHECK-NEXT: .LBB1_2: @ %for.body70; CHECK-NEXT: @ =>This Loop Header: Depth=171; CHECK-NEXT: @ Child Loop BB1_4 Depth 272; CHECK-NEXT: mov r4, r073; CHECK-NEXT: wlstp.8 lr, r2, .LBB1_374; CHECK-NEXT: b .LBB1_475; CHECK-NEXT: .LBB1_3: @ %for.body76; CHECK-NEXT: @ in Loop: Header=BB1_2 Depth=177; CHECK-NEXT: add r0, r1278; CHECK-NEXT: subs r1, #179; CHECK-NEXT: beq .LBB1_580; CHECK-NEXT: b .LBB1_281; CHECK-NEXT: .LBB1_4: @ Parent Loop BB1_2 Depth=182; CHECK-NEXT: @ => This Inner Loop Header: Depth=283; CHECK-NEXT: vstrb.8 q0, [r4], #1684; CHECK-NEXT: letp lr, .LBB1_485; CHECK-NEXT: b .LBB1_386; CHECK-NEXT: .LBB1_5:87; CHECK-NEXT: pop.w {r4, lr}88; CHECK-NEXT: bx lr89entry:90 %cmp5 = icmp sgt i32 %n, 091 br i1 %cmp5, label %for.body, label %for.cond.cleanup92 93for.cond.cleanup: ; preds = %for.body, %entry94 ret void95 96for.body: ; preds = %entry, %for.body97 %i.07 = phi i32 [ %inc, %for.body ], [ 0, %entry ]98 %x.addr.06 = phi ptr [ %add.ptr, %for.body ], [ %x, %entry ]99 tail call void @llvm.memset.p0.i32(ptr align 4 %x.addr.06, i8 0, i32 %m, i1 false)100 %add.ptr = getelementptr inbounds i32, ptr %x.addr.06, i32 %m101 %inc = add nuw nsw i32 %i.07, 1102 %exitcond.not = icmp eq i32 %inc, %n103 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body104}105 106define void @test_memmove(ptr nocapture %x, ptr nocapture readonly %y, i32 %n, i32 %m) {107; CHECK-LABEL: test_memmove:108; CHECK: @ %bb.0: @ %entry109; CHECK-NEXT: cmp r2, #1110; CHECK-NEXT: it lt111; CHECK-NEXT: bxlt lr112; CHECK-NEXT: .LBB2_1: @ %for.body.preheader113; CHECK-NEXT: .save {r4, r5, r6, r7, r8, r9, lr}114; CHECK-NEXT: push.w {r4, r5, r6, r7, r8, r9, lr}115; CHECK-NEXT: .pad #4116; CHECK-NEXT: sub sp, #4117; CHECK-NEXT: mov r8, r3118; CHECK-NEXT: mov r5, r2119; CHECK-NEXT: mov r9, r1120; CHECK-NEXT: mov r7, r0121; CHECK-NEXT: lsls r4, r3, #2122; CHECK-NEXT: movs r6, #0123; CHECK-NEXT: .LBB2_2: @ %for.body124; CHECK-NEXT: @ =>This Inner Loop Header: Depth=1125; CHECK-NEXT: adds r0, r7, r6126; CHECK-NEXT: add.w r1, r9, r6127; CHECK-NEXT: mov r2, r8128; CHECK-NEXT: bl __aeabi_memmove4129; CHECK-NEXT: add r6, r4130; CHECK-NEXT: subs r5, #1131; CHECK-NEXT: bne .LBB2_2132; CHECK-NEXT: @ %bb.3:133; CHECK-NEXT: add sp, #4134; CHECK-NEXT: pop.w {r4, r5, r6, r7, r8, r9, lr}135; CHECK-NEXT: bx lr136entry:137 %cmp8 = icmp sgt i32 %n, 0138 br i1 %cmp8, label %for.body, label %for.cond.cleanup139 140for.cond.cleanup: ; preds = %for.body, %entry141 ret void142 143for.body: ; preds = %entry, %for.body144 %i.011 = phi i32 [ %inc, %for.body ], [ 0, %entry ]145 %x.addr.010 = phi ptr [ %add.ptr, %for.body ], [ %x, %entry ]146 %y.addr.09 = phi ptr [ %add.ptr1, %for.body ], [ %y, %entry ]147 tail call void @llvm.memmove.p0.p0.i32(ptr align 4 %x.addr.010, ptr align 4 %y.addr.09, i32 %m, i1 false)148 %add.ptr = getelementptr inbounds i32, ptr %x.addr.010, i32 %m149 %add.ptr1 = getelementptr inbounds i32, ptr %y.addr.09, i32 %m150 %inc = add nuw nsw i32 %i.011, 1151 %exitcond.not = icmp eq i32 %inc, %n152 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body153}154 155 156define void @test_memcpy16(ptr nocapture %x, ptr nocapture readonly %y, i32 %n) {157; CHECK-LABEL: test_memcpy16:158; CHECK: @ %bb.0: @ %entry159; CHECK-NEXT: .save {r4, lr}160; CHECK-NEXT: push {r4, lr}161; CHECK-NEXT: cmp r2, #1162; CHECK-NEXT: it lt163; CHECK-NEXT: poplt {r4, pc}164; CHECK-NEXT: .LBB3_1: @ %for.body.preheader165; CHECK-NEXT: dls lr, r2166; CHECK-NEXT: .LBB3_2: @ %for.body167; CHECK-NEXT: @ =>This Inner Loop Header: Depth=1168; CHECK-NEXT: ldm.w r1, {r2, r3, r12}169; CHECK-NEXT: ldr r4, [r1, #12]170; CHECK-NEXT: adds r1, #64171; CHECK-NEXT: stm.w r0, {r2, r3, r12}172; CHECK-NEXT: str r4, [r0, #12]173; CHECK-NEXT: adds r0, #64174; CHECK-NEXT: le lr, .LBB3_2175; CHECK-NEXT: @ %bb.3: @ %for.cond.cleanup176; CHECK-NEXT: pop {r4, pc}177entry:178 %cmp6 = icmp sgt i32 %n, 0179 br i1 %cmp6, label %for.body, label %for.cond.cleanup180 181for.cond.cleanup: ; preds = %for.body, %entry182 ret void183 184for.body: ; preds = %entry, %for.body185 %i.09 = phi i32 [ %inc, %for.body ], [ 0, %entry ]186 %x.addr.08 = phi ptr [ %add.ptr, %for.body ], [ %x, %entry ]187 %y.addr.07 = phi ptr [ %add.ptr1, %for.body ], [ %y, %entry ]188 tail call void @llvm.memcpy.p0.p0.i32(ptr nonnull align 4 dereferenceable(16) %x.addr.08, ptr nonnull align 4 dereferenceable(16) %y.addr.07, i32 16, i1 false)189 %add.ptr = getelementptr inbounds i32, ptr %x.addr.08, i32 16190 %add.ptr1 = getelementptr inbounds i32, ptr %y.addr.07, i32 16191 %inc = add nuw nsw i32 %i.09, 1192 %exitcond.not = icmp eq i32 %inc, %n193 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body194}195 196define void @test_memset16(ptr nocapture %x, i32 %n) {197; CHECK-LABEL: test_memset16:198; CHECK: @ %bb.0: @ %entry199; CHECK-NEXT: .save {r7, lr}200; CHECK-NEXT: push {r7, lr}201; CHECK-NEXT: cmp r1, #1202; CHECK-NEXT: it lt203; CHECK-NEXT: poplt {r7, pc}204; CHECK-NEXT: .LBB4_1: @ %for.body.preheader205; CHECK-NEXT: dls lr, r1206; CHECK-NEXT: movs r1, #0207; CHECK-NEXT: .LBB4_2: @ %for.body208; CHECK-NEXT: @ =>This Inner Loop Header: Depth=1209; CHECK-NEXT: strd r1, r1, [r0]210; CHECK-NEXT: strd r1, r1, [r0, #8]211; CHECK-NEXT: adds r0, #64212; CHECK-NEXT: le lr, .LBB4_2213; CHECK-NEXT: @ %bb.3: @ %for.cond.cleanup214; CHECK-NEXT: pop {r7, pc}215entry:216 %cmp4 = icmp sgt i32 %n, 0217 br i1 %cmp4, label %for.body, label %for.cond.cleanup218 219for.cond.cleanup: ; preds = %for.body, %entry220 ret void221 222for.body: ; preds = %entry, %for.body223 %i.06 = phi i32 [ %inc, %for.body ], [ 0, %entry ]224 %x.addr.05 = phi ptr [ %add.ptr, %for.body ], [ %x, %entry ]225 tail call void @llvm.memset.p0.i32(ptr nonnull align 4 dereferenceable(16) %x.addr.05, i8 0, i32 16, i1 false)226 %add.ptr = getelementptr inbounds i32, ptr %x.addr.05, i32 16227 %inc = add nuw nsw i32 %i.06, 1228 %exitcond.not = icmp eq i32 %inc, %n229 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body230}231 232define void @test_memmove16(ptr nocapture %x, ptr nocapture readonly %y, i32 %n) {233; CHECK-LABEL: test_memmove16:234; CHECK: @ %bb.0: @ %entry235; CHECK-NEXT: .save {r4, lr}236; CHECK-NEXT: push {r4, lr}237; CHECK-NEXT: cmp r2, #1238; CHECK-NEXT: it lt239; CHECK-NEXT: poplt {r4, pc}240; CHECK-NEXT: .LBB5_1: @ %for.body.preheader241; CHECK-NEXT: dls lr, r2242; CHECK-NEXT: .LBB5_2: @ %for.body243; CHECK-NEXT: @ =>This Inner Loop Header: Depth=1244; CHECK-NEXT: ldm.w r1, {r2, r3, r12}245; CHECK-NEXT: ldr r4, [r1, #12]246; CHECK-NEXT: adds r1, #64247; CHECK-NEXT: stm.w r0, {r2, r3, r12}248; CHECK-NEXT: str r4, [r0, #12]249; CHECK-NEXT: adds r0, #64250; CHECK-NEXT: le lr, .LBB5_2251; CHECK-NEXT: @ %bb.3: @ %for.cond.cleanup252; CHECK-NEXT: pop {r4, pc}253entry:254 %cmp6 = icmp sgt i32 %n, 0255 br i1 %cmp6, label %for.body, label %for.cond.cleanup256 257for.cond.cleanup: ; preds = %for.body, %entry258 ret void259 260for.body: ; preds = %entry, %for.body261 %i.09 = phi i32 [ %inc, %for.body ], [ 0, %entry ]262 %x.addr.08 = phi ptr [ %add.ptr, %for.body ], [ %x, %entry ]263 %y.addr.07 = phi ptr [ %add.ptr1, %for.body ], [ %y, %entry ]264 tail call void @llvm.memmove.p0.p0.i32(ptr nonnull align 4 dereferenceable(16) %x.addr.08, ptr nonnull align 4 dereferenceable(16) %y.addr.07, i32 16, i1 false)265 %add.ptr = getelementptr inbounds i32, ptr %x.addr.08, i32 16266 %add.ptr1 = getelementptr inbounds i32, ptr %y.addr.07, i32 16267 %inc = add nuw nsw i32 %i.09, 1268 %exitcond.not = icmp eq i32 %inc, %n269 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body270}271 272define void @test_memset_preheader(ptr %x, ptr %y, i32 %n) {273; CHECK-LABEL: test_memset_preheader:274; CHECK: @ %bb.0: @ %entry275; CHECK-NEXT: .save {r4, lr}276; CHECK-NEXT: push {r4, lr}277; CHECK-NEXT: cbz r2, .LBB6_5278; CHECK-NEXT: @ %bb.1: @ %prehead279; CHECK-NEXT: vmov.i32 q0, #0x0280; CHECK-NEXT: mov r4, r0281; CHECK-NEXT: wlstp.8 lr, r2, .LBB6_3282; CHECK-NEXT: .LBB6_2: @ =>This Inner Loop Header: Depth=1283; CHECK-NEXT: vstrb.8 q0, [r4], #16284; CHECK-NEXT: letp lr, .LBB6_2285; CHECK-NEXT: .LBB6_3: @ %prehead286; CHECK-NEXT: dls lr, r2287; CHECK-NEXT: mov r3, r0288; CHECK-NEXT: .LBB6_4: @ %for.body289; CHECK-NEXT: @ =>This Inner Loop Header: Depth=1290; CHECK-NEXT: ldrb r4, [r3], #1291; CHECK-NEXT: strb r4, [r1], #1292; CHECK-NEXT: le lr, .LBB6_4293; CHECK-NEXT: .LBB6_5: @ %for.cond.cleanup294; CHECK-NEXT: vmov.i32 q0, #0x0295; CHECK-NEXT: wlstp.8 lr, r2, .LBB6_7296; CHECK-NEXT: .LBB6_6: @ =>This Inner Loop Header: Depth=1297; CHECK-NEXT: vstrb.8 q0, [r0], #16298; CHECK-NEXT: letp lr, .LBB6_6299; CHECK-NEXT: .LBB6_7: @ %for.cond.cleanup300; CHECK-NEXT: pop {r4, pc}301entry:302 %cmp6 = icmp ne i32 %n, 0303 br i1 %cmp6, label %prehead, label %for.cond.cleanup304 305prehead:306 call void @llvm.memset.p0.i32(ptr %x, i8 0, i32 %n, i1 false)307 br label %for.body308 309for.body: ; preds = %entry, %for.body310 %i.09 = phi i32 [ %inc, %for.body ], [ 0, %prehead ]311 %x.addr.08 = phi ptr [ %add.ptr, %for.body ], [ %x, %prehead ]312 %y.addr.07 = phi ptr [ %add.ptr1, %for.body ], [ %y, %prehead ]313 %add.ptr = getelementptr inbounds i8, ptr %x.addr.08, i32 1314 %add.ptr1 = getelementptr inbounds i8, ptr %y.addr.07, i32 1315 %l = load i8, ptr %x.addr.08316 store i8 %l, ptr %y.addr.07317 %inc = add nuw nsw i32 %i.09, 1318 %exitcond.not = icmp eq i32 %inc, %n319 br i1 %exitcond.not, label %for.cond.cleanup, label %for.body320 321for.cond.cleanup: ; preds = %for.body, %entry322 call void @llvm.memset.p0.i32(ptr %x, i8 0, i32 %n, i1 false)323 ret void324}325 326 327 328declare void @llvm.memcpy.p0.p0.i32(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i32, i1 immarg)329declare void @llvm.memset.p0.i32(ptr nocapture writeonly, i8, i32, i1 immarg)330declare void @llvm.memmove.p0.p0.i32(ptr nocapture writeonly, ptr nocapture readonly, i32, i1 immarg)331