brintos

brintos / llvm-project-archived public Read only

0
0
Text · 10.7 KiB · 037b272 Raw
301 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -mtriple=thumbv8.1m.main -mattr=+lob --verify-machineinstrs %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-NOMVE3; RUN: llc -mtriple=thumbv8.1m.main -mattr=+lob,+mve --verify-machineinstrs %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-MVE4 5; Check that loop strength reduction understands that it can fold a sub into an6; le instruction and reduces the cost appropriately, causing it to do this no7; matter the preferred addressing mode.8 9define void @test(ptr %dst, i32 %n) {10; CHECK-NOMVE-LABEL: test:11; CHECK-NOMVE:       @ %bb.0: @ %entry12; CHECK-NOMVE-NEXT:    push {r7, lr}13; CHECK-NOMVE-NEXT:    add.w r0, r0, r1, lsl #114; CHECK-NOMVE-NEXT:    movs r2, #015; CHECK-NOMVE-NEXT:    sub.w r12, r0, #216; CHECK-NOMVE-NEXT:    movs r3, #017; CHECK-NOMVE-NEXT:  .LBB0_1: @ %outer_loop18; CHECK-NOMVE-NEXT:    @ =>This Loop Header: Depth=119; CHECK-NOMVE-NEXT:    @ Child Loop BB0_2 Depth 220; CHECK-NOMVE-NEXT:    dls lr, r121; CHECK-NOMVE-NEXT:    mov r0, r1222; CHECK-NOMVE-NEXT:  .LBB0_2: @ %inner_loop23; CHECK-NOMVE-NEXT:    @ Parent Loop BB0_1 Depth=124; CHECK-NOMVE-NEXT:    @ => This Inner Loop Header: Depth=225; CHECK-NOMVE-NEXT:    strh r2, [r0, #2]!26; CHECK-NOMVE-NEXT:    le lr, .LBB0_227; CHECK-NOMVE-NEXT:  @ %bb.3: @ %outer_loop_end28; CHECK-NOMVE-NEXT:    @ in Loop: Header=BB0_1 Depth=129; CHECK-NOMVE-NEXT:    adds r3, #130; CHECK-NOMVE-NEXT:    cmp r3, r131; CHECK-NOMVE-NEXT:    it eq32; CHECK-NOMVE-NEXT:    popeq {r7, pc}33; CHECK-NOMVE-NEXT:    b .LBB0_134;35; CHECK-MVE-LABEL: test:36; CHECK-MVE:       @ %bb.0: @ %entry37; CHECK-MVE-NEXT:    push {r7, lr}38; CHECK-MVE-NEXT:    add.w r12, r0, r1, lsl #139; CHECK-MVE-NEXT:    movs r2, #040; CHECK-MVE-NEXT:    movs r3, #041; CHECK-MVE-NEXT:  .LBB0_1: @ %outer_loop42; CHECK-MVE-NEXT:    @ =>This Loop Header: Depth=143; CHECK-MVE-NEXT:    @ Child Loop BB0_2 Depth 244; CHECK-MVE-NEXT:    dls lr, r145; CHECK-MVE-NEXT:    mov r0, r1246; CHECK-MVE-NEXT:  .LBB0_2: @ %inner_loop47; CHECK-MVE-NEXT:    @ Parent Loop BB0_1 Depth=148; CHECK-MVE-NEXT:    @ => This Inner Loop Header: Depth=249; CHECK-MVE-NEXT:    strh r2, [r0], #250; CHECK-MVE-NEXT:    le lr, .LBB0_251; CHECK-MVE-NEXT:  @ %bb.3: @ %outer_loop_end52; CHECK-MVE-NEXT:    @ in Loop: Header=BB0_1 Depth=153; CHECK-MVE-NEXT:    adds r3, #154; CHECK-MVE-NEXT:    cmp r3, r155; CHECK-MVE-NEXT:    it eq56; CHECK-MVE-NEXT:    popeq {r7, pc}57; CHECK-MVE-NEXT:    b .LBB0_158entry:59  br label %outer_loop60 61outer_loop:62  %idx_outer = phi i32 [ %idx_outer.inc, %outer_loop_end ], [ 0, %entry ]63  br label %inner_loop64 65inner_loop:66  %idx_inner = phi i32 [ 0, %outer_loop ], [ %idx_inner.inc, %inner_loop ]67  %add = add i32 %idx_inner, %n68  %gep = getelementptr inbounds i16, ptr %dst, i32 %add69  store i16 0, ptr %gep, align 270  %idx_inner.inc = add nuw nsw i32 %idx_inner, 171  %cond_inner = icmp eq i32 %idx_inner.inc, %n72  br i1 %cond_inner, label %outer_loop_end, label %inner_loop73 74outer_loop_end:75  %idx_outer.inc = add nuw i32 %idx_outer, 176  %cond_outer = icmp eq i32 %idx_outer.inc, %n77  br i1 %cond_outer, label %exit, label %outer_loop78 79exit:80  ret void81}82 83define void @test_optsize(ptr %dst, i32 %n) optsize {84; CHECK-LABEL: test_optsize:85; CHECK:       @ %bb.0: @ %entry86; CHECK-NEXT:    push {r7, lr}87; CHECK-NEXT:    add.w r12, r0, r1, lsl #188; CHECK-NEXT:    movs r2, #089; CHECK-NEXT:    movs r3, #090; CHECK-NEXT:  .LBB1_1: @ %outer_loop91; CHECK-NEXT:    @ =>This Loop Header: Depth=192; CHECK-NEXT:    @ Child Loop BB1_2 Depth 293; CHECK-NEXT:    dls lr, r194; CHECK-NEXT:    mov r0, r1295; CHECK-NEXT:  .LBB1_2: @ %inner_loop96; CHECK-NEXT:    @ Parent Loop BB1_1 Depth=197; CHECK-NEXT:    @ => This Inner Loop Header: Depth=298; CHECK-NEXT:    strh r2, [r0], #299; CHECK-NEXT:    le lr, .LBB1_2100; CHECK-NEXT:  @ %bb.3: @ %outer_loop_end101; CHECK-NEXT:    @ in Loop: Header=BB1_1 Depth=1102; CHECK-NEXT:    adds r3, #1103; CHECK-NEXT:    cmp r3, r1104; CHECK-NEXT:    it eq105; CHECK-NEXT:    popeq {r7, pc}106; CHECK-NEXT:    b .LBB1_1107entry:108  br label %outer_loop109 110outer_loop:111  %idx_outer = phi i32 [ %idx_outer.inc, %outer_loop_end ], [ 0, %entry ]112  br label %inner_loop113 114inner_loop:115  %idx_inner = phi i32 [ 0, %outer_loop ], [ %idx_inner.inc, %inner_loop ]116  %add = add i32 %idx_inner, %n117  %gep = getelementptr inbounds i16, ptr %dst, i32 %add118  store i16 0, ptr %gep, align 2119  %idx_inner.inc = add nuw nsw i32 %idx_inner, 1120  %cond_inner = icmp eq i32 %idx_inner.inc, %n121  br i1 %cond_inner, label %outer_loop_end, label %inner_loop122 123outer_loop_end:124  %idx_outer.inc = add nuw i32 %idx_outer, 1125  %cond_outer = icmp eq i32 %idx_outer.inc, %n126  br i1 %cond_outer, label %exit, label %outer_loop127 128exit:129  ret void130}131 132; Check that when we can't use LE we don't discount the cost of a sub133; instruction, so we only get it when postincrement is the preferred addressing134; mode (i.e. when we have mve).135 136declare void @otherfn()137 138define void @test_no_le(ptr %dst, i32 %n) {139; CHECK-NOMVE-LABEL: test_no_le:140; CHECK-NOMVE:       @ %bb.0: @ %entry141; CHECK-NOMVE-NEXT:    push.w {r4, r5, r6, r7, r8, lr}142; CHECK-NOMVE-NEXT:    add.w r5, r0, r1, lsl #1143; CHECK-NOMVE-NEXT:    mov r4, r1144; CHECK-NOMVE-NEXT:    movs r6, #0145; CHECK-NOMVE-NEXT:    mov.w r8, #0146; CHECK-NOMVE-NEXT:  .LBB2_1: @ %outer_loop147; CHECK-NOMVE-NEXT:    @ =>This Loop Header: Depth=1148; CHECK-NOMVE-NEXT:    @ Child Loop BB2_2 Depth 2149; CHECK-NOMVE-NEXT:    movs r7, #0150; CHECK-NOMVE-NEXT:  .LBB2_2: @ %inner_loop151; CHECK-NOMVE-NEXT:    @ Parent Loop BB2_1 Depth=1152; CHECK-NOMVE-NEXT:    @ => This Inner Loop Header: Depth=2153; CHECK-NOMVE-NEXT:    bl otherfn154; CHECK-NOMVE-NEXT:    strh.w r6, [r5, r7, lsl #1]155; CHECK-NOMVE-NEXT:    adds r7, #1156; CHECK-NOMVE-NEXT:    cmp r4, r7157; CHECK-NOMVE-NEXT:    bne .LBB2_2158; CHECK-NOMVE-NEXT:  @ %bb.3: @ %outer_loop_end159; CHECK-NOMVE-NEXT:    @ in Loop: Header=BB2_1 Depth=1160; CHECK-NOMVE-NEXT:    add.w r8, r8, #1161; CHECK-NOMVE-NEXT:    cmp r8, r4162; CHECK-NOMVE-NEXT:    bne .LBB2_1163; CHECK-NOMVE-NEXT:  @ %bb.4: @ %exit164; CHECK-NOMVE-NEXT:    pop.w {r4, r5, r6, r7, r8, pc}165;166; CHECK-MVE-LABEL: test_no_le:167; CHECK-MVE:       @ %bb.0: @ %entry168; CHECK-MVE-NEXT:    push.w {r4, r5, r6, r7, r8, r9, lr}169; CHECK-MVE-NEXT:    sub sp, #4170; CHECK-MVE-NEXT:    add.w r8, r0, r1, lsl #1171; CHECK-MVE-NEXT:    mov r9, r1172; CHECK-MVE-NEXT:    movs r6, #0173; CHECK-MVE-NEXT:    movs r7, #0174; CHECK-MVE-NEXT:  .LBB2_1: @ %outer_loop175; CHECK-MVE-NEXT:    @ =>This Loop Header: Depth=1176; CHECK-MVE-NEXT:    @ Child Loop BB2_2 Depth 2177; CHECK-MVE-NEXT:    mov r5, r8178; CHECK-MVE-NEXT:    mov r4, r9179; CHECK-MVE-NEXT:  .LBB2_2: @ %inner_loop180; CHECK-MVE-NEXT:    @ Parent Loop BB2_1 Depth=1181; CHECK-MVE-NEXT:    @ => This Inner Loop Header: Depth=2182; CHECK-MVE-NEXT:    bl otherfn183; CHECK-MVE-NEXT:    strh r6, [r5], #2184; CHECK-MVE-NEXT:    subs r4, #1185; CHECK-MVE-NEXT:    bne .LBB2_2186; CHECK-MVE-NEXT:  @ %bb.3: @ %outer_loop_end187; CHECK-MVE-NEXT:    @ in Loop: Header=BB2_1 Depth=1188; CHECK-MVE-NEXT:    adds r7, #1189; CHECK-MVE-NEXT:    cmp r7, r9190; CHECK-MVE-NEXT:    bne .LBB2_1191; CHECK-MVE-NEXT:  @ %bb.4: @ %exit192; CHECK-MVE-NEXT:    add sp, #4193; CHECK-MVE-NEXT:    pop.w {r4, r5, r6, r7, r8, r9, pc}194entry:195  br label %outer_loop196 197outer_loop:198  %idx_outer = phi i32 [ %idx_outer.inc, %outer_loop_end ], [ 0, %entry ]199  br label %inner_loop200 201inner_loop:202  %idx_inner = phi i32 [ 0, %outer_loop ], [ %idx_inner.inc, %inner_loop ]203  call void @otherfn()204  %add = add i32 %idx_inner, %n205  %gep = getelementptr inbounds i16, ptr %dst, i32 %add206  store i16 0, ptr %gep, align 2207  %idx_inner.inc = add nuw nsw i32 %idx_inner, 1208  %cond_inner = icmp eq i32 %idx_inner.inc, %n209  br i1 %cond_inner, label %outer_loop_end, label %inner_loop210 211outer_loop_end:212  %idx_outer.inc = add nuw i32 %idx_outer, 1213  %cond_outer = icmp eq i32 %idx_outer.inc, %n214  br i1 %cond_outer, label %exit, label %outer_loop215 216exit:217  ret void218}219 220define void @test_no_le_optsize(ptr %dst, i32 %n) optsize {221; CHECK-NOMVE-LABEL: test_no_le_optsize:222; CHECK-NOMVE:       @ %bb.0: @ %entry223; CHECK-NOMVE-NEXT:    push.w {r4, r5, r6, r7, r8, lr}224; CHECK-NOMVE-NEXT:    add.w r5, r0, r1, lsl #1225; CHECK-NOMVE-NEXT:    mov r4, r1226; CHECK-NOMVE-NEXT:    movs r6, #0227; CHECK-NOMVE-NEXT:    mov.w r8, #0228; CHECK-NOMVE-NEXT:  .LBB3_1: @ %outer_loop229; CHECK-NOMVE-NEXT:    @ =>This Loop Header: Depth=1230; CHECK-NOMVE-NEXT:    @ Child Loop BB3_2 Depth 2231; CHECK-NOMVE-NEXT:    movs r7, #0232; CHECK-NOMVE-NEXT:  .LBB3_2: @ %inner_loop233; CHECK-NOMVE-NEXT:    @ Parent Loop BB3_1 Depth=1234; CHECK-NOMVE-NEXT:    @ => This Inner Loop Header: Depth=2235; CHECK-NOMVE-NEXT:    bl otherfn236; CHECK-NOMVE-NEXT:    strh.w r6, [r5, r7, lsl #1]237; CHECK-NOMVE-NEXT:    adds r7, #1238; CHECK-NOMVE-NEXT:    cmp r4, r7239; CHECK-NOMVE-NEXT:    bne .LBB3_2240; CHECK-NOMVE-NEXT:  @ %bb.3: @ %outer_loop_end241; CHECK-NOMVE-NEXT:    @ in Loop: Header=BB3_1 Depth=1242; CHECK-NOMVE-NEXT:    add.w r8, r8, #1243; CHECK-NOMVE-NEXT:    cmp r8, r4244; CHECK-NOMVE-NEXT:    bne .LBB3_1245; CHECK-NOMVE-NEXT:  @ %bb.4: @ %exit246; CHECK-NOMVE-NEXT:    pop.w {r4, r5, r6, r7, r8, pc}247;248; CHECK-MVE-LABEL: test_no_le_optsize:249; CHECK-MVE:       @ %bb.0: @ %entry250; CHECK-MVE-NEXT:    push.w {r4, r5, r6, r7, r8, r9, lr}251; CHECK-MVE-NEXT:    sub sp, #4252; CHECK-MVE-NEXT:    add.w r8, r0, r1, lsl #1253; CHECK-MVE-NEXT:    mov r9, r1254; CHECK-MVE-NEXT:    movs r6, #0255; CHECK-MVE-NEXT:    movs r7, #0256; CHECK-MVE-NEXT:  .LBB3_1: @ %outer_loop257; CHECK-MVE-NEXT:    @ =>This Loop Header: Depth=1258; CHECK-MVE-NEXT:    @ Child Loop BB3_2 Depth 2259; CHECK-MVE-NEXT:    mov r5, r8260; CHECK-MVE-NEXT:    mov r4, r9261; CHECK-MVE-NEXT:  .LBB3_2: @ %inner_loop262; CHECK-MVE-NEXT:    @ Parent Loop BB3_1 Depth=1263; CHECK-MVE-NEXT:    @ => This Inner Loop Header: Depth=2264; CHECK-MVE-NEXT:    bl otherfn265; CHECK-MVE-NEXT:    strh r6, [r5], #2266; CHECK-MVE-NEXT:    subs r4, #1267; CHECK-MVE-NEXT:    bne .LBB3_2268; CHECK-MVE-NEXT:  @ %bb.3: @ %outer_loop_end269; CHECK-MVE-NEXT:    @ in Loop: Header=BB3_1 Depth=1270; CHECK-MVE-NEXT:    adds r7, #1271; CHECK-MVE-NEXT:    cmp r7, r9272; CHECK-MVE-NEXT:    bne .LBB3_1273; CHECK-MVE-NEXT:  @ %bb.4: @ %exit274; CHECK-MVE-NEXT:    add sp, #4275; CHECK-MVE-NEXT:    pop.w {r4, r5, r6, r7, r8, r9, pc}276entry:277  br label %outer_loop278 279outer_loop:280  %idx_outer = phi i32 [ %idx_outer.inc, %outer_loop_end ], [ 0, %entry ]281  br label %inner_loop282 283inner_loop:284  %idx_inner = phi i32 [ 0, %outer_loop ], [ %idx_inner.inc, %inner_loop ]285  call void @otherfn()286  %add = add i32 %idx_inner, %n287  %gep = getelementptr inbounds i16, ptr %dst, i32 %add288  store i16 0, ptr %gep, align 2289  %idx_inner.inc = add nuw nsw i32 %idx_inner, 1290  %cond_inner = icmp eq i32 %idx_inner.inc, %n291  br i1 %cond_inner, label %outer_loop_end, label %inner_loop292 293outer_loop_end:294  %idx_outer.inc = add nuw i32 %idx_outer, 1295  %cond_outer = icmp eq i32 %idx_outer.inc, %n296  br i1 %cond_outer, label %exit, label %outer_loop297 298exit:299  ret void300}301