1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=thumbv7-apple-ios -mcpu=cortex-a8 | FileCheck %s 3; RUN: llc < %s -mtriple=thumbv8 | FileCheck -check-prefix=CHECK-V8 %s 4; RUN: llc < %s -mtriple=thumbv7 -arm-restrict-it | FileCheck -check-prefix=CHECK-RESTRICT-IT %s 5 6define i32 @t1(i32 %a, i32 %b, ptr %retaddr) { 7; CHECK-LABEL: t1: 8; CHECK: @ %bb.0: 9; CHECK-NEXT: ldr r3, LCPI0_0 10; CHECK-NEXT: cmp r0, #0 11; CHECK-NEXT: LPC0_0: 12; CHECK-NEXT: add r3, pc 13; CHECK-NEXT: str r3, [r2] 14; CHECK-NEXT: mov.w r2, #1 15; CHECK-NEXT: it eq 16; CHECK-NEXT: moveq.w r2, #-1 17; CHECK-NEXT: Ltmp0: @ Block address taken 18; CHECK-NEXT: @ %bb.1: @ %common.ret 19; CHECK-NEXT: adds r0, r1, r2 20; CHECK-NEXT: bx lr 21; CHECK-NEXT: .p2align 2 22; CHECK-NEXT: @ %bb.2: 23; CHECK-NEXT: .data_region 24; CHECK-NEXT: LCPI0_0: 25; CHECK-NEXT: .long Ltmp0-(LPC0_0+4) 26; CHECK-NEXT: .end_data_region 27; 28; CHECK-V8-LABEL: t1: 29; CHECK-V8: @ %bb.0: 30; CHECK-V8-NEXT: ldr r3, .LCPI0_0 31; CHECK-V8-NEXT: cmp r0, #0 32; CHECK-V8-NEXT: str r3, [r2] 33; CHECK-V8-NEXT: mov.w r2, #1 34; CHECK-V8-NEXT: it eq 35; CHECK-V8-NEXT: moveq.w r2, #-1 36; CHECK-V8-NEXT: .Ltmp0: @ Block address taken 37; CHECK-V8-NEXT: @ %bb.1: @ %common.ret 38; CHECK-V8-NEXT: adds r0, r1, r2 39; CHECK-V8-NEXT: bx lr 40; CHECK-V8-NEXT: .p2align 2 41; CHECK-V8-NEXT: @ %bb.2: 42; CHECK-V8-NEXT: .LCPI0_0: 43; CHECK-V8-NEXT: .long .Ltmp0 44; 45; CHECK-RESTRICT-IT-LABEL: t1: 46; CHECK-RESTRICT-IT: @ %bb.0: 47; CHECK-RESTRICT-IT-NEXT: ldr r3, .LCPI0_0 48; CHECK-RESTRICT-IT-NEXT: str r3, [r2] 49; CHECK-RESTRICT-IT-NEXT: movs r2, #1 50; CHECK-RESTRICT-IT-NEXT: cmp r0, #0 51; CHECK-RESTRICT-IT-NEXT: it eq 52; CHECK-RESTRICT-IT-NEXT: moveq.w r2, #-1 53; CHECK-RESTRICT-IT-NEXT: .Ltmp0: @ Block address taken 54; CHECK-RESTRICT-IT-NEXT: @ %bb.1: @ %common.ret 55; CHECK-RESTRICT-IT-NEXT: adds r0, r1, r2 56; CHECK-RESTRICT-IT-NEXT: bx lr 57; CHECK-RESTRICT-IT-NEXT: .p2align 2 58; CHECK-RESTRICT-IT-NEXT: @ %bb.2: 59; CHECK-RESTRICT-IT-NEXT: .LCPI0_0: 60; CHECK-RESTRICT-IT-NEXT: .long .Ltmp0 61 store ptr blockaddress(@t1, %cond_true), ptr %retaddr 62 %tmp2 = icmp eq i32 %a, 0 63 br i1 %tmp2, label %cond_false, label %cond_true 64 65cond_true: 66 %tmp5 = add i32 %b, 1 67 ret i32 %tmp5 68 69cond_false: 70 %tmp7 = add i32 %b, -1 71 ret i32 %tmp7 72} 73 74define i32 @t2(i32 %a, i32 %b, i32 %c, i32 %d, ptr %retaddr) { 75; CHECK-LABEL: t2: 76; CHECK: @ %bb.0: 77; CHECK-NEXT: ldr.w r9, [sp] 78; CHECK-NEXT: add r0, r1 79; CHECK-NEXT: ldr.w r12, LCPI1_0 80; CHECK-NEXT: cmp r3, #3 81; CHECK-NEXT: LPC1_0: 82; CHECK-NEXT: add r12, pc 83; CHECK-NEXT: str.w r12, [r9] 84; CHECK-NEXT: it gt 85; CHECK-NEXT: bxgt lr 86; CHECK-NEXT: LBB1_1: 87; CHECK-NEXT: cmp r2, #10 88; CHECK-NEXT: ble LBB1_3 89; CHECK-NEXT: Ltmp1: @ Block address taken 90; CHECK-NEXT: @ %bb.2: @ %cond_true 91; CHECK-NEXT: add r0, r2 92; CHECK-NEXT: subs r0, r0, r3 93; CHECK-NEXT: LBB1_3: @ %common.ret 94; CHECK-NEXT: bx lr 95; CHECK-NEXT: .p2align 2 96; CHECK-NEXT: @ %bb.4: 97; CHECK-NEXT: .data_region 98; CHECK-NEXT: LCPI1_0: 99; CHECK-NEXT: .long Ltmp1-(LPC1_0+4) 100; CHECK-NEXT: .end_data_region 101; 102; CHECK-V8-LABEL: t2: 103; CHECK-V8: @ %bb.0: 104; CHECK-V8-NEXT: push {r7, lr} 105; CHECK-V8-NEXT: ldr.w r12, [sp, #8] 106; CHECK-V8-NEXT: add r0, r1 107; CHECK-V8-NEXT: ldr.w lr, .LCPI1_0 108; CHECK-V8-NEXT: cmp r3, #3 109; CHECK-V8-NEXT: str.w lr, [r12] 110; CHECK-V8-NEXT: it gt 111; CHECK-V8-NEXT: popgt {r7, pc} 112; CHECK-V8-NEXT: .LBB1_1: 113; CHECK-V8-NEXT: cmp r2, #10 114; CHECK-V8-NEXT: ble .LBB1_3 115; CHECK-V8-NEXT: .Ltmp1: @ Block address taken 116; CHECK-V8-NEXT: @ %bb.2: @ %cond_true 117; CHECK-V8-NEXT: add r0, r2 118; CHECK-V8-NEXT: subs r0, r0, r3 119; CHECK-V8-NEXT: .LBB1_3: @ %common.ret 120; CHECK-V8-NEXT: pop {r7, pc} 121; CHECK-V8-NEXT: .p2align 2 122; CHECK-V8-NEXT: @ %bb.4: 123; CHECK-V8-NEXT: .LCPI1_0: 124; CHECK-V8-NEXT: .long .Ltmp1 125; 126; CHECK-RESTRICT-IT-LABEL: t2: 127; CHECK-RESTRICT-IT: @ %bb.0: 128; CHECK-RESTRICT-IT-NEXT: push {r7, lr} 129; CHECK-RESTRICT-IT-NEXT: ldr.w r12, [sp, #8] 130; CHECK-RESTRICT-IT-NEXT: add r0, r1 131; CHECK-RESTRICT-IT-NEXT: ldr.w lr, .LCPI1_0 132; CHECK-RESTRICT-IT-NEXT: cmp r3, #3 133; CHECK-RESTRICT-IT-NEXT: str.w lr, [r12] 134; CHECK-RESTRICT-IT-NEXT: bgt .LBB1_3 135; CHECK-RESTRICT-IT-NEXT: @ %bb.1: 136; CHECK-RESTRICT-IT-NEXT: cmp r2, #10 137; CHECK-RESTRICT-IT-NEXT: ble .LBB1_3 138; CHECK-RESTRICT-IT-NEXT: .Ltmp1: @ Block address taken 139; CHECK-RESTRICT-IT-NEXT: @ %bb.2: @ %cond_true 140; CHECK-RESTRICT-IT-NEXT: add r0, r2 141; CHECK-RESTRICT-IT-NEXT: subs r0, r0, r3 142; CHECK-RESTRICT-IT-NEXT: .LBB1_3: @ %common.ret 143; CHECK-RESTRICT-IT-NEXT: pop {r7, pc} 144; CHECK-RESTRICT-IT-NEXT: .p2align 2 145; CHECK-RESTRICT-IT-NEXT: @ %bb.4: 146; CHECK-RESTRICT-IT-NEXT: .LCPI1_0: 147; CHECK-RESTRICT-IT-NEXT: .long .Ltmp1 148 store ptr blockaddress(@t2, %cond_true), ptr %retaddr 149 %tmp2 = icmp sgt i32 %c, 10 150 %tmp5 = icmp slt i32 %d, 4 151 %tmp8 = and i1 %tmp5, %tmp2 152 %tmp13 = add i32 %b, %a 153 br i1 %tmp8, label %cond_true, label %UnifiedReturnBlock 154 155cond_true: 156 %tmp15 = add i32 %tmp13, %c 157 %tmp1821 = sub i32 %tmp15, %d 158 ret i32 %tmp1821 159 160UnifiedReturnBlock: 161 ret i32 %tmp13 162} 163 164define hidden fastcc void @t3(ptr %retaddr, i1 %tst, ptr %p8) { 165; CHECK-LABEL: t3: 166; CHECK: @ %bb.0: @ %bb 167; CHECK-NEXT: ldr r1, LCPI2_0 168; CHECK-NEXT: LPC2_0: 169; CHECK-NEXT: add r1, pc 170; CHECK-NEXT: str r1, [r0] 171; CHECK-NEXT: Ltmp2: @ Block address taken 172; CHECK-NEXT: @ %bb.1: @ %common.ret 173; CHECK-NEXT: bx lr 174; CHECK-NEXT: .p2align 2 175; CHECK-NEXT: @ %bb.2: 176; CHECK-NEXT: .data_region 177; CHECK-NEXT: LCPI2_0: 178; CHECK-NEXT: .long Ltmp2-(LPC2_0+4) 179; CHECK-NEXT: .end_data_region 180; 181; CHECK-V8-LABEL: t3: 182; CHECK-V8: @ %bb.0: @ %bb 183; CHECK-V8-NEXT: ldr r1, .LCPI2_0 184; CHECK-V8-NEXT: str r1, [r0] 185; CHECK-V8-NEXT: .Ltmp2: @ Block address taken 186; CHECK-V8-NEXT: @ %bb.1: @ %common.ret 187; CHECK-V8-NEXT: bx lr 188; CHECK-V8-NEXT: .p2align 2 189; CHECK-V8-NEXT: @ %bb.2: 190; CHECK-V8-NEXT: .LCPI2_0: 191; CHECK-V8-NEXT: .long .Ltmp2 192; 193; CHECK-RESTRICT-IT-LABEL: t3: 194; CHECK-RESTRICT-IT: @ %bb.0: @ %bb 195; CHECK-RESTRICT-IT-NEXT: ldr r1, .LCPI2_0 196; CHECK-RESTRICT-IT-NEXT: str r1, [r0] 197; CHECK-RESTRICT-IT-NEXT: .Ltmp2: @ Block address taken 198; CHECK-RESTRICT-IT-NEXT: @ %bb.1: @ %common.ret 199; CHECK-RESTRICT-IT-NEXT: bx lr 200; CHECK-RESTRICT-IT-NEXT: .p2align 2 201; CHECK-RESTRICT-IT-NEXT: @ %bb.2: 202; CHECK-RESTRICT-IT-NEXT: .LCPI2_0: 203; CHECK-RESTRICT-IT-NEXT: .long .Ltmp2 204bb: 205 store ptr blockaddress(@t3, %KBBlockZero_return_1), ptr %retaddr 206 br i1 %tst, label %bb77, label %bb7.i 207 208bb7.i: ; preds = %bb35 209 br label %bb2.i 210 211KBBlockZero_return_1: ; preds = %KBBlockZero.exit 212 ret void 213 214KBBlockZero_return_0: ; preds = %KBBlockZero.exit 215 ret void 216 217bb77: ; preds = %bb26, %bb12, %bb 218 ret void 219 220bb2.i: ; preds = %bb6.i350, %bb7.i 221 br i1 %tst, label %bb6.i350, label %KBBlockZero.exit 222 223bb6.i350: ; preds = %bb2.i 224 br label %bb2.i 225 226KBBlockZero.exit: ; preds = %bb2.i 227 indirectbr ptr %p8, [label %KBBlockZero_return_1, label %KBBlockZero_return_0] 228} 229 230@foo = global ptr null 231define i32 @t4(i32 %x, ptr %p_foo) { 232; CHECK-LABEL: t4: 233; CHECK: @ %bb.0: @ %entry 234; CHECK-NEXT: push {r4, lr} 235; CHECK-NEXT: mov r4, r0 236; CHECK-NEXT: cmp r0, #59 237; CHECK-NEXT: ittt gt 238; CHECK-NEXT: mvngt r0, #119 239; CHECK-NEXT: addgt r0, r4 240; CHECK-NEXT: popgt {r4, pc} 241; CHECK-NEXT: LBB3_1: @ %if.then 242; CHECK-NEXT: blx r1 243; CHECK-NEXT: mov.w r0, #-1 244; CHECK-NEXT: add r0, r4 245; CHECK-NEXT: pop {r4, pc} 246; 247; CHECK-V8-LABEL: t4: 248; CHECK-V8: @ %bb.0: @ %entry 249; CHECK-V8-NEXT: push {r4, lr} 250; CHECK-V8-NEXT: mov r4, r0 251; CHECK-V8-NEXT: cmp r0, #59 252; CHECK-V8-NEXT: bgt .LBB3_2 253; CHECK-V8-NEXT: @ %bb.1: @ %if.then 254; CHECK-V8-NEXT: blx r1 255; CHECK-V8-NEXT: mov.w r0, #-1 256; CHECK-V8-NEXT: add r0, r4 257; CHECK-V8-NEXT: pop {r4, pc} 258; CHECK-V8-NEXT: .LBB3_2: 259; CHECK-V8-NEXT: mvn r0, #119 260; CHECK-V8-NEXT: add r0, r4 261; CHECK-V8-NEXT: pop {r4, pc} 262; 263; CHECK-RESTRICT-IT-LABEL: t4: 264; CHECK-RESTRICT-IT: @ %bb.0: @ %entry 265; CHECK-RESTRICT-IT-NEXT: push {r4, lr} 266; CHECK-RESTRICT-IT-NEXT: mov r4, r0 267; CHECK-RESTRICT-IT-NEXT: cmp r0, #59 268; CHECK-RESTRICT-IT-NEXT: bgt .LBB3_2 269; CHECK-RESTRICT-IT-NEXT: @ %bb.1: @ %if.then 270; CHECK-RESTRICT-IT-NEXT: blx r1 271; CHECK-RESTRICT-IT-NEXT: mov.w r0, #-1 272; CHECK-RESTRICT-IT-NEXT: add r0, r4 273; CHECK-RESTRICT-IT-NEXT: pop {r4, pc} 274; CHECK-RESTRICT-IT-NEXT: .LBB3_2: 275; CHECK-RESTRICT-IT-NEXT: mvn r0, #119 276; CHECK-RESTRICT-IT-NEXT: add r0, r4 277; CHECK-RESTRICT-IT-NEXT: pop {r4, pc} 278entry: 279 %cmp = icmp slt i32 %x, 60 280 br i1 %cmp, label %if.then, label %if.else 281 282if.then: ; preds = %entry 283 %tmp.2 = call i32 %p_foo() 284 %sub = add nsw i32 %x, -1 285 br label %return 286 287if.else: ; preds = %entry 288 %sub1 = add nsw i32 %x, -120 289 br label %return 290 291return: ; preds = %if.end5, %if.then4, %if.then 292 %retval.0 = phi i32 [ %sub, %if.then ], [ %sub1, %if.else ] 293 ret i32 %retval.0 294} 295 296; If-converter was checking for the wrong predicate subsumes pattern when doing 297; nested predicates. 298; E.g., Let A be a basic block that flows conditionally into B and B be a 299; predicated block. 300; B can be predicated with A.BrToBPredicate into A iff B.Predicate is less 301; "permissive" than A.BrToBPredicate, i.e., iff A.BrToBPredicate subsumes 302; B.Predicate. 303 304define i32 @wrapDistance(i32 %tx, i32 %sx, i32 %w) { 305; CHECK-LABEL: wrapDistance: 306; CHECK: @ %bb.0: @ %entry 307; CHECK-NEXT: cmp r1, #59 308; CHECK-NEXT: itt le 309; CHECK-NEXT: suble r0, r2, #1 310; CHECK-NEXT: bxle lr 311; CHECK-NEXT: LBB4_1: @ %if.else 312; CHECK-NEXT: subs r2, #120 313; CHECK-NEXT: cmp r2, r1 314; CHECK-NEXT: bge LBB4_3 315; CHECK-NEXT: @ %bb.2: @ %if.else 316; CHECK-NEXT: cmp r0, #119 317; CHECK-NEXT: itt le 318; CHECK-NEXT: addle r0, r1, #1 319; CHECK-NEXT: bxle lr 320; CHECK-NEXT: LBB4_3: @ %if.end5 321; CHECK-NEXT: subs r0, r1, r0 322; CHECK-NEXT: bx lr 323; 324; CHECK-V8-LABEL: wrapDistance: 325; CHECK-V8: @ %bb.0: @ %entry 326; CHECK-V8-NEXT: cmp r1, #59 327; CHECK-V8-NEXT: itt le 328; CHECK-V8-NEXT: suble r0, r2, #1 329; CHECK-V8-NEXT: bxle lr 330; CHECK-V8-NEXT: .LBB4_1: @ %if.else 331; CHECK-V8-NEXT: subs r2, #120 332; CHECK-V8-NEXT: cmp r2, r1 333; CHECK-V8-NEXT: bge .LBB4_3 334; CHECK-V8-NEXT: @ %bb.2: @ %if.else 335; CHECK-V8-NEXT: cmp r0, #119 336; CHECK-V8-NEXT: itt le 337; CHECK-V8-NEXT: addle r0, r1, #1 338; CHECK-V8-NEXT: bxle lr 339; CHECK-V8-NEXT: .LBB4_3: @ %if.end5 340; CHECK-V8-NEXT: subs r0, r1, r0 341; CHECK-V8-NEXT: bx lr 342; 343; CHECK-RESTRICT-IT-LABEL: wrapDistance: 344; CHECK-RESTRICT-IT: @ %bb.0: @ %entry 345; CHECK-RESTRICT-IT-NEXT: cmp r1, #59 346; CHECK-RESTRICT-IT-NEXT: bgt .LBB4_2 347; CHECK-RESTRICT-IT-NEXT: @ %bb.1: @ %if.then 348; CHECK-RESTRICT-IT-NEXT: subs r0, r2, #1 349; CHECK-RESTRICT-IT-NEXT: bx lr 350; CHECK-RESTRICT-IT-NEXT: .LBB4_2: @ %if.else 351; CHECK-RESTRICT-IT-NEXT: subs r2, #120 352; CHECK-RESTRICT-IT-NEXT: cmp r2, r1 353; CHECK-RESTRICT-IT-NEXT: bge .LBB4_5 354; CHECK-RESTRICT-IT-NEXT: @ %bb.3: @ %if.else 355; CHECK-RESTRICT-IT-NEXT: cmp r0, #119 356; CHECK-RESTRICT-IT-NEXT: bgt .LBB4_5 357; CHECK-RESTRICT-IT-NEXT: @ %bb.4: @ %if.then4 358; CHECK-RESTRICT-IT-NEXT: adds r0, r1, #1 359; CHECK-RESTRICT-IT-NEXT: bx lr 360; CHECK-RESTRICT-IT-NEXT: .LBB4_5: @ %if.end5 361; CHECK-RESTRICT-IT-NEXT: subs r0, r1, r0 362; CHECK-RESTRICT-IT-NEXT: bx lr 363entry: 364 %cmp = icmp slt i32 %sx, 60 365 br i1 %cmp, label %if.then, label %if.else 366 367if.then: ; preds = %entry 368 %sub = add nsw i32 %w, -1 369 br label %return 370 371if.else: ; preds = %entry 372 %sub1 = add nsw i32 %w, -120 373 %cmp2 = icmp slt i32 %sub1, %sx 374 %cmp3 = icmp slt i32 %tx, 120 375 %or.cond = and i1 %cmp2, %cmp3 376 br i1 %or.cond, label %if.then4, label %if.end5 377 378if.then4: ; preds = %if.else 379 %add = add nsw i32 %sx, 1 380 br label %return 381 382if.end5: ; preds = %if.else 383 %sub6 = sub nsw i32 %sx, %tx 384 br label %return 385 386return: ; preds = %if.end5, %if.then4, %if.then 387 %retval.0 = phi i32 [ %sub, %if.then ], [ %add, %if.then4 ], [ %sub6, %if.end5 ] 388 ret i32 %retval.0 389} 390