1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -debugify-and-strip-all-safe %s -o - -mtriple=arm64-apple-ios -enable-shrink-wrap=true -disable-post-ra -frame-pointer=non-leaf | FileCheck %s --check-prefix=ENABLE 3; RUN: llc -debugify-and-strip-all-safe %s -o - -enable-shrink-wrap=false -disable-post-ra -frame-pointer=non-leaf | FileCheck %s --check-prefix=DISABLE 4target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128" 5target triple = "arm64-apple-ios" 6 7 8; Initial motivating example: Simple diamond with a call just on one side. 9define i32 @foo(i32 %a, i32 %b) { 10; ENABLE-LABEL: foo: 11; ENABLE: ; %bb.0: 12; ENABLE-NEXT: cmp w0, w1 13; ENABLE-NEXT: b.ge LBB0_2 14; ENABLE-NEXT: ; %bb.1: ; %true 15; ENABLE-NEXT: sub sp, sp, #32 16; ENABLE-NEXT: stp x29, x30, [sp, #16] ; 16-byte Folded Spill 17; ENABLE-NEXT: add x29, sp, #16 18; ENABLE-NEXT: .cfi_def_cfa w29, 16 19; ENABLE-NEXT: .cfi_offset w30, -8 20; ENABLE-NEXT: .cfi_offset w29, -16 21; ENABLE-NEXT: stur w0, [x29, #-4] 22; ENABLE-NEXT: sub x1, x29, #4 23; ENABLE-NEXT: mov w0, wzr 24; ENABLE-NEXT: bl _doSomething 25; ENABLE-NEXT: ldp x29, x30, [sp, #16] ; 16-byte Folded Reload 26; ENABLE-NEXT: add sp, sp, #32 27; ENABLE-NEXT: LBB0_2: ; %false 28; ENABLE-NEXT: ret 29; 30; DISABLE-LABEL: foo: 31; DISABLE: ; %bb.0: 32; DISABLE-NEXT: sub sp, sp, #32 33; DISABLE-NEXT: stp x29, x30, [sp, #16] ; 16-byte Folded Spill 34; DISABLE-NEXT: add x29, sp, #16 35; DISABLE-NEXT: .cfi_def_cfa w29, 16 36; DISABLE-NEXT: .cfi_offset w30, -8 37; DISABLE-NEXT: .cfi_offset w29, -16 38; DISABLE-NEXT: cmp w0, w1 39; DISABLE-NEXT: b.ge LBB0_2 40; DISABLE-NEXT: ; %bb.1: ; %true 41; DISABLE-NEXT: stur w0, [x29, #-4] 42; DISABLE-NEXT: sub x1, x29, #4 43; DISABLE-NEXT: mov w0, wzr 44; DISABLE-NEXT: bl _doSomething 45; DISABLE-NEXT: LBB0_2: ; %false 46; DISABLE-NEXT: ldp x29, x30, [sp, #16] ; 16-byte Folded Reload 47; DISABLE-NEXT: add sp, sp, #32 48; DISABLE-NEXT: ret 49 %tmp = alloca i32, align 4 50 %tmp2 = icmp slt i32 %a, %b 51 br i1 %tmp2, label %true, label %false 52 53true: 54 store i32 %a, ptr %tmp, align 4 55 %tmp4 = call i32 @doSomething(i32 0, ptr %tmp) 56 br label %false 57 58false: 59 %tmp.0 = phi i32 [ %tmp4, %true ], [ %a, %0 ] 60 ret i32 %tmp.0 61} 62 63; Function Attrs: optsize 64declare i32 @doSomething(i32, ptr) 65 66 67; Check that we do not perform the restore inside the loop whereas the save 68; is outside. 69define i32 @freqSaveAndRestoreOutsideLoop(i32 %cond, i32 %N) { 70; ENABLE-LABEL: freqSaveAndRestoreOutsideLoop: 71; ENABLE: ; %bb.0: ; %entry 72; ENABLE-NEXT: cbz w0, LBB1_4 73; ENABLE-NEXT: ; %bb.1: ; %for.body.preheader 74; ENABLE-NEXT: stp x20, x19, [sp, #-32]! ; 16-byte Folded Spill 75; ENABLE-NEXT: stp x29, x30, [sp, #16] ; 16-byte Folded Spill 76; ENABLE-NEXT: add x29, sp, #16 77; ENABLE-NEXT: .cfi_def_cfa w29, 16 78; ENABLE-NEXT: .cfi_offset w30, -8 79; ENABLE-NEXT: .cfi_offset w29, -16 80; ENABLE-NEXT: .cfi_offset w19, -24 81; ENABLE-NEXT: .cfi_offset w20, -32 82; ENABLE-NEXT: mov w19, wzr 83; ENABLE-NEXT: mov w20, #10 ; =0xa 84; ENABLE-NEXT: LBB1_2: ; %for.body 85; ENABLE-NEXT: ; =>This Inner Loop Header: Depth=1 86; ENABLE-NEXT: bl _something 87; ENABLE-NEXT: subs w20, w20, #1 88; ENABLE-NEXT: add w19, w0, w19 89; ENABLE-NEXT: b.ne LBB1_2 90; ENABLE-NEXT: ; %bb.3: ; %for.end 91; ENABLE-NEXT: lsl w0, w19, #3 92; ENABLE-NEXT: ldp x29, x30, [sp, #16] ; 16-byte Folded Reload 93; ENABLE-NEXT: ldp x20, x19, [sp], #32 ; 16-byte Folded Reload 94; ENABLE-NEXT: ret 95; ENABLE-NEXT: LBB1_4: ; %if.else 96; ENABLE-NEXT: lsl w0, w1, #1 97; ENABLE-NEXT: ret 98; 99; DISABLE-LABEL: freqSaveAndRestoreOutsideLoop: 100; DISABLE: ; %bb.0: ; %entry 101; DISABLE-NEXT: stp x20, x19, [sp, #-32]! ; 16-byte Folded Spill 102; DISABLE-NEXT: stp x29, x30, [sp, #16] ; 16-byte Folded Spill 103; DISABLE-NEXT: add x29, sp, #16 104; DISABLE-NEXT: .cfi_def_cfa w29, 16 105; DISABLE-NEXT: .cfi_offset w30, -8 106; DISABLE-NEXT: .cfi_offset w29, -16 107; DISABLE-NEXT: .cfi_offset w19, -24 108; DISABLE-NEXT: .cfi_offset w20, -32 109; DISABLE-NEXT: cbz w0, LBB1_4 110; DISABLE-NEXT: ; %bb.1: ; %for.body.preheader 111; DISABLE-NEXT: mov w19, wzr 112; DISABLE-NEXT: mov w20, #10 ; =0xa 113; DISABLE-NEXT: LBB1_2: ; %for.body 114; DISABLE-NEXT: ; =>This Inner Loop Header: Depth=1 115; DISABLE-NEXT: bl _something 116; DISABLE-NEXT: subs w20, w20, #1 117; DISABLE-NEXT: add w19, w0, w19 118; DISABLE-NEXT: b.ne LBB1_2 119; DISABLE-NEXT: ; %bb.3: ; %for.end 120; DISABLE-NEXT: lsl w0, w19, #3 121; DISABLE-NEXT: b LBB1_5 122; DISABLE-NEXT: LBB1_4: ; %if.else 123; DISABLE-NEXT: lsl w0, w1, #1 124; DISABLE-NEXT: LBB1_5: ; %if.end 125; DISABLE-NEXT: ldp x29, x30, [sp, #16] ; 16-byte Folded Reload 126; DISABLE-NEXT: ldp x20, x19, [sp], #32 ; 16-byte Folded Reload 127; DISABLE-NEXT: ret 128entry: 129 %tobool = icmp eq i32 %cond, 0 130 br i1 %tobool, label %if.else, label %for.body 131 132for.body: ; preds = %entry, %for.body 133 %i.05 = phi i32 [ %inc, %for.body ], [ 0, %entry ] 134 %sum.04 = phi i32 [ %add, %for.body ], [ 0, %entry ] 135 %call = tail call i32 @something() 136 %add = add nsw i32 %call, %sum.04 137 %inc = add nuw nsw i32 %i.05, 1 138 %exitcond = icmp eq i32 %inc, 10 139 br i1 %exitcond, label %for.end, label %for.body 140 141for.end: ; preds = %for.body 142 %shl = shl i32 %add, 3 143 br label %if.end 144 145if.else: ; preds = %entry 146 %mul = shl nsw i32 %N, 1 147 br label %if.end 148 149if.end: ; preds = %if.else, %for.end 150 %sum.1 = phi i32 [ %shl, %for.end ], [ %mul, %if.else ] 151 ret i32 %sum.1 152} 153 154declare i32 @something(...) 155 156; Check that we do not perform the shrink-wrapping inside the loop even 157; though that would be legal. The cost model must prevent that. 158define i32 @freqSaveAndRestoreOutsideLoop2(i32 %cond) { 159; ENABLE-LABEL: freqSaveAndRestoreOutsideLoop2: 160; ENABLE: ; %bb.0: ; %entry 161; ENABLE-NEXT: stp x20, x19, [sp, #-32]! ; 16-byte Folded Spill 162; ENABLE-NEXT: stp x29, x30, [sp, #16] ; 16-byte Folded Spill 163; ENABLE-NEXT: add x29, sp, #16 164; ENABLE-NEXT: .cfi_def_cfa w29, 16 165; ENABLE-NEXT: .cfi_offset w30, -8 166; ENABLE-NEXT: .cfi_offset w29, -16 167; ENABLE-NEXT: .cfi_offset w19, -24 168; ENABLE-NEXT: .cfi_offset w20, -32 169; ENABLE-NEXT: mov w19, wzr 170; ENABLE-NEXT: mov w20, #10 ; =0xa 171; ENABLE-NEXT: LBB2_1: ; %for.body 172; ENABLE-NEXT: ; =>This Inner Loop Header: Depth=1 173; ENABLE-NEXT: bl _something 174; ENABLE-NEXT: subs w20, w20, #1 175; ENABLE-NEXT: add w19, w0, w19 176; ENABLE-NEXT: b.ne LBB2_1 177; ENABLE-NEXT: ; %bb.2: ; %for.end 178; ENABLE-NEXT: mov w0, w19 179; ENABLE-NEXT: ldp x29, x30, [sp, #16] ; 16-byte Folded Reload 180; ENABLE-NEXT: ldp x20, x19, [sp], #32 ; 16-byte Folded Reload 181; ENABLE-NEXT: ret 182; 183; DISABLE-LABEL: freqSaveAndRestoreOutsideLoop2: 184; DISABLE: ; %bb.0: ; %entry 185; DISABLE-NEXT: stp x20, x19, [sp, #-32]! ; 16-byte Folded Spill 186; DISABLE-NEXT: stp x29, x30, [sp, #16] ; 16-byte Folded Spill 187; DISABLE-NEXT: add x29, sp, #16 188; DISABLE-NEXT: .cfi_def_cfa w29, 16 189; DISABLE-NEXT: .cfi_offset w30, -8 190; DISABLE-NEXT: .cfi_offset w29, -16 191; DISABLE-NEXT: .cfi_offset w19, -24 192; DISABLE-NEXT: .cfi_offset w20, -32 193; DISABLE-NEXT: mov w19, wzr 194; DISABLE-NEXT: mov w20, #10 ; =0xa 195; DISABLE-NEXT: LBB2_1: ; %for.body 196; DISABLE-NEXT: ; =>This Inner Loop Header: Depth=1 197; DISABLE-NEXT: bl _something 198; DISABLE-NEXT: subs w20, w20, #1 199; DISABLE-NEXT: add w19, w0, w19 200; DISABLE-NEXT: b.ne LBB2_1 201; DISABLE-NEXT: ; %bb.2: ; %for.end 202; DISABLE-NEXT: mov w0, w19 203; DISABLE-NEXT: ldp x29, x30, [sp, #16] ; 16-byte Folded Reload 204; DISABLE-NEXT: ldp x20, x19, [sp], #32 ; 16-byte Folded Reload 205; DISABLE-NEXT: ret 206entry: 207 br label %for.body 208 209for.body: ; preds = %for.body, %entry 210 %i.04 = phi i32 [ 0, %entry ], [ %inc, %for.body ] 211 %sum.03 = phi i32 [ 0, %entry ], [ %add, %for.body ] 212 %call = tail call i32 @something() 213 %add = add nsw i32 %call, %sum.03 214 %inc = add nuw nsw i32 %i.04, 1 215 %exitcond = icmp eq i32 %inc, 10 216 br i1 %exitcond, label %for.end, label %for.body 217 218for.end: ; preds = %for.body 219 ret i32 %add 220} 221 222; Check with a more complex case that we do not have save within the loop and 223; restore outside. 224define i32 @loopInfoSaveOutsideLoop(i32 %cond, i32 %N) { 225; ENABLE-LABEL: loopInfoSaveOutsideLoop: 226; ENABLE: ; %bb.0: ; %entry 227; ENABLE-NEXT: cbz w0, LBB3_4 228; ENABLE-NEXT: ; %bb.1: ; %for.body.preheader 229; ENABLE-NEXT: stp x20, x19, [sp, #-32]! ; 16-byte Folded Spill 230; ENABLE-NEXT: stp x29, x30, [sp, #16] ; 16-byte Folded Spill 231; ENABLE-NEXT: add x29, sp, #16 232; ENABLE-NEXT: .cfi_def_cfa w29, 16 233; ENABLE-NEXT: .cfi_offset w30, -8 234; ENABLE-NEXT: .cfi_offset w29, -16 235; ENABLE-NEXT: .cfi_offset w19, -24 236; ENABLE-NEXT: .cfi_offset w20, -32 237; ENABLE-NEXT: mov w19, wzr 238; ENABLE-NEXT: mov w20, #10 ; =0xa 239; ENABLE-NEXT: LBB3_2: ; %for.body 240; ENABLE-NEXT: ; =>This Inner Loop Header: Depth=1 241; ENABLE-NEXT: bl _something 242; ENABLE-NEXT: subs w20, w20, #1 243; ENABLE-NEXT: add w19, w0, w19 244; ENABLE-NEXT: b.ne LBB3_2 245; ENABLE-NEXT: ; %bb.3: ; %for.end 246; ENABLE-NEXT: bl _somethingElse 247; ENABLE-NEXT: lsl w0, w19, #3 248; ENABLE-NEXT: ldp x29, x30, [sp, #16] ; 16-byte Folded Reload 249; ENABLE-NEXT: ldp x20, x19, [sp], #32 ; 16-byte Folded Reload 250; ENABLE-NEXT: ret 251; ENABLE-NEXT: LBB3_4: ; %if.else 252; ENABLE-NEXT: lsl w0, w1, #1 253; ENABLE-NEXT: ret 254; 255; DISABLE-LABEL: loopInfoSaveOutsideLoop: 256; DISABLE: ; %bb.0: ; %entry 257; DISABLE-NEXT: stp x20, x19, [sp, #-32]! ; 16-byte Folded Spill 258; DISABLE-NEXT: stp x29, x30, [sp, #16] ; 16-byte Folded Spill 259; DISABLE-NEXT: add x29, sp, #16 260; DISABLE-NEXT: .cfi_def_cfa w29, 16 261; DISABLE-NEXT: .cfi_offset w30, -8 262; DISABLE-NEXT: .cfi_offset w29, -16 263; DISABLE-NEXT: .cfi_offset w19, -24 264; DISABLE-NEXT: .cfi_offset w20, -32 265; DISABLE-NEXT: cbz w0, LBB3_4 266; DISABLE-NEXT: ; %bb.1: ; %for.body.preheader 267; DISABLE-NEXT: mov w19, wzr 268; DISABLE-NEXT: mov w20, #10 ; =0xa 269; DISABLE-NEXT: LBB3_2: ; %for.body 270; DISABLE-NEXT: ; =>This Inner Loop Header: Depth=1 271; DISABLE-NEXT: bl _something 272; DISABLE-NEXT: subs w20, w20, #1 273; DISABLE-NEXT: add w19, w0, w19 274; DISABLE-NEXT: b.ne LBB3_2 275; DISABLE-NEXT: ; %bb.3: ; %for.end 276; DISABLE-NEXT: bl _somethingElse 277; DISABLE-NEXT: lsl w0, w19, #3 278; DISABLE-NEXT: b LBB3_5 279; DISABLE-NEXT: LBB3_4: ; %if.else 280; DISABLE-NEXT: lsl w0, w1, #1 281; DISABLE-NEXT: LBB3_5: ; %if.end 282; DISABLE-NEXT: ldp x29, x30, [sp, #16] ; 16-byte Folded Reload 283; DISABLE-NEXT: ldp x20, x19, [sp], #32 ; 16-byte Folded Reload 284; DISABLE-NEXT: ret 285entry: 286 %tobool = icmp eq i32 %cond, 0 287 br i1 %tobool, label %if.else, label %for.body 288 289for.body: ; preds = %entry, %for.body 290 %i.05 = phi i32 [ %inc, %for.body ], [ 0, %entry ] 291 %sum.04 = phi i32 [ %add, %for.body ], [ 0, %entry ] 292 %call = tail call i32 @something() 293 %add = add nsw i32 %call, %sum.04 294 %inc = add nuw nsw i32 %i.05, 1 295 %exitcond = icmp eq i32 %inc, 10 296 br i1 %exitcond, label %for.end, label %for.body 297 298for.end: ; preds = %for.body 299 tail call void @somethingElse() 300 %shl = shl i32 %add, 3 301 br label %if.end 302 303if.else: ; preds = %entry 304 %mul = shl nsw i32 %N, 1 305 br label %if.end 306 307if.end: ; preds = %if.else, %for.end 308 %sum.1 = phi i32 [ %shl, %for.end ], [ %mul, %if.else ] 309 ret i32 %sum.1 310} 311 312declare void @somethingElse(...) 313 314; Check with a more complex case that we do not have restore within the loop and 315; save outside. 316define i32 @loopInfoRestoreOutsideLoop(i32 %cond, i32 %N) nounwind uwtable { 317; ENABLE-LABEL: loopInfoRestoreOutsideLoop: 318; ENABLE: ; %bb.0: ; %entry 319; ENABLE-NEXT: cbz w0, LBB4_4 320; ENABLE-NEXT: ; %bb.1: ; %if.then 321; ENABLE-NEXT: stp x20, x19, [sp, #-32]! ; 16-byte Folded Spill 322; ENABLE-NEXT: .cfi_def_cfa_offset 32 323; ENABLE-NEXT: stp x29, x30, [sp, #16] ; 16-byte Folded Spill 324; ENABLE-NEXT: add x29, sp, #16 325; ENABLE-NEXT: .cfi_def_cfa w29, 16 326; ENABLE-NEXT: .cfi_offset w30, -8 327; ENABLE-NEXT: .cfi_offset w29, -16 328; ENABLE-NEXT: .cfi_offset w19, -24 329; ENABLE-NEXT: .cfi_offset w20, -32 330; ENABLE-NEXT: bl _somethingElse 331; ENABLE-NEXT: mov w19, wzr 332; ENABLE-NEXT: mov w20, #10 ; =0xa 333; ENABLE-NEXT: LBB4_2: ; %for.body 334; ENABLE-NEXT: ; =>This Inner Loop Header: Depth=1 335; ENABLE-NEXT: bl _something 336; ENABLE-NEXT: subs w20, w20, #1 337; ENABLE-NEXT: add w19, w0, w19 338; ENABLE-NEXT: b.ne LBB4_2 339; ENABLE-NEXT: ; %bb.3: ; %for.end 340; ENABLE-NEXT: lsl w0, w19, #3 341; ENABLE-NEXT: .cfi_def_cfa wsp, 32 342; ENABLE-NEXT: ldp x29, x30, [sp, #16] ; 16-byte Folded Reload 343; ENABLE-NEXT: ldp x20, x19, [sp], #32 ; 16-byte Folded Reload 344; ENABLE-NEXT: .cfi_def_cfa_offset 0 345; ENABLE-NEXT: .cfi_restore w30 346; ENABLE-NEXT: .cfi_restore w29 347; ENABLE-NEXT: .cfi_restore w19 348; ENABLE-NEXT: .cfi_restore w20 349; ENABLE-NEXT: ret 350; ENABLE-NEXT: LBB4_4: ; %if.else 351; ENABLE-NEXT: lsl w0, w1, #1 352; ENABLE-NEXT: ret 353; 354; DISABLE-LABEL: loopInfoRestoreOutsideLoop: 355; DISABLE: ; %bb.0: ; %entry 356; DISABLE-NEXT: stp x20, x19, [sp, #-32]! ; 16-byte Folded Spill 357; DISABLE-NEXT: .cfi_def_cfa_offset 32 358; DISABLE-NEXT: stp x29, x30, [sp, #16] ; 16-byte Folded Spill 359; DISABLE-NEXT: add x29, sp, #16 360; DISABLE-NEXT: .cfi_def_cfa w29, 16 361; DISABLE-NEXT: .cfi_offset w30, -8 362; DISABLE-NEXT: .cfi_offset w29, -16 363; DISABLE-NEXT: .cfi_offset w19, -24 364; DISABLE-NEXT: .cfi_offset w20, -32 365; DISABLE-NEXT: cbz w0, LBB4_4 366; DISABLE-NEXT: ; %bb.1: ; %if.then 367; DISABLE-NEXT: bl _somethingElse 368; DISABLE-NEXT: mov w19, wzr 369; DISABLE-NEXT: mov w20, #10 ; =0xa 370; DISABLE-NEXT: LBB4_2: ; %for.body 371; DISABLE-NEXT: ; =>This Inner Loop Header: Depth=1 372; DISABLE-NEXT: bl _something 373; DISABLE-NEXT: subs w20, w20, #1 374; DISABLE-NEXT: add w19, w0, w19 375; DISABLE-NEXT: b.ne LBB4_2 376; DISABLE-NEXT: ; %bb.3: ; %for.end 377; DISABLE-NEXT: lsl w0, w19, #3 378; DISABLE-NEXT: b LBB4_5 379; DISABLE-NEXT: LBB4_4: ; %if.else 380; DISABLE-NEXT: lsl w0, w1, #1 381; DISABLE-NEXT: LBB4_5: ; %if.end 382; DISABLE-NEXT: .cfi_def_cfa wsp, 32 383; DISABLE-NEXT: ldp x29, x30, [sp, #16] ; 16-byte Folded Reload 384; DISABLE-NEXT: ldp x20, x19, [sp], #32 ; 16-byte Folded Reload 385; DISABLE-NEXT: .cfi_def_cfa_offset 0 386; DISABLE-NEXT: .cfi_restore w30 387; DISABLE-NEXT: .cfi_restore w29 388; DISABLE-NEXT: .cfi_restore w19 389; DISABLE-NEXT: .cfi_restore w20 390; DISABLE-NEXT: ret 391entry: 392 %tobool = icmp eq i32 %cond, 0 393 br i1 %tobool, label %if.else, label %if.then 394 395if.then: ; preds = %entry 396 tail call void @somethingElse() 397 br label %for.body 398 399for.body: ; preds = %for.body, %if.then 400 %i.05 = phi i32 [ 0, %if.then ], [ %inc, %for.body ] 401 %sum.04 = phi i32 [ 0, %if.then ], [ %add, %for.body ] 402 %call = tail call i32 @something() 403 %add = add nsw i32 %call, %sum.04 404 %inc = add nuw nsw i32 %i.05, 1 405 %exitcond = icmp eq i32 %inc, 10 406 br i1 %exitcond, label %for.end, label %for.body 407 408for.end: ; preds = %for.body 409 %shl = shl i32 %add, 3 410 br label %if.end 411 412if.else: ; preds = %entry 413 %mul = shl nsw i32 %N, 1 414 br label %if.end 415 416if.end: ; preds = %if.else, %for.end 417 %sum.1 = phi i32 [ %shl, %for.end ], [ %mul, %if.else ] 418 ret i32 %sum.1 419} 420 421; Check that we handle function with no frame information correctly. 422define i32 @emptyFrame() { 423; ENABLE-LABEL: emptyFrame: 424; ENABLE: ; %bb.0: ; %entry 425; ENABLE-NEXT: mov w0, wzr 426; ENABLE-NEXT: ret 427; 428; DISABLE-LABEL: emptyFrame: 429; DISABLE: ; %bb.0: ; %entry 430; DISABLE-NEXT: mov w0, wzr 431; DISABLE-NEXT: ret 432entry: 433 ret i32 0 434} 435 436; Check that we handle variadic function correctly. 437define i32 @variadicFunc(i32 %cond, i32 %count, ...) nounwind uwtable { 438; ENABLE-LABEL: variadicFunc: 439; ENABLE: ; %bb.0: ; %entry 440; ENABLE-NEXT: cbz w0, LBB6_4 441; ENABLE-NEXT: ; %bb.1: ; %if.then 442; ENABLE-NEXT: sub sp, sp, #16 443; ENABLE-NEXT: .cfi_def_cfa_offset 16 444; ENABLE-NEXT: add x8, sp, #16 445; ENABLE-NEXT: cmp w1, #1 446; ENABLE-NEXT: str x8, [sp, #8] 447; ENABLE-NEXT: mov w0, wzr 448; ENABLE-NEXT: b.lt LBB6_3 449; ENABLE-NEXT: LBB6_2: ; %for.body 450; ENABLE-NEXT: ; =>This Inner Loop Header: Depth=1 451; ENABLE-NEXT: ldr x8, [sp, #8] 452; ENABLE-NEXT: add x9, x8, #8 453; ENABLE-NEXT: str x9, [sp, #8] 454; ENABLE-NEXT: ldr w8, [x8] 455; ENABLE-NEXT: subs w1, w1, #1 456; ENABLE-NEXT: add w0, w0, w8 457; ENABLE-NEXT: b.ne LBB6_2 458; ENABLE-NEXT: LBB6_3: ; %for.end 459; ENABLE-NEXT: add sp, sp, #16 460; ENABLE-NEXT: .cfi_def_cfa_offset 0 461; ENABLE-NEXT: ret 462; ENABLE-NEXT: LBB6_4: ; %if.else 463; ENABLE-NEXT: lsl w0, w1, #1 464; ENABLE-NEXT: ret 465; 466; DISABLE-LABEL: variadicFunc: 467; DISABLE: ; %bb.0: ; %entry 468; DISABLE-NEXT: sub sp, sp, #16 469; DISABLE-NEXT: .cfi_def_cfa_offset 16 470; DISABLE-NEXT: cbz w0, LBB6_3 471; DISABLE-NEXT: ; %bb.1: ; %if.then 472; DISABLE-NEXT: add x8, sp, #16 473; DISABLE-NEXT: cmp w1, #1 474; DISABLE-NEXT: str x8, [sp, #8] 475; DISABLE-NEXT: mov w0, wzr 476; DISABLE-NEXT: b.lt LBB6_4 477; DISABLE-NEXT: LBB6_2: ; %for.body 478; DISABLE-NEXT: ; =>This Inner Loop Header: Depth=1 479; DISABLE-NEXT: ldr x8, [sp, #8] 480; DISABLE-NEXT: add x9, x8, #8 481; DISABLE-NEXT: str x9, [sp, #8] 482; DISABLE-NEXT: ldr w8, [x8] 483; DISABLE-NEXT: subs w1, w1, #1 484; DISABLE-NEXT: add w0, w0, w8 485; DISABLE-NEXT: b.ne LBB6_2 486; DISABLE-NEXT: b LBB6_4 487; DISABLE-NEXT: LBB6_3: ; %if.else 488; DISABLE-NEXT: lsl w0, w1, #1 489; DISABLE-NEXT: LBB6_4: ; %if.end 490; DISABLE-NEXT: add sp, sp, #16 491; DISABLE-NEXT: .cfi_def_cfa_offset 0 492; DISABLE-NEXT: ret 493entry: 494 %ap = alloca ptr, align 8 495 %tobool = icmp eq i32 %cond, 0 496 br i1 %tobool, label %if.else, label %if.then 497 498if.then: ; preds = %entry 499 call void @llvm.va_start(ptr %ap) 500 %cmp6 = icmp sgt i32 %count, 0 501 br i1 %cmp6, label %for.body, label %for.end 502 503for.body: ; preds = %if.then, %for.body 504 %i.08 = phi i32 [ %inc, %for.body ], [ 0, %if.then ] 505 %sum.07 = phi i32 [ %add, %for.body ], [ 0, %if.then ] 506 %0 = va_arg ptr %ap, i32 507 %add = add nsw i32 %sum.07, %0 508 %inc = add nuw nsw i32 %i.08, 1 509 %exitcond = icmp eq i32 %inc, %count 510 br i1 %exitcond, label %for.end, label %for.body 511 512for.end: ; preds = %for.body, %if.then 513 %sum.0.lcssa = phi i32 [ 0, %if.then ], [ %add, %for.body ] 514 call void @llvm.va_end(ptr %ap) 515 br label %if.end 516 517if.else: ; preds = %entry 518 %mul = shl nsw i32 %count, 1 519 br label %if.end 520 521if.end: ; preds = %if.else, %for.end 522 %sum.1 = phi i32 [ %sum.0.lcssa, %for.end ], [ %mul, %if.else ] 523 ret i32 %sum.1 524} 525 526declare void @llvm.va_start(ptr) 527 528declare void @llvm.va_end(ptr) 529 530; Check that we handle inline asm correctly. 531define i32 @inlineAsm(i32 %cond, i32 %N) { 532; ENABLE-LABEL: inlineAsm: 533; ENABLE: ; %bb.0: ; %entry 534; ENABLE-NEXT: cbz w0, LBB7_4 535; ENABLE-NEXT: ; %bb.1: ; %for.body.preheader 536; ENABLE-NEXT: stp x20, x19, [sp, #-16]! ; 16-byte Folded Spill 537; ENABLE-NEXT: .cfi_def_cfa_offset 16 538; ENABLE-NEXT: .cfi_offset w19, -8 539; ENABLE-NEXT: .cfi_offset w20, -16 540; ENABLE-NEXT: mov w8, #10 ; =0xa 541; ENABLE-NEXT: LBB7_2: ; %for.body 542; ENABLE-NEXT: ; =>This Inner Loop Header: Depth=1 543; ENABLE-NEXT: subs w8, w8, #1 544; ENABLE-NEXT: ; InlineAsm Start 545; ENABLE-NEXT: add x19, x19, #1 546; ENABLE-NEXT: ; InlineAsm End 547; ENABLE-NEXT: b.ne LBB7_2 548; ENABLE-NEXT: ; %bb.3: 549; ENABLE-NEXT: mov w0, wzr 550; ENABLE-NEXT: ldp x20, x19, [sp], #16 ; 16-byte Folded Reload 551; ENABLE-NEXT: ret 552; ENABLE-NEXT: LBB7_4: ; %if.else 553; ENABLE-NEXT: lsl w0, w1, #1 554; ENABLE-NEXT: ret 555; 556; DISABLE-LABEL: inlineAsm: 557; DISABLE: ; %bb.0: ; %entry 558; DISABLE-NEXT: stp x20, x19, [sp, #-16]! ; 16-byte Folded Spill 559; DISABLE-NEXT: .cfi_def_cfa_offset 16 560; DISABLE-NEXT: .cfi_offset w19, -8 561; DISABLE-NEXT: .cfi_offset w20, -16 562; DISABLE-NEXT: cbz w0, LBB7_4 563; DISABLE-NEXT: ; %bb.1: ; %for.body.preheader 564; DISABLE-NEXT: mov w8, #10 ; =0xa 565; DISABLE-NEXT: LBB7_2: ; %for.body 566; DISABLE-NEXT: ; =>This Inner Loop Header: Depth=1 567; DISABLE-NEXT: subs w8, w8, #1 568; DISABLE-NEXT: ; InlineAsm Start 569; DISABLE-NEXT: add x19, x19, #1 570; DISABLE-NEXT: ; InlineAsm End 571; DISABLE-NEXT: b.ne LBB7_2 572; DISABLE-NEXT: ; %bb.3: 573; DISABLE-NEXT: mov w0, wzr 574; DISABLE-NEXT: ldp x20, x19, [sp], #16 ; 16-byte Folded Reload 575; DISABLE-NEXT: ret 576; DISABLE-NEXT: LBB7_4: ; %if.else 577; DISABLE-NEXT: lsl w0, w1, #1 578; DISABLE-NEXT: ldp x20, x19, [sp], #16 ; 16-byte Folded Reload 579; DISABLE-NEXT: ret 580entry: 581 %tobool = icmp eq i32 %cond, 0 582 br i1 %tobool, label %if.else, label %for.body 583 584for.body: ; preds = %entry, %for.body 585 %i.03 = phi i32 [ %inc, %for.body ], [ 0, %entry ] 586 tail call void asm sideeffect "add x19, x19, #1", "~{x19}"() 587 %inc = add nuw nsw i32 %i.03, 1 588 %exitcond = icmp eq i32 %inc, 10 589 br i1 %exitcond, label %if.end, label %for.body 590 591if.else: ; preds = %entry 592 %mul = shl nsw i32 %N, 1 593 br label %if.end 594 595if.end: ; preds = %for.body, %if.else 596 %sum.0 = phi i32 [ %mul, %if.else ], [ 0, %for.body ] 597 ret i32 %sum.0 598} 599 600; Check that we handle calls to variadic functions correctly. 601define i32 @callVariadicFunc(i32 %cond, i32 %N) { 602; ENABLE-LABEL: callVariadicFunc: 603; ENABLE: ; %bb.0: ; %entry 604; ENABLE-NEXT: ; kill: def $w1 killed $w1 def $x1 605; ENABLE-NEXT: cbz w0, LBB8_2 606; ENABLE-NEXT: ; %bb.1: ; %if.then 607; ENABLE-NEXT: sub sp, sp, #64 608; ENABLE-NEXT: stp x29, x30, [sp, #48] ; 16-byte Folded Spill 609; ENABLE-NEXT: add x29, sp, #48 610; ENABLE-NEXT: .cfi_def_cfa w29, 16 611; ENABLE-NEXT: .cfi_offset w30, -8 612; ENABLE-NEXT: .cfi_offset w29, -16 613; ENABLE-NEXT: stp x1, x1, [sp, #32] 614; ENABLE-NEXT: stp x1, x1, [sp, #16] 615; ENABLE-NEXT: stp x1, x1, [sp] 616; ENABLE-NEXT: mov w0, w1 617; ENABLE-NEXT: bl _someVariadicFunc 618; ENABLE-NEXT: lsl w0, w0, #3 619; ENABLE-NEXT: ldp x29, x30, [sp, #48] ; 16-byte Folded Reload 620; ENABLE-NEXT: add sp, sp, #64 621; ENABLE-NEXT: ret 622; ENABLE-NEXT: LBB8_2: ; %if.else 623; ENABLE-NEXT: lsl w0, w1, #1 624; ENABLE-NEXT: ret 625; 626; DISABLE-LABEL: callVariadicFunc: 627; DISABLE: ; %bb.0: ; %entry 628; DISABLE-NEXT: sub sp, sp, #64 629; DISABLE-NEXT: stp x29, x30, [sp, #48] ; 16-byte Folded Spill 630; DISABLE-NEXT: add x29, sp, #48 631; DISABLE-NEXT: .cfi_def_cfa w29, 16 632; DISABLE-NEXT: .cfi_offset w30, -8 633; DISABLE-NEXT: .cfi_offset w29, -16 634; DISABLE-NEXT: ; kill: def $w1 killed $w1 def $x1 635; DISABLE-NEXT: cbz w0, LBB8_2 636; DISABLE-NEXT: ; %bb.1: ; %if.then 637; DISABLE-NEXT: stp x1, x1, [sp, #32] 638; DISABLE-NEXT: stp x1, x1, [sp, #16] 639; DISABLE-NEXT: stp x1, x1, [sp] 640; DISABLE-NEXT: mov w0, w1 641; DISABLE-NEXT: bl _someVariadicFunc 642; DISABLE-NEXT: lsl w0, w0, #3 643; DISABLE-NEXT: b LBB8_3 644; DISABLE-NEXT: LBB8_2: ; %if.else 645; DISABLE-NEXT: lsl w0, w1, #1 646; DISABLE-NEXT: LBB8_3: ; %if.end 647; DISABLE-NEXT: ldp x29, x30, [sp, #48] ; 16-byte Folded Reload 648; DISABLE-NEXT: add sp, sp, #64 649; DISABLE-NEXT: ret 650entry: 651 %tobool = icmp eq i32 %cond, 0 652 br i1 %tobool, label %if.else, label %if.then 653 654if.then: ; preds = %entry 655 %call = tail call i32 (i32, ...) @someVariadicFunc(i32 %N, i32 %N, i32 %N, i32 %N, i32 %N, i32 %N, i32 %N) 656 %shl = shl i32 %call, 3 657 br label %if.end 658 659if.else: ; preds = %entry 660 %mul = shl nsw i32 %N, 1 661 br label %if.end 662 663if.end: ; preds = %if.else, %if.then 664 %sum.0 = phi i32 [ %shl, %if.then ], [ %mul, %if.else ] 665 ret i32 %sum.0 666} 667 668declare i32 @someVariadicFunc(i32, ...) 669 670; Make sure we do not insert unreachable code after noreturn function. 671; Although this is not incorrect to insert such code, it is useless 672; and it hurts the binary size. 673; 674define i32 @noreturn(i8 signext %bad_thing) { 675; ENABLE-LABEL: noreturn: 676; ENABLE: ; %bb.0: ; %entry 677; ENABLE-NEXT: cbnz w0, LBB9_2 678; ENABLE-NEXT: ; %bb.1: ; %if.end 679; ENABLE-NEXT: mov w0, #42 ; =0x2a 680; ENABLE-NEXT: ret 681; ENABLE-NEXT: LBB9_2: ; %if.abort 682; ENABLE-NEXT: stp x29, x30, [sp, #-16]! ; 16-byte Folded Spill 683; ENABLE-NEXT: mov x29, sp 684; ENABLE-NEXT: .cfi_def_cfa w29, 16 685; ENABLE-NEXT: .cfi_offset w30, -8 686; ENABLE-NEXT: .cfi_offset w29, -16 687; ENABLE-NEXT: bl _abort 688; 689; DISABLE-LABEL: noreturn: 690; DISABLE: ; %bb.0: ; %entry 691; DISABLE-NEXT: stp x29, x30, [sp, #-16]! ; 16-byte Folded Spill 692; DISABLE-NEXT: mov x29, sp 693; DISABLE-NEXT: .cfi_def_cfa w29, 16 694; DISABLE-NEXT: .cfi_offset w30, -8 695; DISABLE-NEXT: .cfi_offset w29, -16 696; DISABLE-NEXT: cbnz w0, LBB9_2 697; DISABLE-NEXT: ; %bb.1: ; %if.end 698; DISABLE-NEXT: mov w0, #42 ; =0x2a 699; DISABLE-NEXT: ldp x29, x30, [sp], #16 ; 16-byte Folded Reload 700; DISABLE-NEXT: ret 701; DISABLE-NEXT: LBB9_2: ; %if.abort 702; DISABLE-NEXT: bl _abort 703entry: 704 %tobool = icmp eq i8 %bad_thing, 0 705 br i1 %tobool, label %if.end, label %if.abort 706 707if.abort: 708 tail call void @abort() #0 709 unreachable 710 711if.end: 712 ret i32 42 713} 714 715declare void @abort() #0 716 717attributes #0 = { noreturn nounwind } 718 719; Make sure that we handle infinite loops properly When checking that the Save 720; and Restore blocks are control flow equivalent, the loop searches for the 721; immediate (post) dominator for the (restore) save blocks. When either the Save 722; or Restore block is located in an infinite loop the only immediate (post) 723; dominator is itself. In this case, we cannot perform shrink wrapping, but we 724; should return gracefully and continue compilation. 725; The only condition for this test is the compilation finishes correctly. 726; 727define void @infiniteloop() { 728; ENABLE-LABEL: infiniteloop: 729; ENABLE: ; %bb.0: ; %entry 730; ENABLE-NEXT: stp x20, x19, [sp, #-32]! ; 16-byte Folded Spill 731; ENABLE-NEXT: stp x29, x30, [sp, #16] ; 16-byte Folded Spill 732; ENABLE-NEXT: add x29, sp, #16 733; ENABLE-NEXT: .cfi_def_cfa w29, 16 734; ENABLE-NEXT: .cfi_offset w30, -8 735; ENABLE-NEXT: .cfi_offset w29, -16 736; ENABLE-NEXT: .cfi_offset w19, -24 737; ENABLE-NEXT: .cfi_offset w20, -32 738; ENABLE-NEXT: cbnz wzr, LBB10_3 739; ENABLE-NEXT: ; %bb.1: ; %if.then 740; ENABLE-NEXT: sub x19, sp, #16 741; ENABLE-NEXT: mov sp, x19 742; ENABLE-NEXT: mov w20, wzr 743; ENABLE-NEXT: LBB10_2: ; %for.body 744; ENABLE-NEXT: ; =>This Inner Loop Header: Depth=1 745; ENABLE-NEXT: bl _something 746; ENABLE-NEXT: add w20, w0, w20 747; ENABLE-NEXT: str w20, [x19] 748; ENABLE-NEXT: b LBB10_2 749; ENABLE-NEXT: LBB10_3: ; %if.end 750; ENABLE-NEXT: sub sp, x29, #16 751; ENABLE-NEXT: ldp x29, x30, [sp, #16] ; 16-byte Folded Reload 752; ENABLE-NEXT: ldp x20, x19, [sp], #32 ; 16-byte Folded Reload 753; ENABLE-NEXT: ret 754; 755; DISABLE-LABEL: infiniteloop: 756; DISABLE: ; %bb.0: ; %entry 757; DISABLE-NEXT: stp x20, x19, [sp, #-32]! ; 16-byte Folded Spill 758; DISABLE-NEXT: stp x29, x30, [sp, #16] ; 16-byte Folded Spill 759; DISABLE-NEXT: add x29, sp, #16 760; DISABLE-NEXT: .cfi_def_cfa w29, 16 761; DISABLE-NEXT: .cfi_offset w30, -8 762; DISABLE-NEXT: .cfi_offset w29, -16 763; DISABLE-NEXT: .cfi_offset w19, -24 764; DISABLE-NEXT: .cfi_offset w20, -32 765; DISABLE-NEXT: cbnz wzr, LBB10_3 766; DISABLE-NEXT: ; %bb.1: ; %if.then 767; DISABLE-NEXT: sub x19, sp, #16 768; DISABLE-NEXT: mov sp, x19 769; DISABLE-NEXT: mov w20, wzr 770; DISABLE-NEXT: LBB10_2: ; %for.body 771; DISABLE-NEXT: ; =>This Inner Loop Header: Depth=1 772; DISABLE-NEXT: bl _something 773; DISABLE-NEXT: add w20, w0, w20 774; DISABLE-NEXT: str w20, [x19] 775; DISABLE-NEXT: b LBB10_2 776; DISABLE-NEXT: LBB10_3: ; %if.end 777; DISABLE-NEXT: sub sp, x29, #16 778; DISABLE-NEXT: ldp x29, x30, [sp, #16] ; 16-byte Folded Reload 779; DISABLE-NEXT: ldp x20, x19, [sp], #32 ; 16-byte Folded Reload 780; DISABLE-NEXT: ret 781entry: 782 br i1 undef, label %if.then, label %if.end 783 784if.then: 785 %ptr = alloca i32, i32 4 786 br label %for.body 787 788for.body: ; preds = %for.body, %entry 789 %sum.03 = phi i32 [ 0, %if.then ], [ %add, %for.body ] 790 %call = tail call i32 @something() 791 %add = add nsw i32 %call, %sum.03 792 store i32 %add, ptr %ptr 793 br label %for.body 794 795if.end: 796 ret void 797} 798 799; Another infinite loop test this time with a body bigger than just one block. 800define void @infiniteloop2() { 801; ENABLE-LABEL: infiniteloop2: 802; ENABLE: ; %bb.0: ; %entry 803; ENABLE-NEXT: stp x20, x19, [sp, #-32]! ; 16-byte Folded Spill 804; ENABLE-NEXT: stp x29, x30, [sp, #16] ; 16-byte Folded Spill 805; ENABLE-NEXT: add x29, sp, #16 806; ENABLE-NEXT: .cfi_def_cfa w29, 16 807; ENABLE-NEXT: .cfi_offset w30, -8 808; ENABLE-NEXT: .cfi_offset w29, -16 809; ENABLE-NEXT: .cfi_offset w19, -24 810; ENABLE-NEXT: .cfi_offset w20, -32 811; ENABLE-NEXT: cbnz wzr, LBB11_3 812; ENABLE-NEXT: ; %bb.1: ; %if.then 813; ENABLE-NEXT: sub x8, sp, #16 814; ENABLE-NEXT: mov sp, x8 815; ENABLE-NEXT: mov w9, wzr 816; ENABLE-NEXT: LBB11_2: ; %for.body 817; ENABLE-NEXT: ; =>This Inner Loop Header: Depth=1 818; ENABLE-NEXT: ; InlineAsm Start 819; ENABLE-NEXT: mov x10, #0 ; =0x0 820; ENABLE-NEXT: ; InlineAsm End 821; ENABLE-NEXT: add w10, w10, w9 822; ENABLE-NEXT: mov w9, #1 ; =0x1 823; ENABLE-NEXT: str w10, [x8] 824; ENABLE-NEXT: ; InlineAsm Start 825; ENABLE-NEXT: nop 826; ENABLE-NEXT: ; InlineAsm End 827; ENABLE-NEXT: b LBB11_2 828; ENABLE-NEXT: LBB11_3: ; %if.end 829; ENABLE-NEXT: sub sp, x29, #16 830; ENABLE-NEXT: ldp x29, x30, [sp, #16] ; 16-byte Folded Reload 831; ENABLE-NEXT: ldp x20, x19, [sp], #32 ; 16-byte Folded Reload 832; ENABLE-NEXT: ret 833; 834; DISABLE-LABEL: infiniteloop2: 835; DISABLE: ; %bb.0: ; %entry 836; DISABLE-NEXT: stp x20, x19, [sp, #-32]! ; 16-byte Folded Spill 837; DISABLE-NEXT: stp x29, x30, [sp, #16] ; 16-byte Folded Spill 838; DISABLE-NEXT: add x29, sp, #16 839; DISABLE-NEXT: .cfi_def_cfa w29, 16 840; DISABLE-NEXT: .cfi_offset w30, -8 841; DISABLE-NEXT: .cfi_offset w29, -16 842; DISABLE-NEXT: .cfi_offset w19, -24 843; DISABLE-NEXT: .cfi_offset w20, -32 844; DISABLE-NEXT: cbnz wzr, LBB11_3 845; DISABLE-NEXT: ; %bb.1: ; %if.then 846; DISABLE-NEXT: sub x8, sp, #16 847; DISABLE-NEXT: mov sp, x8 848; DISABLE-NEXT: mov w9, wzr 849; DISABLE-NEXT: LBB11_2: ; %for.body 850; DISABLE-NEXT: ; =>This Inner Loop Header: Depth=1 851; DISABLE-NEXT: ; InlineAsm Start 852; DISABLE-NEXT: mov x10, #0 ; =0x0 853; DISABLE-NEXT: ; InlineAsm End 854; DISABLE-NEXT: add w10, w10, w9 855; DISABLE-NEXT: mov w9, #1 ; =0x1 856; DISABLE-NEXT: str w10, [x8] 857; DISABLE-NEXT: ; InlineAsm Start 858; DISABLE-NEXT: nop 859; DISABLE-NEXT: ; InlineAsm End 860; DISABLE-NEXT: b LBB11_2 861; DISABLE-NEXT: LBB11_3: ; %if.end 862; DISABLE-NEXT: sub sp, x29, #16 863; DISABLE-NEXT: ldp x29, x30, [sp, #16] ; 16-byte Folded Reload 864; DISABLE-NEXT: ldp x20, x19, [sp], #32 ; 16-byte Folded Reload 865; DISABLE-NEXT: ret 866entry: 867 br i1 undef, label %if.then, label %if.end 868 869if.then: 870 %ptr = alloca i32, i32 4 871 br label %for.body 872 873for.body: ; preds = %for.body, %entry 874 %sum.03 = phi i32 [ 0, %if.then ], [ %add, %body1 ], [ 1, %body2] 875 %call = tail call i32 asm "mov $0, #0", "=r,~{x19}"() 876 %add = add nsw i32 %call, %sum.03 877 store i32 %add, ptr %ptr 878 br i1 undef, label %body1, label %body2 879 880body1: 881 tail call void asm sideeffect "nop", "~{x19}"() 882 br label %for.body 883 884body2: 885 tail call void asm sideeffect "nop", "~{x19}"() 886 br label %for.body 887 888if.end: 889 ret void 890} 891 892; Another infinite loop test this time with two nested infinite loop. 893define void @infiniteloop3() { 894; ENABLE-LABEL: infiniteloop3: 895; ENABLE: ; %bb.0: ; %entry 896; ENABLE-NEXT: cbnz wzr, LBB12_5 897; ENABLE-NEXT: ; %bb.1: ; %loop2a.preheader 898; ENABLE-NEXT: mov x8, xzr 899; ENABLE-NEXT: mov x9, xzr 900; ENABLE-NEXT: mov x11, xzr 901; ENABLE-NEXT: b LBB12_3 902; ENABLE-NEXT: LBB12_2: ; %loop2b 903; ENABLE-NEXT: ; in Loop: Header=BB12_3 Depth=1 904; ENABLE-NEXT: str x10, [x11] 905; ENABLE-NEXT: mov x11, x10 906; ENABLE-NEXT: LBB12_3: ; %loop1 907; ENABLE-NEXT: ; =>This Inner Loop Header: Depth=1 908; ENABLE-NEXT: mov x10, x9 909; ENABLE-NEXT: ldr x9, [x8] 910; ENABLE-NEXT: cbnz x8, LBB12_2 911; ENABLE-NEXT: ; %bb.4: ; in Loop: Header=BB12_3 Depth=1 912; ENABLE-NEXT: mov x8, x10 913; ENABLE-NEXT: mov x11, x10 914; ENABLE-NEXT: b LBB12_3 915; ENABLE-NEXT: LBB12_5: ; %end 916; ENABLE-NEXT: ret 917; 918; DISABLE-LABEL: infiniteloop3: 919; DISABLE: ; %bb.0: ; %entry 920; DISABLE-NEXT: cbnz wzr, LBB12_5 921; DISABLE-NEXT: ; %bb.1: ; %loop2a.preheader 922; DISABLE-NEXT: mov x8, xzr 923; DISABLE-NEXT: mov x9, xzr 924; DISABLE-NEXT: mov x11, xzr 925; DISABLE-NEXT: b LBB12_3 926; DISABLE-NEXT: LBB12_2: ; %loop2b 927; DISABLE-NEXT: ; in Loop: Header=BB12_3 Depth=1 928; DISABLE-NEXT: str x10, [x11] 929; DISABLE-NEXT: mov x11, x10 930; DISABLE-NEXT: LBB12_3: ; %loop1 931; DISABLE-NEXT: ; =>This Inner Loop Header: Depth=1 932; DISABLE-NEXT: mov x10, x9 933; DISABLE-NEXT: ldr x9, [x8] 934; DISABLE-NEXT: cbnz x8, LBB12_2 935; DISABLE-NEXT: ; %bb.4: ; in Loop: Header=BB12_3 Depth=1 936; DISABLE-NEXT: mov x8, x10 937; DISABLE-NEXT: mov x11, x10 938; DISABLE-NEXT: b LBB12_3 939; DISABLE-NEXT: LBB12_5: ; %end 940; DISABLE-NEXT: ret 941entry: 942 br i1 undef, label %loop2a, label %body 943 944body: ; preds = %entry 945 br i1 undef, label %loop2a, label %end 946 947loop1: ; preds = %loop2a, %loop2b 948 %var.phi = phi ptr [ %next.phi, %loop2b ], [ %var, %loop2a ] 949 %next.phi = phi ptr [ %next.load, %loop2b ], [ %next.var, %loop2a ] 950 %0 = icmp eq ptr %var, null 951 %next.load = load ptr, ptr undef 952 br i1 %0, label %loop2a, label %loop2b 953 954loop2a: ; preds = %loop1, %body, %entry 955 %var = phi ptr [ null, %body ], [ null, %entry ], [ %next.phi, %loop1 ] 956 %next.var = phi ptr [ undef, %body ], [ null, %entry ], [ %next.load, %loop1 ] 957 br label %loop1 958 959loop2b: ; preds = %loop1 960 store ptr %next.phi, ptr %var.phi 961 br label %loop1 962 963end: 964 ret void 965} 966 967; Re-aligned stack pointer. See bug 26642. Avoid clobbering live 968; values in the prologue when re-aligning the stack pointer. 969define i32 @stack_realign(i32 %a, i32 %b, ptr %ptr1, ptr %ptr2) { 970; ENABLE-LABEL: stack_realign: 971; ENABLE: ; %bb.0: 972; ENABLE-NEXT: lsl w9, w0, w1 973; ENABLE-NEXT: lsl w8, w1, w0 974; ENABLE-NEXT: cmp w0, w1 975; ENABLE-NEXT: b.ge LBB13_2 976; ENABLE-NEXT: ; %bb.1: ; %true 977; ENABLE-NEXT: stp x29, x30, [sp, #-16]! ; 16-byte Folded Spill 978; ENABLE-NEXT: mov x29, sp 979; ENABLE-NEXT: sub x1, sp, #16 980; ENABLE-NEXT: and sp, x1, #0xffffffffffffffe0 981; ENABLE-NEXT: .cfi_def_cfa w29, 16 982; ENABLE-NEXT: .cfi_offset w30, -8 983; ENABLE-NEXT: .cfi_offset w29, -16 984; ENABLE-NEXT: str w0, [sp] 985; ENABLE-NEXT: mov sp, x29 986; ENABLE-NEXT: ldp x29, x30, [sp], #16 ; 16-byte Folded Reload 987; ENABLE-NEXT: LBB13_2: ; %false 988; ENABLE-NEXT: str w9, [x2] 989; ENABLE-NEXT: str w8, [x3] 990; ENABLE-NEXT: ret 991; 992; DISABLE-LABEL: stack_realign: 993; DISABLE: ; %bb.0: 994; DISABLE-NEXT: stp x29, x30, [sp, #-16]! ; 16-byte Folded Spill 995; DISABLE-NEXT: mov x29, sp 996; DISABLE-NEXT: sub x9, sp, #16 997; DISABLE-NEXT: and sp, x9, #0xffffffffffffffe0 998; DISABLE-NEXT: .cfi_def_cfa w29, 16 999; DISABLE-NEXT: .cfi_offset w30, -8 1000; DISABLE-NEXT: .cfi_offset w29, -16 1001; DISABLE-NEXT: lsl w9, w0, w1 1002; DISABLE-NEXT: lsl w8, w1, w0 1003; DISABLE-NEXT: cmp w0, w1 1004; DISABLE-NEXT: b.ge LBB13_2 1005; DISABLE-NEXT: ; %bb.1: ; %true 1006; DISABLE-NEXT: str w0, [sp] 1007; DISABLE-NEXT: LBB13_2: ; %false 1008; DISABLE-NEXT: str w9, [x2] 1009; DISABLE-NEXT: str w8, [x3] 1010; DISABLE-NEXT: mov sp, x29 1011; DISABLE-NEXT: ldp x29, x30, [sp], #16 ; 16-byte Folded Reload 1012; DISABLE-NEXT: ret 1013 %tmp = alloca i32, align 32 1014 %shl1 = shl i32 %a, %b 1015 %shl2 = shl i32 %b, %a 1016 %tmp2 = icmp slt i32 %a, %b 1017 br i1 %tmp2, label %true, label %false 1018 1019true: 1020 store i32 %a, ptr %tmp, align 4 1021 %tmp4 = load i32, ptr %tmp 1022 br label %false 1023 1024false: 1025 %tmp.0 = phi i32 [ %tmp4, %true ], [ %a, %0 ] 1026 store i32 %shl1, ptr %ptr1 1027 store i32 %shl2, ptr %ptr2 1028 ret i32 %tmp.0 1029} 1030 1031; Re-aligned stack pointer with all caller-save regs live. See bug 1032; 26642. In this case we currently avoid shrink wrapping because 1033; ensuring we have a scratch register to re-align the stack pointer is 1034; too complicated. Output should be the same for both enabled and 1035; disabled shrink wrapping. 1036define void @stack_realign2(i32 %a, i32 %b, ptr %ptr1, ptr %ptr2, ptr %ptr3, ptr %ptr4, ptr %ptr5, ptr %ptr6) { 1037; ENABLE-LABEL: stack_realign2: 1038; ENABLE: ; %bb.0: 1039; ENABLE-NEXT: stp x28, x27, [sp, #-96]! ; 16-byte Folded Spill 1040; ENABLE-NEXT: stp x26, x25, [sp, #16] ; 16-byte Folded Spill 1041; ENABLE-NEXT: stp x24, x23, [sp, #32] ; 16-byte Folded Spill 1042; ENABLE-NEXT: stp x22, x21, [sp, #48] ; 16-byte Folded Spill 1043; ENABLE-NEXT: stp x20, x19, [sp, #64] ; 16-byte Folded Spill 1044; ENABLE-NEXT: stp x29, x30, [sp, #80] ; 16-byte Folded Spill 1045; ENABLE-NEXT: add x29, sp, #80 1046; ENABLE-NEXT: sub x9, sp, #32 1047; ENABLE-NEXT: and sp, x9, #0xffffffffffffffe0 1048; ENABLE-NEXT: .cfi_def_cfa w29, 16 1049; ENABLE-NEXT: .cfi_offset w30, -8 1050; ENABLE-NEXT: .cfi_offset w29, -16 1051; ENABLE-NEXT: .cfi_offset w19, -24 1052; ENABLE-NEXT: .cfi_offset w20, -32 1053; ENABLE-NEXT: .cfi_offset w21, -40 1054; ENABLE-NEXT: .cfi_offset w22, -48 1055; ENABLE-NEXT: .cfi_offset w23, -56 1056; ENABLE-NEXT: .cfi_offset w24, -64 1057; ENABLE-NEXT: .cfi_offset w25, -72 1058; ENABLE-NEXT: .cfi_offset w26, -80 1059; ENABLE-NEXT: .cfi_offset w27, -88 1060; ENABLE-NEXT: .cfi_offset w28, -96 1061; ENABLE-NEXT: lsl w8, w1, w0 1062; ENABLE-NEXT: lsr w9, w0, w1 1063; ENABLE-NEXT: lsl w14, w0, w1 1064; ENABLE-NEXT: lsr w11, w1, w0 1065; ENABLE-NEXT: add w15, w1, w0 1066; ENABLE-NEXT: sub w10, w8, w9 1067; ENABLE-NEXT: subs w17, w1, w0 1068; ENABLE-NEXT: add w16, w14, w8 1069; ENABLE-NEXT: add w12, w9, w11 1070; ENABLE-NEXT: add w13, w11, w15 1071; ENABLE-NEXT: b.le LBB14_2 1072; ENABLE-NEXT: ; %bb.1: ; %true 1073; ENABLE-NEXT: str w0, [sp] 1074; ENABLE-NEXT: ; InlineAsm Start 1075; ENABLE-NEXT: nop 1076; ENABLE-NEXT: ; InlineAsm End 1077; ENABLE-NEXT: LBB14_2: ; %false 1078; ENABLE-NEXT: str w14, [x2] 1079; ENABLE-NEXT: str w8, [x3] 1080; ENABLE-NEXT: str w9, [x4] 1081; ENABLE-NEXT: str w11, [x5] 1082; ENABLE-NEXT: str w15, [x6] 1083; ENABLE-NEXT: str w17, [x7] 1084; ENABLE-NEXT: stp w0, w1, [x2, #4] 1085; ENABLE-NEXT: stp w16, w10, [x2, #12] 1086; ENABLE-NEXT: stp w12, w13, [x2, #20] 1087; ENABLE-NEXT: sub sp, x29, #80 1088; ENABLE-NEXT: ldp x29, x30, [sp, #80] ; 16-byte Folded Reload 1089; ENABLE-NEXT: ldp x20, x19, [sp, #64] ; 16-byte Folded Reload 1090; ENABLE-NEXT: ldp x22, x21, [sp, #48] ; 16-byte Folded Reload 1091; ENABLE-NEXT: ldp x24, x23, [sp, #32] ; 16-byte Folded Reload 1092; ENABLE-NEXT: ldp x26, x25, [sp, #16] ; 16-byte Folded Reload 1093; ENABLE-NEXT: ldp x28, x27, [sp], #96 ; 16-byte Folded Reload 1094; ENABLE-NEXT: ret 1095; 1096; DISABLE-LABEL: stack_realign2: 1097; DISABLE: ; %bb.0: 1098; DISABLE-NEXT: stp x28, x27, [sp, #-96]! ; 16-byte Folded Spill 1099; DISABLE-NEXT: stp x26, x25, [sp, #16] ; 16-byte Folded Spill 1100; DISABLE-NEXT: stp x24, x23, [sp, #32] ; 16-byte Folded Spill 1101; DISABLE-NEXT: stp x22, x21, [sp, #48] ; 16-byte Folded Spill 1102; DISABLE-NEXT: stp x20, x19, [sp, #64] ; 16-byte Folded Spill 1103; DISABLE-NEXT: stp x29, x30, [sp, #80] ; 16-byte Folded Spill 1104; DISABLE-NEXT: add x29, sp, #80 1105; DISABLE-NEXT: sub x9, sp, #32 1106; DISABLE-NEXT: and sp, x9, #0xffffffffffffffe0 1107; DISABLE-NEXT: .cfi_def_cfa w29, 16 1108; DISABLE-NEXT: .cfi_offset w30, -8 1109; DISABLE-NEXT: .cfi_offset w29, -16 1110; DISABLE-NEXT: .cfi_offset w19, -24 1111; DISABLE-NEXT: .cfi_offset w20, -32 1112; DISABLE-NEXT: .cfi_offset w21, -40 1113; DISABLE-NEXT: .cfi_offset w22, -48 1114; DISABLE-NEXT: .cfi_offset w23, -56 1115; DISABLE-NEXT: .cfi_offset w24, -64 1116; DISABLE-NEXT: .cfi_offset w25, -72 1117; DISABLE-NEXT: .cfi_offset w26, -80 1118; DISABLE-NEXT: .cfi_offset w27, -88 1119; DISABLE-NEXT: .cfi_offset w28, -96 1120; DISABLE-NEXT: lsl w8, w1, w0 1121; DISABLE-NEXT: lsr w9, w0, w1 1122; DISABLE-NEXT: lsl w14, w0, w1 1123; DISABLE-NEXT: lsr w11, w1, w0 1124; DISABLE-NEXT: add w15, w1, w0 1125; DISABLE-NEXT: sub w10, w8, w9 1126; DISABLE-NEXT: subs w17, w1, w0 1127; DISABLE-NEXT: add w16, w14, w8 1128; DISABLE-NEXT: add w12, w9, w11 1129; DISABLE-NEXT: add w13, w11, w15 1130; DISABLE-NEXT: b.le LBB14_2 1131; DISABLE-NEXT: ; %bb.1: ; %true 1132; DISABLE-NEXT: str w0, [sp] 1133; DISABLE-NEXT: ; InlineAsm Start 1134; DISABLE-NEXT: nop 1135; DISABLE-NEXT: ; InlineAsm End 1136; DISABLE-NEXT: LBB14_2: ; %false 1137; DISABLE-NEXT: str w14, [x2] 1138; DISABLE-NEXT: str w8, [x3] 1139; DISABLE-NEXT: str w9, [x4] 1140; DISABLE-NEXT: str w11, [x5] 1141; DISABLE-NEXT: str w15, [x6] 1142; DISABLE-NEXT: str w17, [x7] 1143; DISABLE-NEXT: stp w0, w1, [x2, #4] 1144; DISABLE-NEXT: stp w16, w10, [x2, #12] 1145; DISABLE-NEXT: stp w12, w13, [x2, #20] 1146; DISABLE-NEXT: sub sp, x29, #80 1147; DISABLE-NEXT: ldp x29, x30, [sp, #80] ; 16-byte Folded Reload 1148; DISABLE-NEXT: ldp x20, x19, [sp, #64] ; 16-byte Folded Reload 1149; DISABLE-NEXT: ldp x22, x21, [sp, #48] ; 16-byte Folded Reload 1150; DISABLE-NEXT: ldp x24, x23, [sp, #32] ; 16-byte Folded Reload 1151; DISABLE-NEXT: ldp x26, x25, [sp, #16] ; 16-byte Folded Reload 1152; DISABLE-NEXT: ldp x28, x27, [sp], #96 ; 16-byte Folded Reload 1153; DISABLE-NEXT: ret 1154 %tmp = alloca i32, align 32 1155 %tmp1 = shl i32 %a, %b 1156 %tmp2 = shl i32 %b, %a 1157 %tmp3 = lshr i32 %a, %b 1158 %tmp4 = lshr i32 %b, %a 1159 %tmp5 = add i32 %b, %a 1160 %tmp6 = sub i32 %b, %a 1161 %tmp7 = add i32 %tmp1, %tmp2 1162 %tmp8 = sub i32 %tmp2, %tmp3 1163 %tmp9 = add i32 %tmp3, %tmp4 1164 %tmp10 = add i32 %tmp4, %tmp5 1165 %cmp = icmp slt i32 %a, %b 1166 br i1 %cmp, label %true, label %false 1167 1168true: 1169 store i32 %a, ptr %tmp, align 4 1170 call void asm sideeffect "nop", "~{x19},~{x20},~{x21},~{x22},~{x23},~{x24},~{x25},~{x26},~{x27},~{x28}"() nounwind 1171 br label %false 1172 1173false: 1174 store i32 %tmp1, ptr %ptr1, align 4 1175 store i32 %tmp2, ptr %ptr2, align 4 1176 store i32 %tmp3, ptr %ptr3, align 4 1177 store i32 %tmp4, ptr %ptr4, align 4 1178 store i32 %tmp5, ptr %ptr5, align 4 1179 store i32 %tmp6, ptr %ptr6, align 4 1180 %idx1 = getelementptr inbounds i32, ptr %ptr1, i64 1 1181 store i32 %a, ptr %idx1, align 4 1182 %idx2 = getelementptr inbounds i32, ptr %ptr1, i64 2 1183 store i32 %b, ptr %idx2, align 4 1184 %idx3 = getelementptr inbounds i32, ptr %ptr1, i64 3 1185 store i32 %tmp7, ptr %idx3, align 4 1186 %idx4 = getelementptr inbounds i32, ptr %ptr1, i64 4 1187 store i32 %tmp8, ptr %idx4, align 4 1188 %idx5 = getelementptr inbounds i32, ptr %ptr1, i64 5 1189 store i32 %tmp9, ptr %idx5, align 4 1190 %idx6 = getelementptr inbounds i32, ptr %ptr1, i64 6 1191 store i32 %tmp10, ptr %idx6, align 4 1192 1193 ret void 1194} 1195