1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc %s -o - -enable-shrink-wrap=true -ifcvt-fn-start=1 -ifcvt-fn-stop=0 -tail-dup-placement=0 -mtriple=thumb-macho | FileCheck %s --check-prefix=ENABLE-V4T 3; RUN: llc %s -o - -enable-shrink-wrap=true -ifcvt-fn-start=1 -ifcvt-fn-stop=0 -tail-dup-placement=0 -mtriple=thumbv5-macho | FileCheck %s --check-prefix=ENABLE-V5T 4; RUN: llc %s -o - -enable-shrink-wrap=false -ifcvt-fn-start=1 -ifcvt-fn-stop=0 -tail-dup-placement=0 -mtriple=thumb-macho | FileCheck %s --check-prefix=DISABLE-V4T 5; RUN: llc %s -o - -enable-shrink-wrap=false -ifcvt-fn-start=1 -ifcvt-fn-stop=0 -tail-dup-placement=0 -mtriple=thumbv5-macho | FileCheck %s --check-prefix=DISABLE-V5T 6 7; 8; Note: Lots of tests use inline asm instead of regular calls. 9; This allows to have a better control on what the allocation will do. 10; Otherwise, we may have spill right in the entry block, defeating 11; shrink-wrapping. Moreover, some of the inline asm statements (nop) 12; are here to ensure that the related paths do not end up as critical 13; edges. 14; Also disable the late if-converter as it makes harder to reason on 15; the diffs. 16; Disable tail-duplication during placement, as v4t vs v5t get different 17; results due to branches not being analyzable under v5 18 19; Initial motivating example: Simple diamond with a call just on one side. 20define i32 @foo(i32 %a, i32 %b) { 21; ENABLE-V4T-LABEL: foo: 22; ENABLE-V4T: @ %bb.0: 23; ENABLE-V4T-NEXT: cmp r0, r1 24; ENABLE-V4T-NEXT: bge LBB0_2 25; ENABLE-V4T-NEXT: @ %bb.1: @ %true 26; ENABLE-V4T-NEXT: push {r7, lr} 27; ENABLE-V4T-NEXT: .cfi_def_cfa_offset 8 28; ENABLE-V4T-NEXT: .cfi_offset lr, -4 29; ENABLE-V4T-NEXT: .cfi_offset r7, -8 30; ENABLE-V4T-NEXT: sub sp, #8 31; ENABLE-V4T-NEXT: .cfi_def_cfa_offset 16 32; ENABLE-V4T-NEXT: str r0, [sp, #4] 33; ENABLE-V4T-NEXT: ldr r0, LCPI0_0 34; ENABLE-V4T-NEXT: LPC0_0: 35; ENABLE-V4T-NEXT: add r0, pc 36; ENABLE-V4T-NEXT: ldr r2, [r0] 37; ENABLE-V4T-NEXT: movs r0, #0 38; ENABLE-V4T-NEXT: add r1, sp, #4 39; ENABLE-V4T-NEXT: bl Ltmp0 40; ENABLE-V4T-NEXT: add sp, #8 41; ENABLE-V4T-NEXT: pop {r7} 42; ENABLE-V4T-NEXT: pop {r1} 43; ENABLE-V4T-NEXT: mov lr, r1 44; ENABLE-V4T-NEXT: LBB0_2: @ %false 45; ENABLE-V4T-NEXT: bx lr 46; ENABLE-V4T-NEXT: .p2align 2 47; ENABLE-V4T-NEXT: @ %bb.3: 48; ENABLE-V4T-NEXT: .data_region 49; ENABLE-V4T-NEXT: LCPI0_0: 50; ENABLE-V4T-NEXT: .long L_doSomething$non_lazy_ptr-(LPC0_0+4) 51; ENABLE-V4T-NEXT: .end_data_region 52; 53; ENABLE-V5T-LABEL: foo: 54; ENABLE-V5T: @ %bb.0: 55; ENABLE-V5T-NEXT: cmp r0, r1 56; ENABLE-V5T-NEXT: bge LBB0_2 57; ENABLE-V5T-NEXT: @ %bb.1: @ %true 58; ENABLE-V5T-NEXT: push {r7, lr} 59; ENABLE-V5T-NEXT: .cfi_def_cfa_offset 8 60; ENABLE-V5T-NEXT: .cfi_offset lr, -4 61; ENABLE-V5T-NEXT: .cfi_offset r7, -8 62; ENABLE-V5T-NEXT: sub sp, #8 63; ENABLE-V5T-NEXT: .cfi_def_cfa_offset 16 64; ENABLE-V5T-NEXT: str r0, [sp, #4] 65; ENABLE-V5T-NEXT: movs r0, #0 66; ENABLE-V5T-NEXT: add r1, sp, #4 67; ENABLE-V5T-NEXT: bl _doSomething 68; ENABLE-V5T-NEXT: add sp, #8 69; ENABLE-V5T-NEXT: pop {r7, pc} 70; ENABLE-V5T-NEXT: LBB0_2: @ %false 71; ENABLE-V5T-NEXT: bx lr 72; 73; DISABLE-V4T-LABEL: foo: 74; DISABLE-V4T: @ %bb.0: 75; DISABLE-V4T-NEXT: push {r7, lr} 76; DISABLE-V4T-NEXT: .cfi_def_cfa_offset 8 77; DISABLE-V4T-NEXT: .cfi_offset lr, -4 78; DISABLE-V4T-NEXT: .cfi_offset r7, -8 79; DISABLE-V4T-NEXT: sub sp, #8 80; DISABLE-V4T-NEXT: .cfi_def_cfa_offset 16 81; DISABLE-V4T-NEXT: cmp r0, r1 82; DISABLE-V4T-NEXT: bge LBB0_2 83; DISABLE-V4T-NEXT: @ %bb.1: @ %true 84; DISABLE-V4T-NEXT: str r0, [sp, #4] 85; DISABLE-V4T-NEXT: ldr r0, LCPI0_0 86; DISABLE-V4T-NEXT: LPC0_0: 87; DISABLE-V4T-NEXT: add r0, pc 88; DISABLE-V4T-NEXT: ldr r2, [r0] 89; DISABLE-V4T-NEXT: movs r0, #0 90; DISABLE-V4T-NEXT: add r1, sp, #4 91; DISABLE-V4T-NEXT: bl Ltmp0 92; DISABLE-V4T-NEXT: LBB0_2: @ %false 93; DISABLE-V4T-NEXT: add sp, #8 94; DISABLE-V4T-NEXT: pop {r7} 95; DISABLE-V4T-NEXT: pop {r1} 96; DISABLE-V4T-NEXT: bx r1 97; DISABLE-V4T-NEXT: .p2align 2 98; DISABLE-V4T-NEXT: @ %bb.3: 99; DISABLE-V4T-NEXT: .data_region 100; DISABLE-V4T-NEXT: LCPI0_0: 101; DISABLE-V4T-NEXT: .long L_doSomething$non_lazy_ptr-(LPC0_0+4) 102; DISABLE-V4T-NEXT: .end_data_region 103; 104; DISABLE-V5T-LABEL: foo: 105; DISABLE-V5T: @ %bb.0: 106; DISABLE-V5T-NEXT: push {r7, lr} 107; DISABLE-V5T-NEXT: .cfi_def_cfa_offset 8 108; DISABLE-V5T-NEXT: .cfi_offset lr, -4 109; DISABLE-V5T-NEXT: .cfi_offset r7, -8 110; DISABLE-V5T-NEXT: sub sp, #8 111; DISABLE-V5T-NEXT: .cfi_def_cfa_offset 16 112; DISABLE-V5T-NEXT: cmp r0, r1 113; DISABLE-V5T-NEXT: bge LBB0_2 114; DISABLE-V5T-NEXT: @ %bb.1: @ %true 115; DISABLE-V5T-NEXT: str r0, [sp, #4] 116; DISABLE-V5T-NEXT: movs r0, #0 117; DISABLE-V5T-NEXT: add r1, sp, #4 118; DISABLE-V5T-NEXT: bl _doSomething 119; DISABLE-V5T-NEXT: LBB0_2: @ %false 120; DISABLE-V5T-NEXT: add sp, #8 121; DISABLE-V5T-NEXT: pop {r7, pc} 122 %tmp = alloca i32, align 4 123 %tmp2 = icmp slt i32 %a, %b 124 br i1 %tmp2, label %true, label %false 125 126true: 127 store i32 %a, i32* %tmp, align 4 128 %tmp4 = call i32 @doSomething(i32 0, i32* %tmp) 129 br label %false 130 131false: 132 %tmp.0 = phi i32 [ %tmp4, %true ], [ %a, %0 ] 133 ret i32 %tmp.0 134} 135 136 137; Same, but the final BB is non-trivial, so we don't duplicate the return inst. 138define i32 @bar(i32 %a, i32 %b) { 139; ENABLE-V4T-LABEL: bar: 140; ENABLE-V4T: @ %bb.0: 141; ENABLE-V4T-NEXT: cmp r0, r1 142; ENABLE-V4T-NEXT: bge LBB1_2 143; ENABLE-V4T-NEXT: @ %bb.1: @ %true 144; ENABLE-V4T-NEXT: push {r7, lr} 145; ENABLE-V4T-NEXT: .cfi_def_cfa_offset 8 146; ENABLE-V4T-NEXT: .cfi_offset lr, -4 147; ENABLE-V4T-NEXT: .cfi_offset r7, -8 148; ENABLE-V4T-NEXT: sub sp, #8 149; ENABLE-V4T-NEXT: .cfi_def_cfa_offset 16 150; ENABLE-V4T-NEXT: str r0, [sp, #4] 151; ENABLE-V4T-NEXT: ldr r0, LCPI1_0 152; ENABLE-V4T-NEXT: LPC1_0: 153; ENABLE-V4T-NEXT: add r0, pc 154; ENABLE-V4T-NEXT: ldr r2, [r0] 155; ENABLE-V4T-NEXT: movs r0, #0 156; ENABLE-V4T-NEXT: add r1, sp, #4 157; ENABLE-V4T-NEXT: bl Ltmp1 158; ENABLE-V4T-NEXT: add sp, #8 159; ENABLE-V4T-NEXT: pop {r7} 160; ENABLE-V4T-NEXT: pop {r0} 161; ENABLE-V4T-NEXT: mov lr, r0 162; ENABLE-V4T-NEXT: LBB1_2: @ %false 163; ENABLE-V4T-NEXT: movs r0, #42 164; ENABLE-V4T-NEXT: bx lr 165; ENABLE-V4T-NEXT: .p2align 2 166; ENABLE-V4T-NEXT: @ %bb.3: 167; ENABLE-V4T-NEXT: .data_region 168; ENABLE-V4T-NEXT: LCPI1_0: 169; ENABLE-V4T-NEXT: .long L_doSomething$non_lazy_ptr-(LPC1_0+4) 170; ENABLE-V4T-NEXT: .end_data_region 171; 172; ENABLE-V5T-LABEL: bar: 173; ENABLE-V5T: @ %bb.0: 174; ENABLE-V5T-NEXT: cmp r0, r1 175; ENABLE-V5T-NEXT: bge LBB1_2 176; ENABLE-V5T-NEXT: @ %bb.1: @ %true 177; ENABLE-V5T-NEXT: push {r7, lr} 178; ENABLE-V5T-NEXT: .cfi_def_cfa_offset 8 179; ENABLE-V5T-NEXT: .cfi_offset lr, -4 180; ENABLE-V5T-NEXT: .cfi_offset r7, -8 181; ENABLE-V5T-NEXT: sub sp, #8 182; ENABLE-V5T-NEXT: .cfi_def_cfa_offset 16 183; ENABLE-V5T-NEXT: str r0, [sp, #4] 184; ENABLE-V5T-NEXT: movs r0, #0 185; ENABLE-V5T-NEXT: add r1, sp, #4 186; ENABLE-V5T-NEXT: bl _doSomething 187; ENABLE-V5T-NEXT: add sp, #8 188; ENABLE-V5T-NEXT: pop {r7} 189; ENABLE-V5T-NEXT: pop {r0} 190; ENABLE-V5T-NEXT: mov lr, r0 191; ENABLE-V5T-NEXT: LBB1_2: @ %false 192; ENABLE-V5T-NEXT: movs r0, #42 193; ENABLE-V5T-NEXT: bx lr 194; 195; DISABLE-V4T-LABEL: bar: 196; DISABLE-V4T: @ %bb.0: 197; DISABLE-V4T-NEXT: push {r7, lr} 198; DISABLE-V4T-NEXT: .cfi_def_cfa_offset 8 199; DISABLE-V4T-NEXT: .cfi_offset lr, -4 200; DISABLE-V4T-NEXT: .cfi_offset r7, -8 201; DISABLE-V4T-NEXT: sub sp, #8 202; DISABLE-V4T-NEXT: .cfi_def_cfa_offset 16 203; DISABLE-V4T-NEXT: cmp r0, r1 204; DISABLE-V4T-NEXT: bge LBB1_2 205; DISABLE-V4T-NEXT: @ %bb.1: @ %true 206; DISABLE-V4T-NEXT: str r0, [sp, #4] 207; DISABLE-V4T-NEXT: ldr r0, LCPI1_0 208; DISABLE-V4T-NEXT: LPC1_0: 209; DISABLE-V4T-NEXT: add r0, pc 210; DISABLE-V4T-NEXT: ldr r2, [r0] 211; DISABLE-V4T-NEXT: movs r0, #0 212; DISABLE-V4T-NEXT: add r1, sp, #4 213; DISABLE-V4T-NEXT: bl Ltmp1 214; DISABLE-V4T-NEXT: LBB1_2: @ %false 215; DISABLE-V4T-NEXT: movs r0, #42 216; DISABLE-V4T-NEXT: add sp, #8 217; DISABLE-V4T-NEXT: pop {r7} 218; DISABLE-V4T-NEXT: pop {r1} 219; DISABLE-V4T-NEXT: bx r1 220; DISABLE-V4T-NEXT: .p2align 2 221; DISABLE-V4T-NEXT: @ %bb.3: 222; DISABLE-V4T-NEXT: .data_region 223; DISABLE-V4T-NEXT: LCPI1_0: 224; DISABLE-V4T-NEXT: .long L_doSomething$non_lazy_ptr-(LPC1_0+4) 225; DISABLE-V4T-NEXT: .end_data_region 226; 227; DISABLE-V5T-LABEL: bar: 228; DISABLE-V5T: @ %bb.0: 229; DISABLE-V5T-NEXT: push {r7, lr} 230; DISABLE-V5T-NEXT: .cfi_def_cfa_offset 8 231; DISABLE-V5T-NEXT: .cfi_offset lr, -4 232; DISABLE-V5T-NEXT: .cfi_offset r7, -8 233; DISABLE-V5T-NEXT: sub sp, #8 234; DISABLE-V5T-NEXT: .cfi_def_cfa_offset 16 235; DISABLE-V5T-NEXT: cmp r0, r1 236; DISABLE-V5T-NEXT: bge LBB1_2 237; DISABLE-V5T-NEXT: @ %bb.1: @ %true 238; DISABLE-V5T-NEXT: str r0, [sp, #4] 239; DISABLE-V5T-NEXT: movs r0, #0 240; DISABLE-V5T-NEXT: add r1, sp, #4 241; DISABLE-V5T-NEXT: bl _doSomething 242; DISABLE-V5T-NEXT: LBB1_2: @ %false 243; DISABLE-V5T-NEXT: movs r0, #42 244; DISABLE-V5T-NEXT: add sp, #8 245; DISABLE-V5T-NEXT: pop {r7, pc} 246 %tmp = alloca i32, align 4 247 %tmp2 = icmp slt i32 %a, %b 248 br i1 %tmp2, label %true, label %false 249 250true: 251 store i32 %a, i32* %tmp, align 4 252 %tmp4 = call i32 @doSomething(i32 0, i32* %tmp) 253 br label %false 254 255false: 256 ret i32 42 257} 258 259; Function Attrs: optsize 260declare i32 @doSomething(i32, i32*) 261 262 263; Check that we do not perform the restore inside the loop whereas the save 264; is outside. 265define i32 @freqSaveAndRestoreOutsideLoop(i32 %cond, i32 %N) { 266; ENABLE-V4T-LABEL: freqSaveAndRestoreOutsideLoop: 267; ENABLE-V4T: @ %bb.0: @ %entry 268; ENABLE-V4T-NEXT: cmp r0, #0 269; ENABLE-V4T-NEXT: beq LBB2_4 270; ENABLE-V4T-NEXT: @ %bb.1: @ %for.preheader 271; ENABLE-V4T-NEXT: push {r4, lr} 272; ENABLE-V4T-NEXT: .cfi_def_cfa_offset 8 273; ENABLE-V4T-NEXT: .cfi_offset lr, -4 274; ENABLE-V4T-NEXT: .cfi_offset r4, -8 275; ENABLE-V4T-NEXT: @ InlineAsm Start 276; ENABLE-V4T-NEXT: mov r8, r8 277; ENABLE-V4T-NEXT: @ InlineAsm End 278; ENABLE-V4T-NEXT: movs r0, #0 279; ENABLE-V4T-NEXT: movs r1, #10 280; ENABLE-V4T-NEXT: LBB2_2: @ %for.body 281; ENABLE-V4T-NEXT: @ =>This Inner Loop Header: Depth=1 282; ENABLE-V4T-NEXT: @ InlineAsm Start 283; ENABLE-V4T-NEXT: movs r2, #1 284; ENABLE-V4T-NEXT: @ InlineAsm End 285; ENABLE-V4T-NEXT: adds r0, r2, r0 286; ENABLE-V4T-NEXT: subs r1, r1, #1 287; ENABLE-V4T-NEXT: bne LBB2_2 288; ENABLE-V4T-NEXT: @ %bb.3: @ %for.end 289; ENABLE-V4T-NEXT: lsls r0, r0, #3 290; ENABLE-V4T-NEXT: pop {r4} 291; ENABLE-V4T-NEXT: pop {r1} 292; ENABLE-V4T-NEXT: bx r1 293; ENABLE-V4T-NEXT: LBB2_4: @ %if.else 294; ENABLE-V4T-NEXT: lsls r0, r1, #1 295; ENABLE-V4T-NEXT: bx lr 296; 297; ENABLE-V5T-LABEL: freqSaveAndRestoreOutsideLoop: 298; ENABLE-V5T: @ %bb.0: @ %entry 299; ENABLE-V5T-NEXT: cmp r0, #0 300; ENABLE-V5T-NEXT: beq LBB2_4 301; ENABLE-V5T-NEXT: @ %bb.1: @ %for.preheader 302; ENABLE-V5T-NEXT: push {r4, lr} 303; ENABLE-V5T-NEXT: .cfi_def_cfa_offset 8 304; ENABLE-V5T-NEXT: .cfi_offset lr, -4 305; ENABLE-V5T-NEXT: .cfi_offset r4, -8 306; ENABLE-V5T-NEXT: @ InlineAsm Start 307; ENABLE-V5T-NEXT: mov r8, r8 308; ENABLE-V5T-NEXT: @ InlineAsm End 309; ENABLE-V5T-NEXT: movs r0, #0 310; ENABLE-V5T-NEXT: movs r1, #10 311; ENABLE-V5T-NEXT: LBB2_2: @ %for.body 312; ENABLE-V5T-NEXT: @ =>This Inner Loop Header: Depth=1 313; ENABLE-V5T-NEXT: @ InlineAsm Start 314; ENABLE-V5T-NEXT: movs r2, #1 315; ENABLE-V5T-NEXT: @ InlineAsm End 316; ENABLE-V5T-NEXT: adds r0, r2, r0 317; ENABLE-V5T-NEXT: subs r1, r1, #1 318; ENABLE-V5T-NEXT: bne LBB2_2 319; ENABLE-V5T-NEXT: @ %bb.3: @ %for.end 320; ENABLE-V5T-NEXT: lsls r0, r0, #3 321; ENABLE-V5T-NEXT: pop {r4, pc} 322; ENABLE-V5T-NEXT: LBB2_4: @ %if.else 323; ENABLE-V5T-NEXT: lsls r0, r1, #1 324; ENABLE-V5T-NEXT: LBB2_5: @ %if.end 325; ENABLE-V5T-NEXT: bx lr 326; 327; DISABLE-V4T-LABEL: freqSaveAndRestoreOutsideLoop: 328; DISABLE-V4T: @ %bb.0: @ %entry 329; DISABLE-V4T-NEXT: push {r4, lr} 330; DISABLE-V4T-NEXT: .cfi_def_cfa_offset 8 331; DISABLE-V4T-NEXT: .cfi_offset lr, -4 332; DISABLE-V4T-NEXT: .cfi_offset r4, -8 333; DISABLE-V4T-NEXT: cmp r0, #0 334; DISABLE-V4T-NEXT: beq LBB2_4 335; DISABLE-V4T-NEXT: @ %bb.1: @ %for.preheader 336; DISABLE-V4T-NEXT: @ InlineAsm Start 337; DISABLE-V4T-NEXT: mov r8, r8 338; DISABLE-V4T-NEXT: @ InlineAsm End 339; DISABLE-V4T-NEXT: movs r0, #0 340; DISABLE-V4T-NEXT: movs r1, #10 341; DISABLE-V4T-NEXT: LBB2_2: @ %for.body 342; DISABLE-V4T-NEXT: @ =>This Inner Loop Header: Depth=1 343; DISABLE-V4T-NEXT: @ InlineAsm Start 344; DISABLE-V4T-NEXT: movs r2, #1 345; DISABLE-V4T-NEXT: @ InlineAsm End 346; DISABLE-V4T-NEXT: adds r0, r2, r0 347; DISABLE-V4T-NEXT: subs r1, r1, #1 348; DISABLE-V4T-NEXT: bne LBB2_2 349; DISABLE-V4T-NEXT: @ %bb.3: @ %for.end 350; DISABLE-V4T-NEXT: lsls r0, r0, #3 351; DISABLE-V4T-NEXT: b LBB2_5 352; DISABLE-V4T-NEXT: LBB2_4: @ %if.else 353; DISABLE-V4T-NEXT: lsls r0, r1, #1 354; DISABLE-V4T-NEXT: LBB2_5: @ %if.end 355; DISABLE-V4T-NEXT: pop {r4} 356; DISABLE-V4T-NEXT: pop {r1} 357; DISABLE-V4T-NEXT: bx r1 358; 359; DISABLE-V5T-LABEL: freqSaveAndRestoreOutsideLoop: 360; DISABLE-V5T: @ %bb.0: @ %entry 361; DISABLE-V5T-NEXT: push {r4, lr} 362; DISABLE-V5T-NEXT: .cfi_def_cfa_offset 8 363; DISABLE-V5T-NEXT: .cfi_offset lr, -4 364; DISABLE-V5T-NEXT: .cfi_offset r4, -8 365; DISABLE-V5T-NEXT: cmp r0, #0 366; DISABLE-V5T-NEXT: beq LBB2_4 367; DISABLE-V5T-NEXT: @ %bb.1: @ %for.preheader 368; DISABLE-V5T-NEXT: @ InlineAsm Start 369; DISABLE-V5T-NEXT: mov r8, r8 370; DISABLE-V5T-NEXT: @ InlineAsm End 371; DISABLE-V5T-NEXT: movs r0, #0 372; DISABLE-V5T-NEXT: movs r1, #10 373; DISABLE-V5T-NEXT: LBB2_2: @ %for.body 374; DISABLE-V5T-NEXT: @ =>This Inner Loop Header: Depth=1 375; DISABLE-V5T-NEXT: @ InlineAsm Start 376; DISABLE-V5T-NEXT: movs r2, #1 377; DISABLE-V5T-NEXT: @ InlineAsm End 378; DISABLE-V5T-NEXT: adds r0, r2, r0 379; DISABLE-V5T-NEXT: subs r1, r1, #1 380; DISABLE-V5T-NEXT: bne LBB2_2 381; DISABLE-V5T-NEXT: @ %bb.3: @ %for.end 382; DISABLE-V5T-NEXT: lsls r0, r0, #3 383; DISABLE-V5T-NEXT: pop {r4, pc} 384; DISABLE-V5T-NEXT: LBB2_4: @ %if.else 385; DISABLE-V5T-NEXT: lsls r0, r1, #1 386; DISABLE-V5T-NEXT: pop {r4, pc} 387entry: 388 %tobool = icmp eq i32 %cond, 0 389 br i1 %tobool, label %if.else, label %for.preheader 390 391for.preheader: 392 tail call void asm "nop", ""() 393 br label %for.body 394 395for.body: ; preds = %entry, %for.body 396 %i.05 = phi i32 [ %inc, %for.body ], [ 0, %for.preheader ] 397 %sum.04 = phi i32 [ %add, %for.body ], [ 0, %for.preheader ] 398 %call = tail call i32 asm sideeffect "movs $0, #1", "=r,~{r4}"() 399 %add = add nsw i32 %call, %sum.04 400 %inc = add nuw nsw i32 %i.05, 1 401 %exitcond = icmp eq i32 %inc, 10 402 br i1 %exitcond, label %for.end, label %for.body 403 404for.end: ; preds = %for.body 405 %shl = shl i32 %add, 3 406 br label %if.end 407 408if.else: ; preds = %entry 409 %mul = shl nsw i32 %N, 1 410 br label %if.end 411 412if.end: ; preds = %if.else, %for.end 413 %sum.1 = phi i32 [ %shl, %for.end ], [ %mul, %if.else ] 414 ret i32 %sum.1 415} 416 417declare i32 @something(...) 418 419; Check that we do not perform the shrink-wrapping inside the loop even 420; though that would be legal. The cost model must prevent that. 421define i32 @freqSaveAndRestoreOutsideLoop2(i32 %cond) { 422; ENABLE-V4T-LABEL: freqSaveAndRestoreOutsideLoop2: 423; ENABLE-V4T: @ %bb.0: @ %entry 424; ENABLE-V4T-NEXT: push {r4, lr} 425; ENABLE-V4T-NEXT: .cfi_def_cfa_offset 8 426; ENABLE-V4T-NEXT: .cfi_offset lr, -4 427; ENABLE-V4T-NEXT: .cfi_offset r4, -8 428; ENABLE-V4T-NEXT: @ InlineAsm Start 429; ENABLE-V4T-NEXT: mov r8, r8 430; ENABLE-V4T-NEXT: @ InlineAsm End 431; ENABLE-V4T-NEXT: movs r0, #0 432; ENABLE-V4T-NEXT: movs r1, #10 433; ENABLE-V4T-NEXT: LBB3_1: @ %for.body 434; ENABLE-V4T-NEXT: @ =>This Inner Loop Header: Depth=1 435; ENABLE-V4T-NEXT: @ InlineAsm Start 436; ENABLE-V4T-NEXT: movs r2, #1 437; ENABLE-V4T-NEXT: @ InlineAsm End 438; ENABLE-V4T-NEXT: adds r0, r2, r0 439; ENABLE-V4T-NEXT: subs r1, r1, #1 440; ENABLE-V4T-NEXT: bne LBB3_1 441; ENABLE-V4T-NEXT: @ %bb.2: @ %for.exit 442; ENABLE-V4T-NEXT: @ InlineAsm Start 443; ENABLE-V4T-NEXT: mov r8, r8 444; ENABLE-V4T-NEXT: @ InlineAsm End 445; ENABLE-V4T-NEXT: pop {r4} 446; ENABLE-V4T-NEXT: pop {r1} 447; ENABLE-V4T-NEXT: bx r1 448; 449; ENABLE-V5T-LABEL: freqSaveAndRestoreOutsideLoop2: 450; ENABLE-V5T: @ %bb.0: @ %entry 451; ENABLE-V5T-NEXT: push {r4, lr} 452; ENABLE-V5T-NEXT: .cfi_def_cfa_offset 8 453; ENABLE-V5T-NEXT: .cfi_offset lr, -4 454; ENABLE-V5T-NEXT: .cfi_offset r4, -8 455; ENABLE-V5T-NEXT: @ InlineAsm Start 456; ENABLE-V5T-NEXT: mov r8, r8 457; ENABLE-V5T-NEXT: @ InlineAsm End 458; ENABLE-V5T-NEXT: movs r0, #0 459; ENABLE-V5T-NEXT: movs r1, #10 460; ENABLE-V5T-NEXT: LBB3_1: @ %for.body 461; ENABLE-V5T-NEXT: @ =>This Inner Loop Header: Depth=1 462; ENABLE-V5T-NEXT: @ InlineAsm Start 463; ENABLE-V5T-NEXT: movs r2, #1 464; ENABLE-V5T-NEXT: @ InlineAsm End 465; ENABLE-V5T-NEXT: adds r0, r2, r0 466; ENABLE-V5T-NEXT: subs r1, r1, #1 467; ENABLE-V5T-NEXT: bne LBB3_1 468; ENABLE-V5T-NEXT: @ %bb.2: @ %for.exit 469; ENABLE-V5T-NEXT: @ InlineAsm Start 470; ENABLE-V5T-NEXT: mov r8, r8 471; ENABLE-V5T-NEXT: @ InlineAsm End 472; ENABLE-V5T-NEXT: pop {r4, pc} 473; ENABLE-V5T-NEXT: LBB3_3: @ %for.end 474; ENABLE-V5T-NEXT: bx lr 475; 476; DISABLE-V4T-LABEL: freqSaveAndRestoreOutsideLoop2: 477; DISABLE-V4T: @ %bb.0: @ %entry 478; DISABLE-V4T-NEXT: push {r4, lr} 479; DISABLE-V4T-NEXT: .cfi_def_cfa_offset 8 480; DISABLE-V4T-NEXT: .cfi_offset lr, -4 481; DISABLE-V4T-NEXT: .cfi_offset r4, -8 482; DISABLE-V4T-NEXT: @ InlineAsm Start 483; DISABLE-V4T-NEXT: mov r8, r8 484; DISABLE-V4T-NEXT: @ InlineAsm End 485; DISABLE-V4T-NEXT: movs r0, #0 486; DISABLE-V4T-NEXT: movs r1, #10 487; DISABLE-V4T-NEXT: LBB3_1: @ %for.body 488; DISABLE-V4T-NEXT: @ =>This Inner Loop Header: Depth=1 489; DISABLE-V4T-NEXT: @ InlineAsm Start 490; DISABLE-V4T-NEXT: movs r2, #1 491; DISABLE-V4T-NEXT: @ InlineAsm End 492; DISABLE-V4T-NEXT: adds r0, r2, r0 493; DISABLE-V4T-NEXT: subs r1, r1, #1 494; DISABLE-V4T-NEXT: bne LBB3_1 495; DISABLE-V4T-NEXT: @ %bb.2: @ %for.exit 496; DISABLE-V4T-NEXT: @ InlineAsm Start 497; DISABLE-V4T-NEXT: mov r8, r8 498; DISABLE-V4T-NEXT: @ InlineAsm End 499; DISABLE-V4T-NEXT: pop {r4} 500; DISABLE-V4T-NEXT: pop {r1} 501; DISABLE-V4T-NEXT: bx r1 502; 503; DISABLE-V5T-LABEL: freqSaveAndRestoreOutsideLoop2: 504; DISABLE-V5T: @ %bb.0: @ %entry 505; DISABLE-V5T-NEXT: push {r4, lr} 506; DISABLE-V5T-NEXT: .cfi_def_cfa_offset 8 507; DISABLE-V5T-NEXT: .cfi_offset lr, -4 508; DISABLE-V5T-NEXT: .cfi_offset r4, -8 509; DISABLE-V5T-NEXT: @ InlineAsm Start 510; DISABLE-V5T-NEXT: mov r8, r8 511; DISABLE-V5T-NEXT: @ InlineAsm End 512; DISABLE-V5T-NEXT: movs r0, #0 513; DISABLE-V5T-NEXT: movs r1, #10 514; DISABLE-V5T-NEXT: LBB3_1: @ %for.body 515; DISABLE-V5T-NEXT: @ =>This Inner Loop Header: Depth=1 516; DISABLE-V5T-NEXT: @ InlineAsm Start 517; DISABLE-V5T-NEXT: movs r2, #1 518; DISABLE-V5T-NEXT: @ InlineAsm End 519; DISABLE-V5T-NEXT: adds r0, r2, r0 520; DISABLE-V5T-NEXT: subs r1, r1, #1 521; DISABLE-V5T-NEXT: bne LBB3_1 522; DISABLE-V5T-NEXT: @ %bb.2: @ %for.exit 523; DISABLE-V5T-NEXT: @ InlineAsm Start 524; DISABLE-V5T-NEXT: mov r8, r8 525; DISABLE-V5T-NEXT: @ InlineAsm End 526; DISABLE-V5T-NEXT: pop {r4, pc} 527entry: 528 br label %for.preheader 529 530for.preheader: 531 tail call void asm "nop", ""() 532 br label %for.body 533 534for.body: ; preds = %for.body, %entry 535 %i.04 = phi i32 [ 0, %for.preheader ], [ %inc, %for.body ] 536 %sum.03 = phi i32 [ 0, %for.preheader ], [ %add, %for.body ] 537 %call = tail call i32 asm sideeffect "movs $0, #1", "=r,~{r4}"() 538 %add = add nsw i32 %call, %sum.03 539 %inc = add nuw nsw i32 %i.04, 1 540 %exitcond = icmp eq i32 %inc, 10 541 br i1 %exitcond, label %for.exit, label %for.body 542 543for.exit: 544 tail call void asm "nop", ""() 545 br label %for.end 546 547for.end: ; preds = %for.body 548 ret i32 %add 549} 550 551; Check with a more complex case that we do not have save within the loop and 552; restore outside. 553define i32 @loopInfoSaveOutsideLoop(i32 %cond, i32 %N) { 554; ENABLE-V4T-LABEL: loopInfoSaveOutsideLoop: 555; ENABLE-V4T: @ %bb.0: @ %entry 556; ENABLE-V4T-NEXT: cmp r0, #0 557; ENABLE-V4T-NEXT: beq LBB4_4 558; ENABLE-V4T-NEXT: @ %bb.1: @ %for.preheader 559; ENABLE-V4T-NEXT: push {r4, lr} 560; ENABLE-V4T-NEXT: .cfi_def_cfa_offset 8 561; ENABLE-V4T-NEXT: .cfi_offset lr, -4 562; ENABLE-V4T-NEXT: .cfi_offset r4, -8 563; ENABLE-V4T-NEXT: @ InlineAsm Start 564; ENABLE-V4T-NEXT: mov r8, r8 565; ENABLE-V4T-NEXT: @ InlineAsm End 566; ENABLE-V4T-NEXT: movs r0, #0 567; ENABLE-V4T-NEXT: movs r1, #10 568; ENABLE-V4T-NEXT: LBB4_2: @ %for.body 569; ENABLE-V4T-NEXT: @ =>This Inner Loop Header: Depth=1 570; ENABLE-V4T-NEXT: @ InlineAsm Start 571; ENABLE-V4T-NEXT: movs r2, #1 572; ENABLE-V4T-NEXT: @ InlineAsm End 573; ENABLE-V4T-NEXT: adds r0, r2, r0 574; ENABLE-V4T-NEXT: subs r1, r1, #1 575; ENABLE-V4T-NEXT: bne LBB4_2 576; ENABLE-V4T-NEXT: @ %bb.3: @ %for.end 577; ENABLE-V4T-NEXT: @ InlineAsm Start 578; ENABLE-V4T-NEXT: mov r8, r8 579; ENABLE-V4T-NEXT: @ InlineAsm End 580; ENABLE-V4T-NEXT: lsls r0, r0, #3 581; ENABLE-V4T-NEXT: pop {r4} 582; ENABLE-V4T-NEXT: pop {r1} 583; ENABLE-V4T-NEXT: bx r1 584; ENABLE-V4T-NEXT: LBB4_4: @ %if.else 585; ENABLE-V4T-NEXT: lsls r0, r1, #1 586; ENABLE-V4T-NEXT: bx lr 587; 588; ENABLE-V5T-LABEL: loopInfoSaveOutsideLoop: 589; ENABLE-V5T: @ %bb.0: @ %entry 590; ENABLE-V5T-NEXT: cmp r0, #0 591; ENABLE-V5T-NEXT: beq LBB4_4 592; ENABLE-V5T-NEXT: @ %bb.1: @ %for.preheader 593; ENABLE-V5T-NEXT: push {r4, lr} 594; ENABLE-V5T-NEXT: .cfi_def_cfa_offset 8 595; ENABLE-V5T-NEXT: .cfi_offset lr, -4 596; ENABLE-V5T-NEXT: .cfi_offset r4, -8 597; ENABLE-V5T-NEXT: @ InlineAsm Start 598; ENABLE-V5T-NEXT: mov r8, r8 599; ENABLE-V5T-NEXT: @ InlineAsm End 600; ENABLE-V5T-NEXT: movs r0, #0 601; ENABLE-V5T-NEXT: movs r1, #10 602; ENABLE-V5T-NEXT: LBB4_2: @ %for.body 603; ENABLE-V5T-NEXT: @ =>This Inner Loop Header: Depth=1 604; ENABLE-V5T-NEXT: @ InlineAsm Start 605; ENABLE-V5T-NEXT: movs r2, #1 606; ENABLE-V5T-NEXT: @ InlineAsm End 607; ENABLE-V5T-NEXT: adds r0, r2, r0 608; ENABLE-V5T-NEXT: subs r1, r1, #1 609; ENABLE-V5T-NEXT: bne LBB4_2 610; ENABLE-V5T-NEXT: @ %bb.3: @ %for.end 611; ENABLE-V5T-NEXT: @ InlineAsm Start 612; ENABLE-V5T-NEXT: mov r8, r8 613; ENABLE-V5T-NEXT: @ InlineAsm End 614; ENABLE-V5T-NEXT: lsls r0, r0, #3 615; ENABLE-V5T-NEXT: pop {r4, pc} 616; ENABLE-V5T-NEXT: LBB4_4: @ %if.else 617; ENABLE-V5T-NEXT: lsls r0, r1, #1 618; ENABLE-V5T-NEXT: LBB4_5: @ %if.end 619; ENABLE-V5T-NEXT: bx lr 620; 621; DISABLE-V4T-LABEL: loopInfoSaveOutsideLoop: 622; DISABLE-V4T: @ %bb.0: @ %entry 623; DISABLE-V4T-NEXT: push {r4, lr} 624; DISABLE-V4T-NEXT: .cfi_def_cfa_offset 8 625; DISABLE-V4T-NEXT: .cfi_offset lr, -4 626; DISABLE-V4T-NEXT: .cfi_offset r4, -8 627; DISABLE-V4T-NEXT: cmp r0, #0 628; DISABLE-V4T-NEXT: beq LBB4_4 629; DISABLE-V4T-NEXT: @ %bb.1: @ %for.preheader 630; DISABLE-V4T-NEXT: @ InlineAsm Start 631; DISABLE-V4T-NEXT: mov r8, r8 632; DISABLE-V4T-NEXT: @ InlineAsm End 633; DISABLE-V4T-NEXT: movs r0, #0 634; DISABLE-V4T-NEXT: movs r1, #10 635; DISABLE-V4T-NEXT: LBB4_2: @ %for.body 636; DISABLE-V4T-NEXT: @ =>This Inner Loop Header: Depth=1 637; DISABLE-V4T-NEXT: @ InlineAsm Start 638; DISABLE-V4T-NEXT: movs r2, #1 639; DISABLE-V4T-NEXT: @ InlineAsm End 640; DISABLE-V4T-NEXT: adds r0, r2, r0 641; DISABLE-V4T-NEXT: subs r1, r1, #1 642; DISABLE-V4T-NEXT: bne LBB4_2 643; DISABLE-V4T-NEXT: @ %bb.3: @ %for.end 644; DISABLE-V4T-NEXT: @ InlineAsm Start 645; DISABLE-V4T-NEXT: mov r8, r8 646; DISABLE-V4T-NEXT: @ InlineAsm End 647; DISABLE-V4T-NEXT: lsls r0, r0, #3 648; DISABLE-V4T-NEXT: b LBB4_5 649; DISABLE-V4T-NEXT: LBB4_4: @ %if.else 650; DISABLE-V4T-NEXT: lsls r0, r1, #1 651; DISABLE-V4T-NEXT: LBB4_5: @ %if.end 652; DISABLE-V4T-NEXT: pop {r4} 653; DISABLE-V4T-NEXT: pop {r1} 654; DISABLE-V4T-NEXT: bx r1 655; 656; DISABLE-V5T-LABEL: loopInfoSaveOutsideLoop: 657; DISABLE-V5T: @ %bb.0: @ %entry 658; DISABLE-V5T-NEXT: push {r4, lr} 659; DISABLE-V5T-NEXT: .cfi_def_cfa_offset 8 660; DISABLE-V5T-NEXT: .cfi_offset lr, -4 661; DISABLE-V5T-NEXT: .cfi_offset r4, -8 662; DISABLE-V5T-NEXT: cmp r0, #0 663; DISABLE-V5T-NEXT: beq LBB4_4 664; DISABLE-V5T-NEXT: @ %bb.1: @ %for.preheader 665; DISABLE-V5T-NEXT: @ InlineAsm Start 666; DISABLE-V5T-NEXT: mov r8, r8 667; DISABLE-V5T-NEXT: @ InlineAsm End 668; DISABLE-V5T-NEXT: movs r0, #0 669; DISABLE-V5T-NEXT: movs r1, #10 670; DISABLE-V5T-NEXT: LBB4_2: @ %for.body 671; DISABLE-V5T-NEXT: @ =>This Inner Loop Header: Depth=1 672; DISABLE-V5T-NEXT: @ InlineAsm Start 673; DISABLE-V5T-NEXT: movs r2, #1 674; DISABLE-V5T-NEXT: @ InlineAsm End 675; DISABLE-V5T-NEXT: adds r0, r2, r0 676; DISABLE-V5T-NEXT: subs r1, r1, #1 677; DISABLE-V5T-NEXT: bne LBB4_2 678; DISABLE-V5T-NEXT: @ %bb.3: @ %for.end 679; DISABLE-V5T-NEXT: @ InlineAsm Start 680; DISABLE-V5T-NEXT: mov r8, r8 681; DISABLE-V5T-NEXT: @ InlineAsm End 682; DISABLE-V5T-NEXT: lsls r0, r0, #3 683; DISABLE-V5T-NEXT: pop {r4, pc} 684; DISABLE-V5T-NEXT: LBB4_4: @ %if.else 685; DISABLE-V5T-NEXT: lsls r0, r1, #1 686; DISABLE-V5T-NEXT: pop {r4, pc} 687entry: 688 %tobool = icmp eq i32 %cond, 0 689 br i1 %tobool, label %if.else, label %for.preheader 690 691for.preheader: 692 tail call void asm "nop", ""() 693 br label %for.body 694 695for.body: ; preds = %entry, %for.body 696 %i.05 = phi i32 [ %inc, %for.body ], [ 0, %for.preheader ] 697 %sum.04 = phi i32 [ %add, %for.body ], [ 0, %for.preheader ] 698 %call = tail call i32 asm sideeffect "movs $0, #1", "=r,~{r4}"() 699 %add = add nsw i32 %call, %sum.04 700 %inc = add nuw nsw i32 %i.05, 1 701 %exitcond = icmp eq i32 %inc, 10 702 br i1 %exitcond, label %for.end, label %for.body 703 704for.end: ; preds = %for.body 705 tail call void asm "nop", "~{r4}"() 706 %shl = shl i32 %add, 3 707 br label %if.end 708 709if.else: ; preds = %entry 710 %mul = shl nsw i32 %N, 1 711 br label %if.end 712 713if.end: ; preds = %if.else, %for.end 714 %sum.1 = phi i32 [ %shl, %for.end ], [ %mul, %if.else ] 715 ret i32 %sum.1 716} 717 718declare void @somethingElse(...) 719 720; Check with a more complex case that we do not have restore within the loop and 721; save outside. 722define i32 @loopInfoRestoreOutsideLoop(i32 %cond, i32 %N) nounwind { 723; ENABLE-V4T-LABEL: loopInfoRestoreOutsideLoop: 724; ENABLE-V4T: @ %bb.0: @ %entry 725; ENABLE-V4T-NEXT: cmp r0, #0 726; ENABLE-V4T-NEXT: beq LBB5_4 727; ENABLE-V4T-NEXT: @ %bb.1: @ %if.then 728; ENABLE-V4T-NEXT: push {r4, lr} 729; ENABLE-V4T-NEXT: @ InlineAsm Start 730; ENABLE-V4T-NEXT: mov r8, r8 731; ENABLE-V4T-NEXT: @ InlineAsm End 732; ENABLE-V4T-NEXT: movs r0, #0 733; ENABLE-V4T-NEXT: movs r1, #10 734; ENABLE-V4T-NEXT: LBB5_2: @ %for.body 735; ENABLE-V4T-NEXT: @ =>This Inner Loop Header: Depth=1 736; ENABLE-V4T-NEXT: @ InlineAsm Start 737; ENABLE-V4T-NEXT: movs r2, #1 738; ENABLE-V4T-NEXT: @ InlineAsm End 739; ENABLE-V4T-NEXT: adds r0, r2, r0 740; ENABLE-V4T-NEXT: subs r1, r1, #1 741; ENABLE-V4T-NEXT: bne LBB5_2 742; ENABLE-V4T-NEXT: @ %bb.3: @ %for.end 743; ENABLE-V4T-NEXT: lsls r0, r0, #3 744; ENABLE-V4T-NEXT: pop {r4} 745; ENABLE-V4T-NEXT: pop {r1} 746; ENABLE-V4T-NEXT: bx r1 747; ENABLE-V4T-NEXT: LBB5_4: @ %if.else 748; ENABLE-V4T-NEXT: lsls r0, r1, #1 749; ENABLE-V4T-NEXT: bx lr 750; ENABLE-V4T-NEXT: @ -- End function 751; ENABLE-V4T-NEXT: .globl _emptyFrame @ -- Begin function emptyFrame 752; ENABLE-V4T-NEXT: .p2align 1 753; ENABLE-V4T-NEXT: .code 16 @ @emptyFrame 754; ENABLE-V4T-NEXT: .thumb_func _emptyFrame 755; ENABLE-V4T-NEXT: _emptyFrame: 756; ENABLE-V4T-NEXT: .cfi_startproc 757; ENABLE-V4T-NEXT: @ %bb.0: @ %entry 758; ENABLE-V4T-NEXT: movs r0, #0 759; ENABLE-V4T-NEXT: bx lr 760; 761; ENABLE-V5T-LABEL: loopInfoRestoreOutsideLoop: 762; ENABLE-V5T: @ %bb.0: @ %entry 763; ENABLE-V5T-NEXT: cmp r0, #0 764; ENABLE-V5T-NEXT: beq LBB5_4 765; ENABLE-V5T-NEXT: @ %bb.1: @ %if.then 766; ENABLE-V5T-NEXT: push {r4, lr} 767; ENABLE-V5T-NEXT: @ InlineAsm Start 768; ENABLE-V5T-NEXT: mov r8, r8 769; ENABLE-V5T-NEXT: @ InlineAsm End 770; ENABLE-V5T-NEXT: movs r0, #0 771; ENABLE-V5T-NEXT: movs r1, #10 772; ENABLE-V5T-NEXT: LBB5_2: @ %for.body 773; ENABLE-V5T-NEXT: @ =>This Inner Loop Header: Depth=1 774; ENABLE-V5T-NEXT: @ InlineAsm Start 775; ENABLE-V5T-NEXT: movs r2, #1 776; ENABLE-V5T-NEXT: @ InlineAsm End 777; ENABLE-V5T-NEXT: adds r0, r2, r0 778; ENABLE-V5T-NEXT: subs r1, r1, #1 779; ENABLE-V5T-NEXT: bne LBB5_2 780; ENABLE-V5T-NEXT: @ %bb.3: @ %for.end 781; ENABLE-V5T-NEXT: lsls r0, r0, #3 782; ENABLE-V5T-NEXT: pop {r4, pc} 783; ENABLE-V5T-NEXT: LBB5_4: @ %if.else 784; ENABLE-V5T-NEXT: lsls r0, r1, #1 785; ENABLE-V5T-NEXT: LBB5_5: @ %if.end 786; ENABLE-V5T-NEXT: bx lr 787; ENABLE-V5T-NEXT: @ -- End function 788; ENABLE-V5T-NEXT: .globl _emptyFrame @ -- Begin function emptyFrame 789; ENABLE-V5T-NEXT: .p2align 1 790; ENABLE-V5T-NEXT: .code 16 @ @emptyFrame 791; ENABLE-V5T-NEXT: .thumb_func _emptyFrame 792; ENABLE-V5T-NEXT: _emptyFrame: 793; ENABLE-V5T-NEXT: .cfi_startproc 794; ENABLE-V5T-NEXT: @ %bb.0: @ %entry 795; ENABLE-V5T-NEXT: movs r0, #0 796; ENABLE-V5T-NEXT: bx lr 797; 798; DISABLE-V4T-LABEL: loopInfoRestoreOutsideLoop: 799; DISABLE-V4T: @ %bb.0: @ %entry 800; DISABLE-V4T-NEXT: push {r4, lr} 801; DISABLE-V4T-NEXT: cmp r0, #0 802; DISABLE-V4T-NEXT: beq LBB5_4 803; DISABLE-V4T-NEXT: @ %bb.1: @ %if.then 804; DISABLE-V4T-NEXT: @ InlineAsm Start 805; DISABLE-V4T-NEXT: mov r8, r8 806; DISABLE-V4T-NEXT: @ InlineAsm End 807; DISABLE-V4T-NEXT: movs r0, #0 808; DISABLE-V4T-NEXT: movs r1, #10 809; DISABLE-V4T-NEXT: LBB5_2: @ %for.body 810; DISABLE-V4T-NEXT: @ =>This Inner Loop Header: Depth=1 811; DISABLE-V4T-NEXT: @ InlineAsm Start 812; DISABLE-V4T-NEXT: movs r2, #1 813; DISABLE-V4T-NEXT: @ InlineAsm End 814; DISABLE-V4T-NEXT: adds r0, r2, r0 815; DISABLE-V4T-NEXT: subs r1, r1, #1 816; DISABLE-V4T-NEXT: bne LBB5_2 817; DISABLE-V4T-NEXT: @ %bb.3: @ %for.end 818; DISABLE-V4T-NEXT: lsls r0, r0, #3 819; DISABLE-V4T-NEXT: b LBB5_5 820; DISABLE-V4T-NEXT: LBB5_4: @ %if.else 821; DISABLE-V4T-NEXT: lsls r0, r1, #1 822; DISABLE-V4T-NEXT: LBB5_5: @ %if.end 823; DISABLE-V4T-NEXT: pop {r4} 824; DISABLE-V4T-NEXT: pop {r1} 825; DISABLE-V4T-NEXT: bx r1 826; DISABLE-V4T-NEXT: @ -- End function 827; DISABLE-V4T-NEXT: .globl _emptyFrame @ -- Begin function emptyFrame 828; DISABLE-V4T-NEXT: .p2align 1 829; DISABLE-V4T-NEXT: .code 16 @ @emptyFrame 830; DISABLE-V4T-NEXT: .thumb_func _emptyFrame 831; DISABLE-V4T-NEXT: _emptyFrame: 832; DISABLE-V4T-NEXT: .cfi_startproc 833; DISABLE-V4T-NEXT: @ %bb.0: @ %entry 834; DISABLE-V4T-NEXT: movs r0, #0 835; DISABLE-V4T-NEXT: bx lr 836; 837; DISABLE-V5T-LABEL: loopInfoRestoreOutsideLoop: 838; DISABLE-V5T: @ %bb.0: @ %entry 839; DISABLE-V5T-NEXT: push {r4, lr} 840; DISABLE-V5T-NEXT: cmp r0, #0 841; DISABLE-V5T-NEXT: beq LBB5_4 842; DISABLE-V5T-NEXT: @ %bb.1: @ %if.then 843; DISABLE-V5T-NEXT: @ InlineAsm Start 844; DISABLE-V5T-NEXT: mov r8, r8 845; DISABLE-V5T-NEXT: @ InlineAsm End 846; DISABLE-V5T-NEXT: movs r0, #0 847; DISABLE-V5T-NEXT: movs r1, #10 848; DISABLE-V5T-NEXT: LBB5_2: @ %for.body 849; DISABLE-V5T-NEXT: @ =>This Inner Loop Header: Depth=1 850; DISABLE-V5T-NEXT: @ InlineAsm Start 851; DISABLE-V5T-NEXT: movs r2, #1 852; DISABLE-V5T-NEXT: @ InlineAsm End 853; DISABLE-V5T-NEXT: adds r0, r2, r0 854; DISABLE-V5T-NEXT: subs r1, r1, #1 855; DISABLE-V5T-NEXT: bne LBB5_2 856; DISABLE-V5T-NEXT: @ %bb.3: @ %for.end 857; DISABLE-V5T-NEXT: lsls r0, r0, #3 858; DISABLE-V5T-NEXT: pop {r4, pc} 859; DISABLE-V5T-NEXT: LBB5_4: @ %if.else 860; DISABLE-V5T-NEXT: lsls r0, r1, #1 861; DISABLE-V5T-NEXT: pop {r4, pc} 862; DISABLE-V5T-NEXT: @ -- End function 863; DISABLE-V5T-NEXT: .globl _emptyFrame @ -- Begin function emptyFrame 864; DISABLE-V5T-NEXT: .p2align 1 865; DISABLE-V5T-NEXT: .code 16 @ @emptyFrame 866; DISABLE-V5T-NEXT: .thumb_func _emptyFrame 867; DISABLE-V5T-NEXT: _emptyFrame: 868; DISABLE-V5T-NEXT: .cfi_startproc 869; DISABLE-V5T-NEXT: @ %bb.0: @ %entry 870; DISABLE-V5T-NEXT: movs r0, #0 871; DISABLE-V5T-NEXT: bx lr 872entry: 873 %tobool = icmp eq i32 %cond, 0 874 br i1 %tobool, label %if.else, label %if.then 875 876if.then: ; preds = %entry 877 tail call void asm "nop", "~{r4}"() 878 br label %for.body 879 880for.body: ; preds = %for.body, %if.then 881 %i.05 = phi i32 [ 0, %if.then ], [ %inc, %for.body ] 882 %sum.04 = phi i32 [ 0, %if.then ], [ %add, %for.body ] 883 %call = tail call i32 asm sideeffect "movs $0, #1", "=r,~{r4}"() 884 %add = add nsw i32 %call, %sum.04 885 %inc = add nuw nsw i32 %i.05, 1 886 %exitcond = icmp eq i32 %inc, 10 887 br i1 %exitcond, label %for.end, label %for.body 888 889for.end: ; preds = %for.body 890 %shl = shl i32 %add, 3 891 br label %if.end 892 893if.else: ; preds = %entry 894 %mul = shl nsw i32 %N, 1 895 br label %if.end 896 897if.end: ; preds = %if.else, %for.end 898 %sum.1 = phi i32 [ %shl, %for.end ], [ %mul, %if.else ] 899 ret i32 %sum.1 900} 901 902; Check that we handle function with no frame information correctly. 903define i32 @emptyFrame() { 904entry: 905 ret i32 0 906} 907 908; Check that we handle inline asm correctly. 909define i32 @inlineAsm(i32 %cond, i32 %N) { 910; ENABLE-V4T-LABEL: inlineAsm: 911; ENABLE-V4T: @ %bb.0: @ %entry 912; ENABLE-V4T-NEXT: cmp r0, #0 913; ENABLE-V4T-NEXT: beq LBB7_4 914; ENABLE-V4T-NEXT: @ %bb.1: @ %for.preheader 915; ENABLE-V4T-NEXT: push {r4, lr} 916; ENABLE-V4T-NEXT: .cfi_def_cfa_offset 8 917; ENABLE-V4T-NEXT: .cfi_offset lr, -4 918; ENABLE-V4T-NEXT: .cfi_offset r4, -8 919; ENABLE-V4T-NEXT: @ InlineAsm Start 920; ENABLE-V4T-NEXT: mov r8, r8 921; ENABLE-V4T-NEXT: @ InlineAsm End 922; ENABLE-V4T-NEXT: movs r0, #10 923; ENABLE-V4T-NEXT: LBB7_2: @ %for.body 924; ENABLE-V4T-NEXT: @ =>This Inner Loop Header: Depth=1 925; ENABLE-V4T-NEXT: @ InlineAsm Start 926; ENABLE-V4T-NEXT: movs r4, #1 927; ENABLE-V4T-NEXT: @ InlineAsm End 928; ENABLE-V4T-NEXT: subs r0, r0, #1 929; ENABLE-V4T-NEXT: bne LBB7_2 930; ENABLE-V4T-NEXT: @ %bb.3: @ %for.exit 931; ENABLE-V4T-NEXT: @ InlineAsm Start 932; ENABLE-V4T-NEXT: mov r8, r8 933; ENABLE-V4T-NEXT: @ InlineAsm End 934; ENABLE-V4T-NEXT: movs r0, #0 935; ENABLE-V4T-NEXT: pop {r4} 936; ENABLE-V4T-NEXT: pop {r1} 937; ENABLE-V4T-NEXT: bx r1 938; ENABLE-V4T-NEXT: LBB7_4: @ %if.else 939; ENABLE-V4T-NEXT: lsls r0, r1, #1 940; ENABLE-V4T-NEXT: bx lr 941; 942; ENABLE-V5T-LABEL: inlineAsm: 943; ENABLE-V5T: @ %bb.0: @ %entry 944; ENABLE-V5T-NEXT: cmp r0, #0 945; ENABLE-V5T-NEXT: beq LBB7_4 946; ENABLE-V5T-NEXT: @ %bb.1: @ %for.preheader 947; ENABLE-V5T-NEXT: push {r4, lr} 948; ENABLE-V5T-NEXT: .cfi_def_cfa_offset 8 949; ENABLE-V5T-NEXT: .cfi_offset lr, -4 950; ENABLE-V5T-NEXT: .cfi_offset r4, -8 951; ENABLE-V5T-NEXT: @ InlineAsm Start 952; ENABLE-V5T-NEXT: mov r8, r8 953; ENABLE-V5T-NEXT: @ InlineAsm End 954; ENABLE-V5T-NEXT: movs r0, #10 955; ENABLE-V5T-NEXT: LBB7_2: @ %for.body 956; ENABLE-V5T-NEXT: @ =>This Inner Loop Header: Depth=1 957; ENABLE-V5T-NEXT: @ InlineAsm Start 958; ENABLE-V5T-NEXT: movs r4, #1 959; ENABLE-V5T-NEXT: @ InlineAsm End 960; ENABLE-V5T-NEXT: subs r0, r0, #1 961; ENABLE-V5T-NEXT: bne LBB7_2 962; ENABLE-V5T-NEXT: @ %bb.3: @ %for.exit 963; ENABLE-V5T-NEXT: @ InlineAsm Start 964; ENABLE-V5T-NEXT: mov r8, r8 965; ENABLE-V5T-NEXT: @ InlineAsm End 966; ENABLE-V5T-NEXT: movs r0, #0 967; ENABLE-V5T-NEXT: pop {r4, pc} 968; ENABLE-V5T-NEXT: LBB7_4: @ %if.else 969; ENABLE-V5T-NEXT: lsls r0, r1, #1 970; ENABLE-V5T-NEXT: LBB7_5: @ %if.end 971; ENABLE-V5T-NEXT: bx lr 972; 973; DISABLE-V4T-LABEL: inlineAsm: 974; DISABLE-V4T: @ %bb.0: @ %entry 975; DISABLE-V4T-NEXT: push {r4, lr} 976; DISABLE-V4T-NEXT: .cfi_def_cfa_offset 8 977; DISABLE-V4T-NEXT: .cfi_offset lr, -4 978; DISABLE-V4T-NEXT: .cfi_offset r4, -8 979; DISABLE-V4T-NEXT: cmp r0, #0 980; DISABLE-V4T-NEXT: beq LBB7_4 981; DISABLE-V4T-NEXT: @ %bb.1: @ %for.preheader 982; DISABLE-V4T-NEXT: @ InlineAsm Start 983; DISABLE-V4T-NEXT: mov r8, r8 984; DISABLE-V4T-NEXT: @ InlineAsm End 985; DISABLE-V4T-NEXT: movs r0, #10 986; DISABLE-V4T-NEXT: LBB7_2: @ %for.body 987; DISABLE-V4T-NEXT: @ =>This Inner Loop Header: Depth=1 988; DISABLE-V4T-NEXT: @ InlineAsm Start 989; DISABLE-V4T-NEXT: movs r4, #1 990; DISABLE-V4T-NEXT: @ InlineAsm End 991; DISABLE-V4T-NEXT: subs r0, r0, #1 992; DISABLE-V4T-NEXT: bne LBB7_2 993; DISABLE-V4T-NEXT: @ %bb.3: @ %for.exit 994; DISABLE-V4T-NEXT: @ InlineAsm Start 995; DISABLE-V4T-NEXT: mov r8, r8 996; DISABLE-V4T-NEXT: @ InlineAsm End 997; DISABLE-V4T-NEXT: movs r0, #0 998; DISABLE-V4T-NEXT: b LBB7_5 999; DISABLE-V4T-NEXT: LBB7_4: @ %if.else 1000; DISABLE-V4T-NEXT: lsls r0, r1, #1 1001; DISABLE-V4T-NEXT: LBB7_5: @ %if.end 1002; DISABLE-V4T-NEXT: pop {r4} 1003; DISABLE-V4T-NEXT: pop {r1} 1004; DISABLE-V4T-NEXT: bx r1 1005; 1006; DISABLE-V5T-LABEL: inlineAsm: 1007; DISABLE-V5T: @ %bb.0: @ %entry 1008; DISABLE-V5T-NEXT: push {r4, lr} 1009; DISABLE-V5T-NEXT: .cfi_def_cfa_offset 8 1010; DISABLE-V5T-NEXT: .cfi_offset lr, -4 1011; DISABLE-V5T-NEXT: .cfi_offset r4, -8 1012; DISABLE-V5T-NEXT: cmp r0, #0 1013; DISABLE-V5T-NEXT: beq LBB7_4 1014; DISABLE-V5T-NEXT: @ %bb.1: @ %for.preheader 1015; DISABLE-V5T-NEXT: @ InlineAsm Start 1016; DISABLE-V5T-NEXT: mov r8, r8 1017; DISABLE-V5T-NEXT: @ InlineAsm End 1018; DISABLE-V5T-NEXT: movs r0, #10 1019; DISABLE-V5T-NEXT: LBB7_2: @ %for.body 1020; DISABLE-V5T-NEXT: @ =>This Inner Loop Header: Depth=1 1021; DISABLE-V5T-NEXT: @ InlineAsm Start 1022; DISABLE-V5T-NEXT: movs r4, #1 1023; DISABLE-V5T-NEXT: @ InlineAsm End 1024; DISABLE-V5T-NEXT: subs r0, r0, #1 1025; DISABLE-V5T-NEXT: bne LBB7_2 1026; DISABLE-V5T-NEXT: @ %bb.3: @ %for.exit 1027; DISABLE-V5T-NEXT: @ InlineAsm Start 1028; DISABLE-V5T-NEXT: mov r8, r8 1029; DISABLE-V5T-NEXT: @ InlineAsm End 1030; DISABLE-V5T-NEXT: movs r0, #0 1031; DISABLE-V5T-NEXT: pop {r4, pc} 1032; DISABLE-V5T-NEXT: LBB7_4: @ %if.else 1033; DISABLE-V5T-NEXT: lsls r0, r1, #1 1034; DISABLE-V5T-NEXT: pop {r4, pc} 1035entry: 1036 %tobool = icmp eq i32 %cond, 0 1037 br i1 %tobool, label %if.else, label %for.preheader 1038 1039for.preheader: 1040 tail call void asm "nop", ""() 1041 br label %for.body 1042 1043for.body: ; preds = %entry, %for.body 1044 %i.03 = phi i32 [ %inc, %for.body ], [ 0, %for.preheader ] 1045 tail call void asm sideeffect "movs r4, #1", "~{r4}"() 1046 %inc = add nuw nsw i32 %i.03, 1 1047 %exitcond = icmp eq i32 %inc, 10 1048 br i1 %exitcond, label %for.exit, label %for.body 1049 1050for.exit: 1051 tail call void asm "nop", ""() 1052 br label %if.end 1053 1054if.else: ; preds = %entry 1055 %mul = shl nsw i32 %N, 1 1056 br label %if.end 1057 1058if.end: ; preds = %for.body, %if.else 1059 %sum.0 = phi i32 [ %mul, %if.else ], [ 0, %for.exit ] 1060 ret i32 %sum.0 1061} 1062 1063; Check that we handle calls to variadic functions correctly. 1064define i32 @callVariadicFunc(i32 %cond, i32 %N) { 1065; ENABLE-V4T-LABEL: callVariadicFunc: 1066; ENABLE-V4T: @ %bb.0: @ %entry 1067; ENABLE-V4T-NEXT: cmp r0, #0 1068; ENABLE-V4T-NEXT: beq LBB8_2 1069; ENABLE-V4T-NEXT: @ %bb.1: @ %if.then 1070; ENABLE-V4T-NEXT: push {r4, lr} 1071; ENABLE-V4T-NEXT: .cfi_def_cfa_offset 8 1072; ENABLE-V4T-NEXT: .cfi_offset lr, -4 1073; ENABLE-V4T-NEXT: .cfi_offset r4, -8 1074; ENABLE-V4T-NEXT: sub sp, #16 1075; ENABLE-V4T-NEXT: .cfi_def_cfa_offset 24 1076; ENABLE-V4T-NEXT: str r1, [sp] 1077; ENABLE-V4T-NEXT: str r1, [sp, #4] 1078; ENABLE-V4T-NEXT: str r1, [sp, #8] 1079; ENABLE-V4T-NEXT: ldr r0, LCPI8_0 1080; ENABLE-V4T-NEXT: LPC8_0: 1081; ENABLE-V4T-NEXT: add r0, pc 1082; ENABLE-V4T-NEXT: ldr r4, [r0] 1083; ENABLE-V4T-NEXT: movs r0, r1 1084; ENABLE-V4T-NEXT: movs r2, r1 1085; ENABLE-V4T-NEXT: movs r3, r1 1086; ENABLE-V4T-NEXT: bl Ltmp2 1087; ENABLE-V4T-NEXT: lsls r0, r0, #3 1088; ENABLE-V4T-NEXT: add sp, #16 1089; ENABLE-V4T-NEXT: pop {r4} 1090; ENABLE-V4T-NEXT: pop {r1} 1091; ENABLE-V4T-NEXT: bx r1 1092; ENABLE-V4T-NEXT: LBB8_2: @ %if.else 1093; ENABLE-V4T-NEXT: lsls r0, r1, #1 1094; ENABLE-V4T-NEXT: bx lr 1095; ENABLE-V4T-NEXT: .p2align 2 1096; ENABLE-V4T-NEXT: @ %bb.3: 1097; ENABLE-V4T-NEXT: .data_region 1098; ENABLE-V4T-NEXT: LCPI8_0: 1099; ENABLE-V4T-NEXT: .long L_someVariadicFunc$non_lazy_ptr-(LPC8_0+4) 1100; ENABLE-V4T-NEXT: .end_data_region 1101; 1102; ENABLE-V5T-LABEL: callVariadicFunc: 1103; ENABLE-V5T: @ %bb.0: @ %entry 1104; ENABLE-V5T-NEXT: cmp r0, #0 1105; ENABLE-V5T-NEXT: beq LBB8_2 1106; ENABLE-V5T-NEXT: @ %bb.1: @ %if.then 1107; ENABLE-V5T-NEXT: push {r7, lr} 1108; ENABLE-V5T-NEXT: .cfi_def_cfa_offset 8 1109; ENABLE-V5T-NEXT: .cfi_offset lr, -4 1110; ENABLE-V5T-NEXT: .cfi_offset r7, -8 1111; ENABLE-V5T-NEXT: sub sp, #16 1112; ENABLE-V5T-NEXT: .cfi_def_cfa_offset 24 1113; ENABLE-V5T-NEXT: str r1, [sp] 1114; ENABLE-V5T-NEXT: str r1, [sp, #4] 1115; ENABLE-V5T-NEXT: str r1, [sp, #8] 1116; ENABLE-V5T-NEXT: movs r0, r1 1117; ENABLE-V5T-NEXT: movs r2, r1 1118; ENABLE-V5T-NEXT: movs r3, r1 1119; ENABLE-V5T-NEXT: bl _someVariadicFunc 1120; ENABLE-V5T-NEXT: lsls r0, r0, #3 1121; ENABLE-V5T-NEXT: add sp, #16 1122; ENABLE-V5T-NEXT: pop {r7, pc} 1123; ENABLE-V5T-NEXT: LBB8_2: @ %if.else 1124; ENABLE-V5T-NEXT: lsls r0, r1, #1 1125; ENABLE-V5T-NEXT: LBB8_3: @ %if.end 1126; ENABLE-V5T-NEXT: bx lr 1127; 1128; DISABLE-V4T-LABEL: callVariadicFunc: 1129; DISABLE-V4T: @ %bb.0: @ %entry 1130; DISABLE-V4T-NEXT: push {r4, lr} 1131; DISABLE-V4T-NEXT: .cfi_def_cfa_offset 8 1132; DISABLE-V4T-NEXT: .cfi_offset lr, -4 1133; DISABLE-V4T-NEXT: .cfi_offset r4, -8 1134; DISABLE-V4T-NEXT: sub sp, #16 1135; DISABLE-V4T-NEXT: .cfi_def_cfa_offset 24 1136; DISABLE-V4T-NEXT: cmp r0, #0 1137; DISABLE-V4T-NEXT: beq LBB8_2 1138; DISABLE-V4T-NEXT: @ %bb.1: @ %if.then 1139; DISABLE-V4T-NEXT: str r1, [sp] 1140; DISABLE-V4T-NEXT: str r1, [sp, #4] 1141; DISABLE-V4T-NEXT: str r1, [sp, #8] 1142; DISABLE-V4T-NEXT: ldr r0, LCPI8_0 1143; DISABLE-V4T-NEXT: LPC8_0: 1144; DISABLE-V4T-NEXT: add r0, pc 1145; DISABLE-V4T-NEXT: ldr r4, [r0] 1146; DISABLE-V4T-NEXT: movs r0, r1 1147; DISABLE-V4T-NEXT: movs r2, r1 1148; DISABLE-V4T-NEXT: movs r3, r1 1149; DISABLE-V4T-NEXT: bl Ltmp2 1150; DISABLE-V4T-NEXT: lsls r0, r0, #3 1151; DISABLE-V4T-NEXT: b LBB8_3 1152; DISABLE-V4T-NEXT: LBB8_2: @ %if.else 1153; DISABLE-V4T-NEXT: lsls r0, r1, #1 1154; DISABLE-V4T-NEXT: LBB8_3: @ %if.end 1155; DISABLE-V4T-NEXT: add sp, #16 1156; DISABLE-V4T-NEXT: pop {r4} 1157; DISABLE-V4T-NEXT: pop {r1} 1158; DISABLE-V4T-NEXT: bx r1 1159; DISABLE-V4T-NEXT: .p2align 2 1160; DISABLE-V4T-NEXT: @ %bb.4: 1161; DISABLE-V4T-NEXT: .data_region 1162; DISABLE-V4T-NEXT: LCPI8_0: 1163; DISABLE-V4T-NEXT: .long L_someVariadicFunc$non_lazy_ptr-(LPC8_0+4) 1164; DISABLE-V4T-NEXT: .end_data_region 1165; 1166; DISABLE-V5T-LABEL: callVariadicFunc: 1167; DISABLE-V5T: @ %bb.0: @ %entry 1168; DISABLE-V5T-NEXT: push {r7, lr} 1169; DISABLE-V5T-NEXT: .cfi_def_cfa_offset 8 1170; DISABLE-V5T-NEXT: .cfi_offset lr, -4 1171; DISABLE-V5T-NEXT: .cfi_offset r7, -8 1172; DISABLE-V5T-NEXT: sub sp, #16 1173; DISABLE-V5T-NEXT: .cfi_def_cfa_offset 24 1174; DISABLE-V5T-NEXT: cmp r0, #0 1175; DISABLE-V5T-NEXT: beq LBB8_2 1176; DISABLE-V5T-NEXT: @ %bb.1: @ %if.then 1177; DISABLE-V5T-NEXT: str r1, [sp] 1178; DISABLE-V5T-NEXT: str r1, [sp, #4] 1179; DISABLE-V5T-NEXT: str r1, [sp, #8] 1180; DISABLE-V5T-NEXT: movs r0, r1 1181; DISABLE-V5T-NEXT: movs r2, r1 1182; DISABLE-V5T-NEXT: movs r3, r1 1183; DISABLE-V5T-NEXT: bl _someVariadicFunc 1184; DISABLE-V5T-NEXT: lsls r0, r0, #3 1185; DISABLE-V5T-NEXT: add sp, #16 1186; DISABLE-V5T-NEXT: pop {r7, pc} 1187; DISABLE-V5T-NEXT: LBB8_2: @ %if.else 1188; DISABLE-V5T-NEXT: lsls r0, r1, #1 1189; DISABLE-V5T-NEXT: add sp, #16 1190; DISABLE-V5T-NEXT: pop {r7, pc} 1191entry: 1192 %tobool = icmp eq i32 %cond, 0 1193 br i1 %tobool, label %if.else, label %if.then 1194 1195if.then: ; preds = %entry 1196 %call = tail call i32 (i32, ...) @someVariadicFunc(i32 %N, i32 %N, i32 %N, i32 %N, i32 %N, i32 %N, i32 %N) 1197 %shl = shl i32 %call, 3 1198 br label %if.end 1199 1200if.else: ; preds = %entry 1201 %mul = shl nsw i32 %N, 1 1202 br label %if.end 1203 1204if.end: ; preds = %if.else, %if.then 1205 %sum.0 = phi i32 [ %shl, %if.then ], [ %mul, %if.else ] 1206 ret i32 %sum.0 1207} 1208 1209declare i32 @someVariadicFunc(i32, ...) 1210 1211; Make sure we do not insert unreachable code after noreturn function. 1212; Although this is not incorrect to insert such code, it is useless 1213; and it hurts the binary size. 1214; 1215define i32 @noreturn(i8 signext %bad_thing) { 1216; ENABLE-V4T-LABEL: noreturn: 1217; ENABLE-V4T: @ %bb.0: @ %entry 1218; ENABLE-V4T-NEXT: cmp r0, #0 1219; ENABLE-V4T-NEXT: bne LBB9_2 1220; ENABLE-V4T-NEXT: @ %bb.1: @ %if.end 1221; ENABLE-V4T-NEXT: movs r0, #42 1222; ENABLE-V4T-NEXT: bx lr 1223; ENABLE-V4T-NEXT: LBB9_2: @ %if.abort 1224; ENABLE-V4T-NEXT: push {r4, lr} 1225; ENABLE-V4T-NEXT: .cfi_def_cfa_offset 8 1226; ENABLE-V4T-NEXT: .cfi_offset lr, -4 1227; ENABLE-V4T-NEXT: .cfi_offset r4, -8 1228; ENABLE-V4T-NEXT: ldr r0, LCPI9_0 1229; ENABLE-V4T-NEXT: LPC9_0: 1230; ENABLE-V4T-NEXT: add r0, pc 1231; ENABLE-V4T-NEXT: ldr r0, [r0] 1232; ENABLE-V4T-NEXT: @ InlineAsm Start 1233; ENABLE-V4T-NEXT: movs r1, #1 1234; ENABLE-V4T-NEXT: @ InlineAsm End 1235; ENABLE-V4T-NEXT: bl Ltmp3 1236; ENABLE-V4T-NEXT: .p2align 2 1237; ENABLE-V4T-NEXT: @ %bb.3: 1238; ENABLE-V4T-NEXT: .data_region 1239; ENABLE-V4T-NEXT: LCPI9_0: 1240; ENABLE-V4T-NEXT: .long L_abort$non_lazy_ptr-(LPC9_0+4) 1241; ENABLE-V4T-NEXT: .end_data_region 1242; 1243; ENABLE-V5T-LABEL: noreturn: 1244; ENABLE-V5T: @ %bb.0: @ %entry 1245; ENABLE-V5T-NEXT: cmp r0, #0 1246; ENABLE-V5T-NEXT: bne LBB9_2 1247; ENABLE-V5T-NEXT: @ %bb.1: @ %if.end 1248; ENABLE-V5T-NEXT: movs r0, #42 1249; ENABLE-V5T-NEXT: bx lr 1250; ENABLE-V5T-NEXT: LBB9_2: @ %if.abort 1251; ENABLE-V5T-NEXT: push {r4, lr} 1252; ENABLE-V5T-NEXT: .cfi_def_cfa_offset 8 1253; ENABLE-V5T-NEXT: .cfi_offset lr, -4 1254; ENABLE-V5T-NEXT: .cfi_offset r4, -8 1255; ENABLE-V5T-NEXT: @ InlineAsm Start 1256; ENABLE-V5T-NEXT: movs r0, #1 1257; ENABLE-V5T-NEXT: @ InlineAsm End 1258; ENABLE-V5T-NEXT: bl _abort 1259; 1260; DISABLE-V4T-LABEL: noreturn: 1261; DISABLE-V4T: @ %bb.0: @ %entry 1262; DISABLE-V4T-NEXT: push {r4, lr} 1263; DISABLE-V4T-NEXT: .cfi_def_cfa_offset 8 1264; DISABLE-V4T-NEXT: .cfi_offset lr, -4 1265; DISABLE-V4T-NEXT: .cfi_offset r4, -8 1266; DISABLE-V4T-NEXT: cmp r0, #0 1267; DISABLE-V4T-NEXT: bne LBB9_2 1268; DISABLE-V4T-NEXT: @ %bb.1: @ %if.end 1269; DISABLE-V4T-NEXT: movs r0, #42 1270; DISABLE-V4T-NEXT: pop {r4} 1271; DISABLE-V4T-NEXT: pop {r1} 1272; DISABLE-V4T-NEXT: bx r1 1273; DISABLE-V4T-NEXT: LBB9_2: @ %if.abort 1274; DISABLE-V4T-NEXT: ldr r0, LCPI9_0 1275; DISABLE-V4T-NEXT: LPC9_0: 1276; DISABLE-V4T-NEXT: add r0, pc 1277; DISABLE-V4T-NEXT: ldr r0, [r0] 1278; DISABLE-V4T-NEXT: @ InlineAsm Start 1279; DISABLE-V4T-NEXT: movs r1, #1 1280; DISABLE-V4T-NEXT: @ InlineAsm End 1281; DISABLE-V4T-NEXT: bl Ltmp3 1282; DISABLE-V4T-NEXT: .p2align 2 1283; DISABLE-V4T-NEXT: @ %bb.3: 1284; DISABLE-V4T-NEXT: .data_region 1285; DISABLE-V4T-NEXT: LCPI9_0: 1286; DISABLE-V4T-NEXT: .long L_abort$non_lazy_ptr-(LPC9_0+4) 1287; DISABLE-V4T-NEXT: .end_data_region 1288; 1289; DISABLE-V5T-LABEL: noreturn: 1290; DISABLE-V5T: @ %bb.0: @ %entry 1291; DISABLE-V5T-NEXT: push {r4, lr} 1292; DISABLE-V5T-NEXT: .cfi_def_cfa_offset 8 1293; DISABLE-V5T-NEXT: .cfi_offset lr, -4 1294; DISABLE-V5T-NEXT: .cfi_offset r4, -8 1295; DISABLE-V5T-NEXT: cmp r0, #0 1296; DISABLE-V5T-NEXT: bne LBB9_2 1297; DISABLE-V5T-NEXT: @ %bb.1: @ %if.end 1298; DISABLE-V5T-NEXT: movs r0, #42 1299; DISABLE-V5T-NEXT: pop {r4, pc} 1300; DISABLE-V5T-NEXT: LBB9_2: @ %if.abort 1301; DISABLE-V5T-NEXT: @ InlineAsm Start 1302; DISABLE-V5T-NEXT: movs r0, #1 1303; DISABLE-V5T-NEXT: @ InlineAsm End 1304; DISABLE-V5T-NEXT: bl _abort 1305entry: 1306 %tobool = icmp eq i8 %bad_thing, 0 1307 br i1 %tobool, label %if.end, label %if.abort 1308 1309if.abort: 1310 %call = tail call i32 asm sideeffect "movs $0, #1", "=r,~{r4}"() 1311 tail call void @abort() #0 1312 unreachable 1313 1314if.end: 1315 ret i32 42 1316} 1317 1318declare void @abort() #0 1319 1320define i32 @b_to_bx(i32 %value) { 1321; ENABLE-V4T-LABEL: b_to_bx: 1322; ENABLE-V4T: @ %bb.0: @ %entry 1323; ENABLE-V4T-NEXT: movs r1, r0 1324; ENABLE-V4T-NEXT: cmp r0, #49 1325; ENABLE-V4T-NEXT: bgt LBB10_2 1326; ENABLE-V4T-NEXT: @ %bb.1: @ %if.then 1327; ENABLE-V4T-NEXT: push {r7, lr} 1328; ENABLE-V4T-NEXT: .cfi_def_cfa_offset 8 1329; ENABLE-V4T-NEXT: .cfi_offset lr, -4 1330; ENABLE-V4T-NEXT: .cfi_offset r7, -8 1331; ENABLE-V4T-NEXT: ldr r0, LCPI10_0 1332; ENABLE-V4T-NEXT: ldr r2, LCPI10_1 1333; ENABLE-V4T-NEXT: LPC10_0: 1334; ENABLE-V4T-NEXT: add r2, pc 1335; ENABLE-V4T-NEXT: bl Ltmp4 1336; ENABLE-V4T-NEXT: pop {r7} 1337; ENABLE-V4T-NEXT: pop {r1} 1338; ENABLE-V4T-NEXT: bx r1 1339; ENABLE-V4T-NEXT: LBB10_2: @ %if.else 1340; ENABLE-V4T-NEXT: lsls r0, r1, #1 1341; ENABLE-V4T-NEXT: bx lr 1342; ENABLE-V4T-NEXT: .p2align 2 1343; ENABLE-V4T-NEXT: @ %bb.3: 1344; ENABLE-V4T-NEXT: .data_region 1345; ENABLE-V4T-NEXT: LCPI10_0: 1346; ENABLE-V4T-NEXT: .long 5000 @ 0x1388 1347; ENABLE-V4T-NEXT: LCPI10_1: 1348; ENABLE-V4T-NEXT: .long ___divsi3-(LPC10_0+4) 1349; ENABLE-V4T-NEXT: .end_data_region 1350; 1351; ENABLE-V5T-LABEL: b_to_bx: 1352; ENABLE-V5T: @ %bb.0: @ %entry 1353; ENABLE-V5T-NEXT: movs r1, r0 1354; ENABLE-V5T-NEXT: cmp r0, #49 1355; ENABLE-V5T-NEXT: bgt LBB10_2 1356; ENABLE-V5T-NEXT: @ %bb.1: @ %if.then 1357; ENABLE-V5T-NEXT: push {r7, lr} 1358; ENABLE-V5T-NEXT: .cfi_def_cfa_offset 8 1359; ENABLE-V5T-NEXT: .cfi_offset lr, -4 1360; ENABLE-V5T-NEXT: .cfi_offset r7, -8 1361; ENABLE-V5T-NEXT: ldr r0, LCPI10_0 1362; ENABLE-V5T-NEXT: bl ___divsi3 1363; ENABLE-V5T-NEXT: pop {r7, pc} 1364; ENABLE-V5T-NEXT: LBB10_2: @ %if.else 1365; ENABLE-V5T-NEXT: lsls r0, r1, #1 1366; ENABLE-V5T-NEXT: LBB10_3: @ %if.end 1367; ENABLE-V5T-NEXT: bx lr 1368; ENABLE-V5T-NEXT: .p2align 2 1369; ENABLE-V5T-NEXT: @ %bb.4: 1370; ENABLE-V5T-NEXT: .data_region 1371; ENABLE-V5T-NEXT: LCPI10_0: 1372; ENABLE-V5T-NEXT: .long 5000 @ 0x1388 1373; ENABLE-V5T-NEXT: .end_data_region 1374; 1375; DISABLE-V4T-LABEL: b_to_bx: 1376; DISABLE-V4T: @ %bb.0: @ %entry 1377; DISABLE-V4T-NEXT: push {r7, lr} 1378; DISABLE-V4T-NEXT: .cfi_def_cfa_offset 8 1379; DISABLE-V4T-NEXT: .cfi_offset lr, -4 1380; DISABLE-V4T-NEXT: .cfi_offset r7, -8 1381; DISABLE-V4T-NEXT: movs r1, r0 1382; DISABLE-V4T-NEXT: cmp r0, #49 1383; DISABLE-V4T-NEXT: bgt LBB10_2 1384; DISABLE-V4T-NEXT: @ %bb.1: @ %if.then 1385; DISABLE-V4T-NEXT: ldr r0, LCPI10_0 1386; DISABLE-V4T-NEXT: ldr r2, LCPI10_1 1387; DISABLE-V4T-NEXT: LPC10_0: 1388; DISABLE-V4T-NEXT: add r2, pc 1389; DISABLE-V4T-NEXT: bl Ltmp4 1390; DISABLE-V4T-NEXT: b LBB10_3 1391; DISABLE-V4T-NEXT: LBB10_2: @ %if.else 1392; DISABLE-V4T-NEXT: lsls r0, r1, #1 1393; DISABLE-V4T-NEXT: LBB10_3: @ %if.end 1394; DISABLE-V4T-NEXT: pop {r7} 1395; DISABLE-V4T-NEXT: pop {r1} 1396; DISABLE-V4T-NEXT: bx r1 1397; DISABLE-V4T-NEXT: .p2align 2 1398; DISABLE-V4T-NEXT: @ %bb.4: 1399; DISABLE-V4T-NEXT: .data_region 1400; DISABLE-V4T-NEXT: LCPI10_0: 1401; DISABLE-V4T-NEXT: .long 5000 @ 0x1388 1402; DISABLE-V4T-NEXT: LCPI10_1: 1403; DISABLE-V4T-NEXT: .long ___divsi3-(LPC10_0+4) 1404; DISABLE-V4T-NEXT: .end_data_region 1405; 1406; DISABLE-V5T-LABEL: b_to_bx: 1407; DISABLE-V5T: @ %bb.0: @ %entry 1408; DISABLE-V5T-NEXT: push {r7, lr} 1409; DISABLE-V5T-NEXT: .cfi_def_cfa_offset 8 1410; DISABLE-V5T-NEXT: .cfi_offset lr, -4 1411; DISABLE-V5T-NEXT: .cfi_offset r7, -8 1412; DISABLE-V5T-NEXT: movs r1, r0 1413; DISABLE-V5T-NEXT: cmp r0, #49 1414; DISABLE-V5T-NEXT: bgt LBB10_2 1415; DISABLE-V5T-NEXT: @ %bb.1: @ %if.then 1416; DISABLE-V5T-NEXT: ldr r0, LCPI10_0 1417; DISABLE-V5T-NEXT: bl ___divsi3 1418; DISABLE-V5T-NEXT: pop {r7, pc} 1419; DISABLE-V5T-NEXT: LBB10_2: @ %if.else 1420; DISABLE-V5T-NEXT: lsls r0, r1, #1 1421; DISABLE-V5T-NEXT: pop {r7, pc} 1422; DISABLE-V5T-NEXT: .p2align 2 1423; DISABLE-V5T-NEXT: @ %bb.3: 1424; DISABLE-V5T-NEXT: .data_region 1425; DISABLE-V5T-NEXT: LCPI10_0: 1426; DISABLE-V5T-NEXT: .long 5000 @ 0x1388 1427; DISABLE-V5T-NEXT: .end_data_region 1428entry: 1429 %cmp = icmp slt i32 %value, 50 1430 br i1 %cmp, label %if.then, label %if.else 1431 1432if.then: 1433 %div = sdiv i32 5000, %value 1434 br label %if.end 1435 1436if.else: 1437 %mul = shl nsw i32 %value, 1 1438 br label %if.end 1439 1440if.end: 1441 %value.addr.0 = phi i32 [ %div, %if.then ], [ %mul, %if.else ] 1442 ret i32 %value.addr.0 1443} 1444 1445define i1 @beq_to_bx(i32* %y, i32 %head) { 1446; ENABLE-V4T-LABEL: beq_to_bx: 1447; ENABLE-V4T: @ %bb.0: @ %entry 1448; ENABLE-V4T-NEXT: push {r4, lr} 1449; ENABLE-V4T-NEXT: .cfi_def_cfa_offset 8 1450; ENABLE-V4T-NEXT: .cfi_offset lr, -4 1451; ENABLE-V4T-NEXT: .cfi_offset r4, -8 1452; ENABLE-V4T-NEXT: movs r2, r0 1453; ENABLE-V4T-NEXT: movs r0, #1 1454; ENABLE-V4T-NEXT: cmp r2, #0 1455; ENABLE-V4T-NEXT: beq LBB11_3 1456; ENABLE-V4T-NEXT: @ %bb.1: @ %if.end 1457; ENABLE-V4T-NEXT: ldr r3, [r2] 1458; ENABLE-V4T-NEXT: lsls r4, r3, #30 1459; ENABLE-V4T-NEXT: bpl LBB11_3 1460; ENABLE-V4T-NEXT: @ %bb.2: @ %if.end4 1461; ENABLE-V4T-NEXT: str r1, [r2] 1462; ENABLE-V4T-NEXT: str r3, [r2] 1463; ENABLE-V4T-NEXT: movs r0, #0 1464; ENABLE-V4T-NEXT: LBB11_3: @ %cleanup 1465; ENABLE-V4T-NEXT: pop {r4} 1466; ENABLE-V4T-NEXT: pop {r1} 1467; ENABLE-V4T-NEXT: bx r1 1468; 1469; ENABLE-V5T-LABEL: beq_to_bx: 1470; ENABLE-V5T: @ %bb.0: @ %entry 1471; ENABLE-V5T-NEXT: push {r4, lr} 1472; ENABLE-V5T-NEXT: .cfi_def_cfa_offset 8 1473; ENABLE-V5T-NEXT: .cfi_offset lr, -4 1474; ENABLE-V5T-NEXT: .cfi_offset r4, -8 1475; ENABLE-V5T-NEXT: movs r2, r0 1476; ENABLE-V5T-NEXT: movs r0, #1 1477; ENABLE-V5T-NEXT: cmp r2, #0 1478; ENABLE-V5T-NEXT: beq LBB11_3 1479; ENABLE-V5T-NEXT: @ %bb.1: @ %if.end 1480; ENABLE-V5T-NEXT: ldr r3, [r2] 1481; ENABLE-V5T-NEXT: lsls r4, r3, #30 1482; ENABLE-V5T-NEXT: bpl LBB11_3 1483; ENABLE-V5T-NEXT: @ %bb.2: @ %if.end4 1484; ENABLE-V5T-NEXT: str r1, [r2] 1485; ENABLE-V5T-NEXT: str r3, [r2] 1486; ENABLE-V5T-NEXT: movs r0, #0 1487; ENABLE-V5T-NEXT: LBB11_3: @ %cleanup 1488; ENABLE-V5T-NEXT: pop {r4, pc} 1489; 1490; DISABLE-V4T-LABEL: beq_to_bx: 1491; DISABLE-V4T: @ %bb.0: @ %entry 1492; DISABLE-V4T-NEXT: push {r4, lr} 1493; DISABLE-V4T-NEXT: .cfi_def_cfa_offset 8 1494; DISABLE-V4T-NEXT: .cfi_offset lr, -4 1495; DISABLE-V4T-NEXT: .cfi_offset r4, -8 1496; DISABLE-V4T-NEXT: movs r2, r0 1497; DISABLE-V4T-NEXT: movs r0, #1 1498; DISABLE-V4T-NEXT: cmp r2, #0 1499; DISABLE-V4T-NEXT: beq LBB11_3 1500; DISABLE-V4T-NEXT: @ %bb.1: @ %if.end 1501; DISABLE-V4T-NEXT: ldr r3, [r2] 1502; DISABLE-V4T-NEXT: lsls r4, r3, #30 1503; DISABLE-V4T-NEXT: bpl LBB11_3 1504; DISABLE-V4T-NEXT: @ %bb.2: @ %if.end4 1505; DISABLE-V4T-NEXT: str r1, [r2] 1506; DISABLE-V4T-NEXT: str r3, [r2] 1507; DISABLE-V4T-NEXT: movs r0, #0 1508; DISABLE-V4T-NEXT: LBB11_3: @ %cleanup 1509; DISABLE-V4T-NEXT: pop {r4} 1510; DISABLE-V4T-NEXT: pop {r1} 1511; DISABLE-V4T-NEXT: bx r1 1512; 1513; DISABLE-V5T-LABEL: beq_to_bx: 1514; DISABLE-V5T: @ %bb.0: @ %entry 1515; DISABLE-V5T-NEXT: push {r4, lr} 1516; DISABLE-V5T-NEXT: .cfi_def_cfa_offset 8 1517; DISABLE-V5T-NEXT: .cfi_offset lr, -4 1518; DISABLE-V5T-NEXT: .cfi_offset r4, -8 1519; DISABLE-V5T-NEXT: movs r2, r0 1520; DISABLE-V5T-NEXT: movs r0, #1 1521; DISABLE-V5T-NEXT: cmp r2, #0 1522; DISABLE-V5T-NEXT: beq LBB11_3 1523; DISABLE-V5T-NEXT: @ %bb.1: @ %if.end 1524; DISABLE-V5T-NEXT: ldr r3, [r2] 1525; DISABLE-V5T-NEXT: lsls r4, r3, #30 1526; DISABLE-V5T-NEXT: bpl LBB11_3 1527; DISABLE-V5T-NEXT: @ %bb.2: @ %if.end4 1528; DISABLE-V5T-NEXT: str r1, [r2] 1529; DISABLE-V5T-NEXT: str r3, [r2] 1530; DISABLE-V5T-NEXT: movs r0, #0 1531; DISABLE-V5T-NEXT: LBB11_3: @ %cleanup 1532; DISABLE-V5T-NEXT: pop {r4, pc} 1533entry: 1534 %cmp = icmp eq i32* %y, null 1535 br i1 %cmp, label %cleanup, label %if.end 1536 1537if.end: 1538 %z = load i32, i32* %y, align 4 1539 %and = and i32 %z, 2 1540 %cmp2 = icmp eq i32 %and, 0 1541 br i1 %cmp2, label %cleanup, label %if.end4 1542 1543if.end4: 1544 store i32 %head, i32* %y, align 4 1545 store volatile i32 %z, i32* %y, align 4 1546 br label %cleanup 1547 1548cleanup: 1549 %retval.0 = phi i1 [ 0, %if.end4 ], [ 1, %entry ], [ 1, %if.end ] 1550 ret i1 %retval.0 1551} 1552 1553attributes #0 = { noreturn nounwind } 1554