1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=thumbv7-apple-darwin | FileCheck %s --check-prefixes=ALL,V01 3; RUN: llc < %s -mtriple=thumbv7-apple-darwin -arm-default-it | FileCheck %s --check-prefixes=ALL,V01 4; RUN: llc < %s -mtriple=thumbv8 | FileCheck %s --check-prefixes=ALL,V23,V2 5; RUN: llc < %s -mtriple=thumbv8 -enable-tail-merge=0 | FileCheck %s --check-prefixes=ALL,V23,V3 6 7define i32 @t1(i32 %a, i32 %b, i32 %c, i32 %d) nounwind { 8; ALL-LABEL: t1: 9; ALL: @ %bb.0: 10; ALL-NEXT: cmp r2, #1 11; ALL-NEXT: ittee ne 12; ALL-NEXT: cmpne r2, #7 13; ALL-NEXT: addne r0, r1 14; ALL-NEXT: addeq r0, r1 15; ALL-NEXT: addeq r0, #1 16; ALL-NEXT: bx lr 17 switch i32 %c, label %cond_next [ 18 i32 1, label %cond_true 19 i32 7, label %cond_true 20 ] 21 22cond_true: 23 %tmp12 = add i32 %a, 1 24 %tmp1518 = add i32 %tmp12, %b 25 ret i32 %tmp1518 26 27cond_next: 28 %tmp15 = add i32 %b, %a 29 ret i32 %tmp15 30} 31 32define i32 @t2(i32 %a, i32 %b) nounwind { 33; V01-LABEL: t2: 34; V01: @ %bb.0: @ %entry 35; V01-NEXT: cmp r0, r1 36; V01-NEXT: it eq 37; V01-NEXT: bxeq lr 38; V01-NEXT: LBB1_1: @ %bb 39; V01-NEXT: @ =>This Inner Loop Header: Depth=1 40; V01-NEXT: cmp r0, r1 41; V01-NEXT: ite gt 42; V01-NEXT: subgt r0, r0, r1 43; V01-NEXT: suble r1, r1, r0 44; V01-NEXT: cmp r1, r0 45; V01-NEXT: bne LBB1_1 46; V01-NEXT: @ %bb.2: @ %bb17 47; V01-NEXT: bx lr 48; 49; V2-LABEL: t2: 50; V2: @ %bb.0: @ %entry 51; V2-NEXT: cmp r0, r1 52; V2-NEXT: it eq 53; V2-NEXT: bxeq lr 54; V2-NEXT: .LBB1_1: @ %bb 55; V2-NEXT: @ =>This Inner Loop Header: Depth=1 56; V2-NEXT: cmp r0, r1 57; V2-NEXT: ite gt 58; V2-NEXT: subgt r0, r0, r1 59; V2-NEXT: suble r1, r1, r0 60; V2-NEXT: cmp r1, r0 61; V2-NEXT: bne .LBB1_1 62; V2-NEXT: @ %bb.2: @ %bb17 63; V2-NEXT: bx lr 64; 65; V3-LABEL: t2: 66; V3: @ %bb.0: @ %entry 67; V3-NEXT: cmp r0, r1 68; V3-NEXT: it eq 69; V3-NEXT: bxeq lr 70; V3-NEXT: .LBB1_1: @ %bb 71; V3-NEXT: @ =>This Inner Loop Header: Depth=1 72; V3-NEXT: cmp r0, r1 73; V3-NEXT: ite le 74; V3-NEXT: suble r1, r1, r0 75; V3-NEXT: subgt r0, r0, r1 76; V3-NEXT: cmp r1, r0 77; V3-NEXT: bne .LBB1_1 78; V3-NEXT: @ %bb.2: @ %bb17 79; V3-NEXT: bx lr 80entry: 81 %tmp1434 = icmp eq i32 %a, %b ; <i1> [#uses=1] 82 br i1 %tmp1434, label %bb17, label %bb.outer 83 84bb.outer: ; preds = %cond_false, %entry 85 %b_addr.021.0.ph = phi i32 [ %b, %entry ], [ %tmp10, %cond_false ] ; <i32> [#uses=5] 86 %a_addr.026.0.ph = phi i32 [ %a, %entry ], [ %a_addr.026.0, %cond_false ] ; <i32> [#uses=1] 87 br label %bb 88 89bb: ; preds = %cond_true, %bb.outer 90 %indvar = phi i32 [ 0, %bb.outer ], [ %indvar.next, %cond_true ] ; <i32> [#uses=2] 91 %tmp. = sub i32 0, %b_addr.021.0.ph ; <i32> [#uses=1] 92 %tmp.40 = mul i32 %indvar, %tmp. ; <i32> [#uses=1] 93 %a_addr.026.0 = add i32 %tmp.40, %a_addr.026.0.ph ; <i32> [#uses=6] 94 %tmp3 = icmp sgt i32 %a_addr.026.0, %b_addr.021.0.ph ; <i1> [#uses=1] 95 br i1 %tmp3, label %cond_true, label %cond_false 96 97cond_true: ; preds = %bb 98 %tmp7 = sub i32 %a_addr.026.0, %b_addr.021.0.ph ; <i32> [#uses=2] 99 %tmp1437 = icmp eq i32 %tmp7, %b_addr.021.0.ph ; <i1> [#uses=1] 100 %indvar.next = add i32 %indvar, 1 ; <i32> [#uses=1] 101 br i1 %tmp1437, label %bb17, label %bb 102 103cond_false: ; preds = %bb 104 %tmp10 = sub i32 %b_addr.021.0.ph, %a_addr.026.0 ; <i32> [#uses=2] 105 %tmp14 = icmp eq i32 %a_addr.026.0, %tmp10 ; <i1> [#uses=1] 106 br i1 %tmp14, label %bb17, label %bb.outer 107 108bb17: ; preds = %cond_false, %cond_true, %entry 109 %a_addr.026.1 = phi i32 [ %a, %entry ], [ %tmp7, %cond_true ], [ %a_addr.026.0, %cond_false ] ; <i32> [#uses=1] 110 ret i32 %a_addr.026.1 111} 112 113define i32 @t2_nomerge(i32 %a, i32 %b) nounwind { 114; V01-LABEL: t2_nomerge: 115; V01: @ %bb.0: @ %entry 116; V01-NEXT: cmp r0, r1 117; V01-NEXT: it eq 118; V01-NEXT: bxeq lr 119; V01-NEXT: LBB2_1: @ %bb 120; V01-NEXT: @ =>This Inner Loop Header: Depth=1 121; V01-NEXT: cmp r0, r1 122; V01-NEXT: ble LBB2_3 123; V01-NEXT: @ %bb.2: @ %cond_true 124; V01-NEXT: @ in Loop: Header=BB2_1 Depth=1 125; V01-NEXT: subs r0, r0, r1 126; V01-NEXT: cmp r1, r0 127; V01-NEXT: bne LBB2_1 128; V01-NEXT: b LBB2_4 129; V01-NEXT: LBB2_3: @ %cond_false 130; V01-NEXT: @ in Loop: Header=BB2_1 Depth=1 131; V01-NEXT: subs r1, r1, r0 132; V01-NEXT: cmp r0, #0 133; V01-NEXT: bne LBB2_1 134; V01-NEXT: LBB2_4: @ %bb17 135; V01-NEXT: bx lr 136; 137; V2-LABEL: t2_nomerge: 138; V2: @ %bb.0: @ %entry 139; V2-NEXT: cmp r0, r1 140; V2-NEXT: it eq 141; V2-NEXT: bxeq lr 142; V2-NEXT: .LBB2_1: @ %bb 143; V2-NEXT: @ =>This Inner Loop Header: Depth=1 144; V2-NEXT: cmp r0, r1 145; V2-NEXT: ble .LBB2_3 146; V2-NEXT: @ %bb.2: @ %cond_true 147; V2-NEXT: @ in Loop: Header=BB2_1 Depth=1 148; V2-NEXT: subs r0, r0, r1 149; V2-NEXT: cmp r1, r0 150; V2-NEXT: bne .LBB2_1 151; V2-NEXT: b .LBB2_4 152; V2-NEXT: .LBB2_3: @ %cond_false 153; V2-NEXT: @ in Loop: Header=BB2_1 Depth=1 154; V2-NEXT: subs r1, r1, r0 155; V2-NEXT: cmp r0, #0 156; V2-NEXT: bne .LBB2_1 157; V2-NEXT: .LBB2_4: @ %bb17 158; V2-NEXT: bx lr 159; 160; V3-LABEL: t2_nomerge: 161; V3: @ %bb.0: @ %entry 162; V3-NEXT: cmp r0, r1 163; V3-NEXT: beq .LBB2_4 164; V3-NEXT: b .LBB2_2 165; V3-NEXT: .LBB2_1: @ %cond_true 166; V3-NEXT: @ in Loop: Header=BB2_2 Depth=1 167; V3-NEXT: subs r0, r0, r1 168; V3-NEXT: cmp r1, r0 169; V3-NEXT: it eq 170; V3-NEXT: bxeq lr 171; V3-NEXT: .LBB2_2: @ %bb 172; V3-NEXT: @ =>This Inner Loop Header: Depth=1 173; V3-NEXT: cmp r0, r1 174; V3-NEXT: bgt .LBB2_1 175; V3-NEXT: @ %bb.3: @ %cond_false 176; V3-NEXT: @ in Loop: Header=BB2_2 Depth=1 177; V3-NEXT: subs r1, r1, r0 178; V3-NEXT: cmp r0, #0 179; V3-NEXT: bne .LBB2_2 180; V3-NEXT: .LBB2_4: @ %bb17 181; V3-NEXT: bx lr 182entry: 183 %tmp1434 = icmp eq i32 %a, %b ; <i1> [#uses=1] 184 br i1 %tmp1434, label %bb17, label %bb.outer 185 186bb.outer: ; preds = %cond_false, %entry 187 %b_addr.021.0.ph = phi i32 [ %b, %entry ], [ %tmp10, %cond_false ] ; <i32> [#uses=5] 188 %a_addr.026.0.ph = phi i32 [ %a, %entry ], [ %a_addr.026.0, %cond_false ] ; <i32> [#uses=1] 189 br label %bb 190 191bb: ; preds = %cond_true, %bb.outer 192 %indvar = phi i32 [ 0, %bb.outer ], [ %indvar.next, %cond_true ] ; <i32> [#uses=2] 193 %tmp. = sub i32 0, %b_addr.021.0.ph ; <i32> [#uses=1] 194 %tmp.40 = mul i32 %indvar, %tmp. ; <i32> [#uses=1] 195 %a_addr.026.0 = add i32 %tmp.40, %a_addr.026.0.ph ; <i32> [#uses=6] 196 %tmp3 = icmp sgt i32 %a_addr.026.0, %b_addr.021.0.ph ; <i1> [#uses=1] 197 br i1 %tmp3, label %cond_true, label %cond_false 198 199cond_true: ; preds = %bb 200 %tmp7 = sub i32 %a_addr.026.0, %b_addr.021.0.ph ; <i32> [#uses=2] 201 %tmp1437 = icmp eq i32 %tmp7, %b_addr.021.0.ph ; <i1> [#uses=1] 202 %indvar.next = add i32 %indvar, 1 ; <i32> [#uses=1] 203 br i1 %tmp1437, label %bb17, label %bb 204 205cond_false: ; preds = %bb 206 %tmp10 = sub i32 %b_addr.021.0.ph, %a_addr.026.0 ; <i32> [#uses=2] 207 %tmp14 = icmp eq i32 %b_addr.021.0.ph, %tmp10 ; <i1> [#uses=1] 208 br i1 %tmp14, label %bb17, label %bb.outer 209 210bb17: ; preds = %cond_false, %cond_true, %entry 211 %a_addr.026.1 = phi i32 [ %a, %entry ], [ %tmp7, %cond_true ], [ %a_addr.026.0, %cond_false ] ; <i32> [#uses=1] 212 ret i32 %a_addr.026.1 213} 214 215@x = external global ptr ; <ptr> [#uses=1] 216 217define void @foo(i32 %a) nounwind { 218; V01-LABEL: foo: 219; V01: @ %bb.0: @ %entry 220; V01-NEXT: movw r1, :lower16:(L_x$non_lazy_ptr-(LPC3_0+4)) 221; V01-NEXT: movt r1, :upper16:(L_x$non_lazy_ptr-(LPC3_0+4)) 222; V01-NEXT: LPC3_0: 223; V01-NEXT: add r1, pc 224; V01-NEXT: ldr r1, [r1] 225; V01-NEXT: ldr r1, [r1] 226; V01-NEXT: str r0, [r1] 227; V01-NEXT: bx lr 228; 229; V23-LABEL: foo: 230; V23: @ %bb.0: @ %entry 231; V23-NEXT: movw r1, :lower16:x 232; V23-NEXT: movt r1, :upper16:x 233; V23-NEXT: ldr r1, [r1] 234; V23-NEXT: str r0, [r1] 235; V23-NEXT: bx lr 236entry: 237 %tmp = load ptr, ptr @x ; <ptr> [#uses=1] 238 store i32 %a, ptr %tmp 239 ret void 240} 241 242define void @t3(i32 %a, i32 %b) nounwind { 243; V01-LABEL: t3: 244; V01: @ %bb.0: @ %entry 245; V01-NEXT: cmp r0, #10 246; V01-NEXT: it le 247; V01-NEXT: bxle lr 248; V01-NEXT: LBB4_1: @ %cond_true 249; V01-NEXT: str lr, [sp, #-4]! 250; V01-NEXT: mov r0, r1 251; V01-NEXT: bl _foo 252; V01-NEXT: ldr lr, [sp], #4 253; V01-NEXT: bx lr 254; 255; V23-LABEL: t3: 256; V23: @ %bb.0: @ %entry 257; V23-NEXT: cmp r0, #10 258; V23-NEXT: it le 259; V23-NEXT: bxle lr 260; V23-NEXT: .LBB4_1: @ %cond_true 261; V23-NEXT: push {r7, lr} 262; V23-NEXT: mov r0, r1 263; V23-NEXT: bl foo 264; V23-NEXT: pop.w {r7, lr} 265; V23-NEXT: bx lr 266entry: 267 %tmp1 = icmp sgt i32 %a, 10 ; <i1> [#uses=1] 268 br i1 %tmp1, label %cond_true, label %UnifiedReturnBlock 269 270cond_true: ; preds = %entry 271 call void @foo( i32 %b ) 272 ret void 273 274UnifiedReturnBlock: ; preds = %entry 275 ret void 276} 277