diff options
Diffstat (limited to 'test/CodeGen/AArch64/arm64-shrink-wrapping.ll')
| -rw-r--r-- | test/CodeGen/AArch64/arm64-shrink-wrapping.ll | 716 |
1 files changed, 0 insertions, 716 deletions
diff --git a/test/CodeGen/AArch64/arm64-shrink-wrapping.ll b/test/CodeGen/AArch64/arm64-shrink-wrapping.ll deleted file mode 100644 index 0253229c0d7f..000000000000 --- a/test/CodeGen/AArch64/arm64-shrink-wrapping.ll +++ /dev/null @@ -1,716 +0,0 @@ -; RUN: llc %s -o - -enable-shrink-wrap=true -disable-post-ra -disable-fp-elim | FileCheck %s --check-prefix=CHECK --check-prefix=ENABLE -; RUN: llc %s -o - -enable-shrink-wrap=false -disable-post-ra -disable-fp-elim | FileCheck %s --check-prefix=CHECK --check-prefix=DISABLE -target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128" -target triple = "arm64-apple-ios" - - -; Initial motivating example: Simple diamond with a call just on one side. -; CHECK-LABEL: foo: -; -; Compare the arguments and jump to exit. -; No prologue needed. -; ENABLE: cmp w0, w1 -; ENABLE-NEXT: b.ge [[EXIT_LABEL:LBB[0-9_]+]] -; -; Prologue code. -; CHECK: sub sp, sp, #32 -; CHECK-NEXT: stp [[SAVE_SP:x[0-9]+]], [[CSR:x[0-9]+]], [sp, #16] -; CHECK-NEXT: add [[SAVE_SP]], sp, #16 -; -; Compare the arguments and jump to exit. -; After the prologue is set. -; DISABLE: cmp w0, w1 -; DISABLE-NEXT: b.ge [[EXIT_LABEL:LBB[0-9_]+]] -; -; Store %a in the alloca. -; CHECK: stur w0, {{\[}}[[SAVE_SP]], #-4] -; Set the alloca address in the second argument. -; CHECK-NEXT: sub x1, [[SAVE_SP]], #4 -; Set the first argument to zero. -; CHECK-NEXT: mov w0, wzr -; CHECK-NEXT: bl _doSomething -; -; Without shrink-wrapping, epilogue is in the exit block. -; DISABLE: [[EXIT_LABEL]]: -; Epilogue code. -; CHECK-NEXT: ldp x{{[0-9]+}}, [[CSR]], [sp, #16] -; CHECK-NEXT: add sp, sp, #32 -; -; With shrink-wrapping, exit block is a simple return. -; ENABLE: [[EXIT_LABEL]]: -; CHECK-NEXT: ret -define i32 @foo(i32 %a, i32 %b) { - %tmp = alloca i32, align 4 - %tmp2 = icmp slt i32 %a, %b - br i1 %tmp2, label %true, label %false - -true: - store i32 %a, i32* %tmp, align 4 - %tmp4 = call i32 @doSomething(i32 0, i32* %tmp) - br label %false - -false: - %tmp.0 = phi i32 [ %tmp4, %true ], [ %a, %0 ] - ret i32 %tmp.0 -} - -; Function Attrs: optsize -declare i32 @doSomething(i32, i32*) - - -; Check that we do not perform the restore inside the loop whereas the save -; is outside. -; CHECK-LABEL: freqSaveAndRestoreOutsideLoop: -; -; Shrink-wrapping allows to skip the prologue in the else case. -; ENABLE: cbz w0, [[ELSE_LABEL:LBB[0-9_]+]] -; -; Prologue code. -; CHECK: stp [[CSR1:x[0-9]+]], [[CSR2:x[0-9]+]], [sp, #-32]! -; CHECK-NEXT: stp [[CSR3:x[0-9]+]], [[CSR4:x[0-9]+]], [sp, #16] -; CHECK-NEXT: add [[NEW_SP:x[0-9]+]], sp, #16 -; -; DISABLE: cbz w0, [[ELSE_LABEL:LBB[0-9_]+]] -; -; CHECK: mov [[SUM:w[0-9]+]], wzr -; CHECK-NEXT: mov [[IV:w[0-9]+]], #10 -; -; Next BB. -; CHECK: [[LOOP:LBB[0-9_]+]]: ; %for.body -; CHECK: bl _something -; CHECK-NEXT: subs [[IV]], [[IV]], #1 -; CHECK-NEXT: add [[SUM]], w0, [[SUM]] -; CHECK-NEXT: b.ne [[LOOP]] -; -; Next BB. -; Copy SUM into the returned register + << 3. -; CHECK: lsl w0, [[SUM]], #3 -; -; Jump to epilogue. -; DISABLE: b [[EPILOG_BB:LBB[0-9_]+]] -; -; DISABLE: [[ELSE_LABEL]]: ; %if.else -; Shift second argument by one and store into returned register. -; DISABLE: lsl w0, w1, #1 -; DISABLE: [[EPILOG_BB]]: ; %if.end -; -; Epilogue code. -; CHECK: ldp [[CSR3]], [[CSR4]], [sp, #16] -; CHECK-NEXT: ldp [[CSR1]], [[CSR2]], [sp], #32 -; CHECK-NEXT: ret -; -; ENABLE: [[ELSE_LABEL]]: ; %if.else -; Shift second argument by one and store into returned register. -; ENABLE: lsl w0, w1, #1 -; ENABLE: ret -define i32 @freqSaveAndRestoreOutsideLoop(i32 %cond, i32 %N) { -entry: - %tobool = icmp eq i32 %cond, 0 - br i1 %tobool, label %if.else, label %for.body - -for.body: ; preds = %entry, %for.body - %i.05 = phi i32 [ %inc, %for.body ], [ 0, %entry ] - %sum.04 = phi i32 [ %add, %for.body ], [ 0, %entry ] - %call = tail call i32 bitcast (i32 (...)* @something to i32 ()*)() - %add = add nsw i32 %call, %sum.04 - %inc = add nuw nsw i32 %i.05, 1 - %exitcond = icmp eq i32 %inc, 10 - br i1 %exitcond, label %for.end, label %for.body - -for.end: ; preds = %for.body - %shl = shl i32 %add, 3 - br label %if.end - -if.else: ; preds = %entry - %mul = shl nsw i32 %N, 1 - br label %if.end - -if.end: ; preds = %if.else, %for.end - %sum.1 = phi i32 [ %shl, %for.end ], [ %mul, %if.else ] - ret i32 %sum.1 -} - -declare i32 @something(...) - -; Check that we do not perform the shrink-wrapping inside the loop even -; though that would be legal. The cost model must prevent that. -; CHECK-LABEL: freqSaveAndRestoreOutsideLoop2: -; Prologue code. -; CHECK: stp [[CSR1:x[0-9]+]], [[CSR2:x[0-9]+]], [sp, #-32]! -; CHECK-NEXT: stp [[CSR3:x[0-9]+]], [[CSR4:x[0-9]+]], [sp, #16] -; CHECK-NEXT: add [[NEW_SP:x[0-9]+]], sp, #16 -; CHECK: mov [[SUM:w[0-9]+]], wzr -; CHECK-NEXT: mov [[IV:w[0-9]+]], #10 -; Next BB. -; CHECK: [[LOOP_LABEL:LBB[0-9_]+]]: ; %for.body -; CHECK: bl _something -; CHECK-NEXT: subs [[IV]], [[IV]], #1 -; CHECK-NEXT: add [[SUM]], w0, [[SUM]] -; CHECK-NEXT: b.ne [[LOOP_LABEL]] -; Next BB. -; CHECK: ; %for.end -; CHECK: mov w0, [[SUM]] -; CHECK-NEXT: ldp [[CSR3]], [[CSR4]], [sp, #16] -; CHECK-NEXT: ldp [[CSR1]], [[CSR2]], [sp], #32 -; CHECK-NEXT: ret -define i32 @freqSaveAndRestoreOutsideLoop2(i32 %cond) { -entry: - br label %for.body - -for.body: ; preds = %for.body, %entry - %i.04 = phi i32 [ 0, %entry ], [ %inc, %for.body ] - %sum.03 = phi i32 [ 0, %entry ], [ %add, %for.body ] - %call = tail call i32 bitcast (i32 (...)* @something to i32 ()*)() - %add = add nsw i32 %call, %sum.03 - %inc = add nuw nsw i32 %i.04, 1 - %exitcond = icmp eq i32 %inc, 10 - br i1 %exitcond, label %for.end, label %for.body - -for.end: ; preds = %for.body - ret i32 %add -} - -; Check with a more complex case that we do not have save within the loop and -; restore outside. -; CHECK-LABEL: loopInfoSaveOutsideLoop: -; -; ENABLE: cbz w0, [[ELSE_LABEL:LBB[0-9_]+]] -; -; Prologue code. -; CHECK: stp [[CSR1:x[0-9]+]], [[CSR2:x[0-9]+]], [sp, #-32]! -; CHECK-NEXT: stp [[CSR3:x[0-9]+]], [[CSR4:x[0-9]+]], [sp, #16] -; CHECK-NEXT: add [[NEW_SP:x[0-9]+]], sp, #16 -; -; DISABLE: cbz w0, [[ELSE_LABEL:LBB[0-9_]+]] -; -; CHECK: mov [[SUM:w[0-9]+]], wzr -; CHECK-NEXT: mov [[IV:w[0-9]+]], #10 -; -; CHECK: [[LOOP_LABEL:LBB[0-9_]+]]: ; %for.body -; CHECK: bl _something -; CHECK-NEXT: subs [[IV]], [[IV]], #1 -; CHECK-NEXT: add [[SUM]], w0, [[SUM]] -; CHECK-NEXT: b.ne [[LOOP_LABEL]] -; Next BB. -; CHECK: bl _somethingElse -; CHECK-NEXT: lsl w0, [[SUM]], #3 -; -; Jump to epilogue. -; DISABLE: b [[EPILOG_BB:LBB[0-9_]+]] -; -; DISABLE: [[ELSE_LABEL]]: ; %if.else -; Shift second argument by one and store into returned register. -; DISABLE: lsl w0, w1, #1 -; DISABLE: [[EPILOG_BB]]: ; %if.end -; Epilogue code. -; CHECK-NEXT: ldp [[CSR3]], [[CSR4]], [sp, #16] -; CHECK-NEXT: ldp [[CSR1]], [[CSR2]], [sp], #32 -; CHECK-NEXT: ret -; -; ENABLE: [[ELSE_LABEL]]: ; %if.else -; Shift second argument by one and store into returned register. -; ENABLE: lsl w0, w1, #1 -; ENABLE: ret -define i32 @loopInfoSaveOutsideLoop(i32 %cond, i32 %N) { -entry: - %tobool = icmp eq i32 %cond, 0 - br i1 %tobool, label %if.else, label %for.body - -for.body: ; preds = %entry, %for.body - %i.05 = phi i32 [ %inc, %for.body ], [ 0, %entry ] - %sum.04 = phi i32 [ %add, %for.body ], [ 0, %entry ] - %call = tail call i32 bitcast (i32 (...)* @something to i32 ()*)() - %add = add nsw i32 %call, %sum.04 - %inc = add nuw nsw i32 %i.05, 1 - %exitcond = icmp eq i32 %inc, 10 - br i1 %exitcond, label %for.end, label %for.body - -for.end: ; preds = %for.body - tail call void bitcast (void (...)* @somethingElse to void ()*)() - %shl = shl i32 %add, 3 - br label %if.end - -if.else: ; preds = %entry - %mul = shl nsw i32 %N, 1 - br label %if.end - -if.end: ; preds = %if.else, %for.end - %sum.1 = phi i32 [ %shl, %for.end ], [ %mul, %if.else ] - ret i32 %sum.1 -} - -declare void @somethingElse(...) - -; Check with a more complex case that we do not have restore within the loop and -; save outside. -; CHECK-LABEL: loopInfoRestoreOutsideLoop: -; -; ENABLE: cbz w0, [[ELSE_LABEL:LBB[0-9_]+]] -; -; CHECK: stp [[CSR1:x[0-9]+]], [[CSR2:x[0-9]+]], [sp, #-32]! -; CHECK-NEXT: stp [[CSR3:x[0-9]+]], [[CSR4:x[0-9]+]], [sp, #16] -; CHECK-NEXT: add [[NEW_SP:x[0-9]+]], sp, #16 -; -; DISABLE: cbz w0, [[ELSE_LABEL:LBB[0-9_]+]] -; -; CHECK: bl _somethingElse -; CHECK-NEXT: mov [[SUM:w[0-9]+]], wzr -; CHECK-NEXT: mov [[IV:w[0-9]+]], #10 -; -; CHECK: [[LOOP_LABEL:LBB[0-9_]+]]: ; %for.body -; CHECK: bl _something -; CHECK-NEXT: subs [[IV]], [[IV]], #1 -; CHECK-NEXT: add [[SUM]], w0, [[SUM]] -; CHECK-NEXT: b.ne [[LOOP_LABEL]] -; Next BB. -; CHECK: lsl w0, [[SUM]], #3 -; -; Jump to epilogue. -; DISABLE: b [[EPILOG_BB:LBB[0-9_]+]] -; -; DISABLE: [[ELSE_LABEL]]: ; %if.else -; Shift second argument by one and store into returned register. -; DISABLE: lsl w0, w1, #1 -; DISABLE: [[EPILOG_BB]]: ; %if.end -; Epilogue code. -; CHECK: ldp [[CSR3]], [[CSR4]], [sp, #16] -; CHECK-NEXT: ldp [[CSR1]], [[CSR2]], [sp], #32 -; CHECK-NEXT: ret -; -; ENABLE: [[ELSE_LABEL]]: ; %if.else -; Shift second argument by one and store into returned register. -; ENABLE: lsl w0, w1, #1 -; ENABLE: ret -define i32 @loopInfoRestoreOutsideLoop(i32 %cond, i32 %N) #0 { -entry: - %tobool = icmp eq i32 %cond, 0 - br i1 %tobool, label %if.else, label %if.then - -if.then: ; preds = %entry - tail call void bitcast (void (...)* @somethingElse to void ()*)() - br label %for.body - -for.body: ; preds = %for.body, %if.then - %i.05 = phi i32 [ 0, %if.then ], [ %inc, %for.body ] - %sum.04 = phi i32 [ 0, %if.then ], [ %add, %for.body ] - %call = tail call i32 bitcast (i32 (...)* @something to i32 ()*)() - %add = add nsw i32 %call, %sum.04 - %inc = add nuw nsw i32 %i.05, 1 - %exitcond = icmp eq i32 %inc, 10 - br i1 %exitcond, label %for.end, label %for.body - -for.end: ; preds = %for.body - %shl = shl i32 %add, 3 - br label %if.end - -if.else: ; preds = %entry - %mul = shl nsw i32 %N, 1 - br label %if.end - -if.end: ; preds = %if.else, %for.end - %sum.1 = phi i32 [ %shl, %for.end ], [ %mul, %if.else ] - ret i32 %sum.1 -} - -; Check that we handle function with no frame information correctly. -; CHECK-LABEL: emptyFrame: -; CHECK: ; %entry -; CHECK-NEXT: mov w0, wzr -; CHECK-NEXT: ret -define i32 @emptyFrame() { -entry: - ret i32 0 -} - -; Check that we handle variadic function correctly. -; CHECK-LABEL: variadicFunc: -; -; ENABLE: cbz w0, [[ELSE_LABEL:LBB[0-9_]+]] -; -; Prologue code. -; CHECK: sub sp, sp, #16 -; DISABLE: cbz w0, [[ELSE_LABEL:LBB[0-9_]+]] -; -; Sum is merged with the returned register. -; CHECK: add [[VA_BASE:x[0-9]+]], sp, #16 -; CHECK-NEXT: cmp w1, #1 -; CHECK-NEXT: str [[VA_BASE]], [sp, #8] -; CHECK-NEXT: mov [[SUM:w0]], wzr -; CHECK-NEXT: b.lt [[IFEND_LABEL:LBB[0-9_]+]] -; -; CHECK: [[LOOP_LABEL:LBB[0-9_]+]]: ; %for.body -; CHECK: ldr [[VA_ADDR:x[0-9]+]], [sp, #8] -; CHECK-NEXT: add [[NEXT_VA_ADDR:x[0-9]+]], [[VA_ADDR]], #8 -; CHECK-NEXT: str [[NEXT_VA_ADDR]], [sp, #8] -; CHECK-NEXT: ldr [[VA_VAL:w[0-9]+]], {{\[}}[[VA_ADDR]]] -; CHECK-NEXT: subs w1, w1, #1 -; CHECK-NEXT: add [[SUM]], [[SUM]], [[VA_VAL]] -; CHECK-NEXT: b.ne [[LOOP_LABEL]] -; CHECK-NEXT: [[IFEND_LABEL]]: -; Epilogue code. -; CHECK: add sp, sp, #16 -; CHECK-NEXT: ret -; -; CHECK: [[ELSE_LABEL]]: ; %if.else -; CHECK-NEXT: lsl w0, w1, #1 -; DISABLE-NEXT: add sp, sp, #16 -; CHECK-NEXT: ret -define i32 @variadicFunc(i32 %cond, i32 %count, ...) #0 { -entry: - %ap = alloca i8*, align 8 - %tobool = icmp eq i32 %cond, 0 - br i1 %tobool, label %if.else, label %if.then - -if.then: ; preds = %entry - %ap1 = bitcast i8** %ap to i8* - call void @llvm.va_start(i8* %ap1) - %cmp6 = icmp sgt i32 %count, 0 - br i1 %cmp6, label %for.body, label %for.end - -for.body: ; preds = %if.then, %for.body - %i.08 = phi i32 [ %inc, %for.body ], [ 0, %if.then ] - %sum.07 = phi i32 [ %add, %for.body ], [ 0, %if.then ] - %0 = va_arg i8** %ap, i32 - %add = add nsw i32 %sum.07, %0 - %inc = add nuw nsw i32 %i.08, 1 - %exitcond = icmp eq i32 %inc, %count - br i1 %exitcond, label %for.end, label %for.body - -for.end: ; preds = %for.body, %if.then - %sum.0.lcssa = phi i32 [ 0, %if.then ], [ %add, %for.body ] - call void @llvm.va_end(i8* %ap1) - br label %if.end - -if.else: ; preds = %entry - %mul = shl nsw i32 %count, 1 - br label %if.end - -if.end: ; preds = %if.else, %for.end - %sum.1 = phi i32 [ %sum.0.lcssa, %for.end ], [ %mul, %if.else ] - ret i32 %sum.1 -} - -declare void @llvm.va_start(i8*) - -declare void @llvm.va_end(i8*) - -; Check that we handle inline asm correctly. -; CHECK-LABEL: inlineAsm: -; -; ENABLE: cbz w0, [[ELSE_LABEL:LBB[0-9_]+]] -; -; Prologue code. -; Make sure we save the CSR used in the inline asm: x19. -; CHECK: stp [[CSR1:x[0-9]+]], [[CSR2:x19]], [sp, #-16]! -; -; DISABLE: cbz w0, [[ELSE_LABEL:LBB[0-9_]+]] -; -; CHECK: mov [[IV:w[0-9]+]], #10 -; -; CHECK: [[LOOP_LABEL:LBB[0-9_]+]]: ; %for.body -; Inline asm statement. -; CHECK: subs [[IV]], [[IV]], #1 -; CHECK: add x19, x19, #1 -; CHECK: b.ne [[LOOP_LABEL]] -; Next BB. -; CHECK: mov w0, wzr -; Epilogue code. -; CHECK-NEXT: ldp [[CSR1]], [[CSR2]], [sp], #16 -; CHECK-NEXT: ret -; Next BB. -; CHECK: [[ELSE_LABEL]]: ; %if.else -; CHECK-NEXT: lsl w0, w1, #1 -; Epilogue code. -; DISABLE-NEXT: ldp [[CSR1]], [[CSR2]], [sp], #16 -; CHECK-NEXT: ret -define i32 @inlineAsm(i32 %cond, i32 %N) { -entry: - %tobool = icmp eq i32 %cond, 0 - br i1 %tobool, label %if.else, label %for.body - -for.body: ; preds = %entry, %for.body - %i.03 = phi i32 [ %inc, %for.body ], [ 0, %entry ] - tail call void asm sideeffect "add x19, x19, #1", "~{x19}"() - %inc = add nuw nsw i32 %i.03, 1 - %exitcond = icmp eq i32 %inc, 10 - br i1 %exitcond, label %if.end, label %for.body - -if.else: ; preds = %entry - %mul = shl nsw i32 %N, 1 - br label %if.end - -if.end: ; preds = %for.body, %if.else - %sum.0 = phi i32 [ %mul, %if.else ], [ 0, %for.body ] - ret i32 %sum.0 -} - -; Check that we handle calls to variadic functions correctly. -; CHECK-LABEL: callVariadicFunc: -; -; ENABLE: cbz w0, [[ELSE_LABEL:LBB[0-9_]+]] -; -; Prologue code. -; CHECK: sub sp, sp, #64 -; CHECK-NEXT: stp [[CSR1:x[0-9]+]], [[CSR2:x[0-9]+]], [sp, #48] -; CHECK-NEXT: add [[NEW_SP:x[0-9]+]], sp, #48 -; -; DISABLE: cbz w0, [[ELSE_LABEL:LBB[0-9_]+]] -; Setup of the varags. -; CHECK: stp x1, x1, [sp, #32] -; CHECK-NEXT: stp x1, x1, [sp, #16] -; CHECK-NEXT: stp x1, x1, [sp] -; CHECK-NEXT: mov w0, w1 -; CHECK-NEXT: bl _someVariadicFunc -; CHECK-NEXT: lsl w0, w0, #3 -; -; DISABLE: b [[IFEND_LABEL:LBB[0-9_]+]] -; DISABLE: [[ELSE_LABEL]]: ; %if.else -; DISABLE-NEXT: lsl w0, w1, #1 -; DISABLE: [[IFEND_LABEL]]: ; %if.end -; -; Epilogue code. -; CHECK: ldp [[CSR1]], [[CSR2]], [sp, #48] -; CHECK-NEXT: add sp, sp, #64 -; CHECK-NEXT: ret -; -; ENABLE: [[ELSE_LABEL]]: ; %if.else -; ENABLE-NEXT: lsl w0, w1, #1 -; ENABLE-NEXT: ret -define i32 @callVariadicFunc(i32 %cond, i32 %N) { -entry: - %tobool = icmp eq i32 %cond, 0 - br i1 %tobool, label %if.else, label %if.then - -if.then: ; preds = %entry - %call = tail call i32 (i32, ...) @someVariadicFunc(i32 %N, i32 %N, i32 %N, i32 %N, i32 %N, i32 %N, i32 %N) - %shl = shl i32 %call, 3 - br label %if.end - -if.else: ; preds = %entry - %mul = shl nsw i32 %N, 1 - br label %if.end - -if.end: ; preds = %if.else, %if.then - %sum.0 = phi i32 [ %shl, %if.then ], [ %mul, %if.else ] - ret i32 %sum.0 -} - -declare i32 @someVariadicFunc(i32, ...) - -; Make sure we do not insert unreachable code after noreturn function. -; Although this is not incorrect to insert such code, it is useless -; and it hurts the binary size. -; -; CHECK-LABEL: noreturn: -; DISABLE: stp -; -; CHECK: cbnz w0, [[ABORT:LBB[0-9_]+]] -; -; CHECK: mov w0, #42 -; -; DISABLE-NEXT: ldp -; -; CHECK-NEXT: ret -; -; CHECK: [[ABORT]]: ; %if.abort -; -; ENABLE: stp -; -; CHECK: bl _abort -; ENABLE-NOT: ldp -define i32 @noreturn(i8 signext %bad_thing) { -entry: - %tobool = icmp eq i8 %bad_thing, 0 - br i1 %tobool, label %if.end, label %if.abort - -if.abort: - tail call void @abort() #0 - unreachable - -if.end: - ret i32 42 -} - -declare void @abort() #0 - -attributes #0 = { noreturn nounwind } - -; Make sure that we handle infinite loops properly When checking that the Save -; and Restore blocks are control flow equivalent, the loop searches for the -; immediate (post) dominator for the (restore) save blocks. When either the Save -; or Restore block is located in an infinite loop the only immediate (post) -; dominator is itself. In this case, we cannot perform shrink wrapping, but we -; should return gracefully and continue compilation. -; The only condition for this test is the compilation finishes correctly. -; -; CHECK-LABEL: infiniteloop -; CHECK: ret -define void @infiniteloop() { -entry: - br i1 undef, label %if.then, label %if.end - -if.then: - %ptr = alloca i32, i32 4 - br label %for.body - -for.body: ; preds = %for.body, %entry - %sum.03 = phi i32 [ 0, %if.then ], [ %add, %for.body ] - %call = tail call i32 bitcast (i32 (...)* @something to i32 ()*)() - %add = add nsw i32 %call, %sum.03 - store i32 %add, i32* %ptr - br label %for.body - -if.end: - ret void -} - -; Another infinite loop test this time with a body bigger than just one block. -; CHECK-LABEL: infiniteloop2 -; CHECK: ret -define void @infiniteloop2() { -entry: - br i1 undef, label %if.then, label %if.end - -if.then: - %ptr = alloca i32, i32 4 - br label %for.body - -for.body: ; preds = %for.body, %entry - %sum.03 = phi i32 [ 0, %if.then ], [ %add, %body1 ], [ 1, %body2] - %call = tail call i32 asm "mov $0, #0", "=r,~{x19}"() - %add = add nsw i32 %call, %sum.03 - store i32 %add, i32* %ptr - br i1 undef, label %body1, label %body2 - -body1: - tail call void asm sideeffect "nop", "~{x19}"() - br label %for.body - -body2: - tail call void asm sideeffect "nop", "~{x19}"() - br label %for.body - -if.end: - ret void -} - -; Another infinite loop test this time with two nested infinite loop. -; CHECK-LABEL: infiniteloop3 -; CHECK: ret -define void @infiniteloop3() { -entry: - br i1 undef, label %loop2a, label %body - -body: ; preds = %entry - br i1 undef, label %loop2a, label %end - -loop1: ; preds = %loop2a, %loop2b - %var.phi = phi i32* [ %next.phi, %loop2b ], [ %var, %loop2a ] - %next.phi = phi i32* [ %next.load, %loop2b ], [ %next.var, %loop2a ] - %0 = icmp eq i32* %var, null - %next.load = load i32*, i32** undef - br i1 %0, label %loop2a, label %loop2b - -loop2a: ; preds = %loop1, %body, %entry - %var = phi i32* [ null, %body ], [ null, %entry ], [ %next.phi, %loop1 ] - %next.var = phi i32* [ undef, %body ], [ null, %entry ], [ %next.load, %loop1 ] - br label %loop1 - -loop2b: ; preds = %loop1 - %gep1 = bitcast i32* %var.phi to i32* - %next.ptr = bitcast i32* %gep1 to i32** - store i32* %next.phi, i32** %next.ptr - br label %loop1 - -end: - ret void -} - -; Re-aligned stack pointer. See bug 26642. Avoid clobbering live -; values in the prologue when re-aligning the stack pointer. -; CHECK-LABEL: stack_realign: -; ENABLE-DAG: lsl w[[LSL1:[0-9]+]], w0, w1 -; ENABLE-DAG: lsl w[[LSL2:[0-9]+]], w1, w0 -; DISABLE-NOT: lsl w[[LSL1:[0-9]+]], w0, w1 -; DISABLE-NOT: lsl w[[LSL2:[0-9]+]], w1, w0 -; CHECK: stp x29, x30, [sp, #-16]! -; CHECK: mov x29, sp -; ENABLE-NOT: sub x[[LSL1]], sp, #16 -; ENABLE-NOT: sub x[[LSL2]], sp, #16 -; DISABLE: sub x{{[0-9]+}}, sp, #16 -; DISABLE-DAG: lsl w[[LSL1:[0-9]+]], w0, w1 -; DISABLE-DAG: lsl w[[LSL2:[0-9]+]], w1, w0 -; CHECK-DAG: str w[[LSL1]], -; CHECK-DAG: str w[[LSL2]], - -define i32 @stack_realign(i32 %a, i32 %b, i32* %ptr1, i32* %ptr2) { - %tmp = alloca i32, align 32 - %shl1 = shl i32 %a, %b - %shl2 = shl i32 %b, %a - %tmp2 = icmp slt i32 %a, %b - br i1 %tmp2, label %true, label %false - -true: - store i32 %a, i32* %tmp, align 4 - %tmp4 = load i32, i32* %tmp - br label %false - -false: - %tmp.0 = phi i32 [ %tmp4, %true ], [ %a, %0 ] - store i32 %shl1, i32* %ptr1 - store i32 %shl2, i32* %ptr2 - ret i32 %tmp.0 -} - -; Re-aligned stack pointer with all caller-save regs live. See bug -; 26642. In this case we currently avoid shrink wrapping because -; ensuring we have a scratch register to re-align the stack pointer is -; too complicated. Output should be the same for both enabled and -; disabled shrink wrapping. -; CHECK-LABEL: stack_realign2: -; CHECK: stp {{x[0-9]+}}, {{x[0-9]+}}, [sp, #-{{[0-9]+}}]! -; CHECK: add x29, sp, #{{[0-9]+}} -; CHECK: lsl {{w[0-9]+}}, w0, w1 - -define void @stack_realign2(i32 %a, i32 %b, i32* %ptr1, i32* %ptr2, i32* %ptr3, i32* %ptr4, i32* %ptr5, i32* %ptr6) { - %tmp = alloca i32, align 32 - %tmp1 = shl i32 %a, %b - %tmp2 = shl i32 %b, %a - %tmp3 = lshr i32 %a, %b - %tmp4 = lshr i32 %b, %a - %tmp5 = add i32 %b, %a - %tmp6 = sub i32 %b, %a - %tmp7 = add i32 %tmp1, %tmp2 - %tmp8 = sub i32 %tmp2, %tmp3 - %tmp9 = add i32 %tmp3, %tmp4 - %tmp10 = add i32 %tmp4, %tmp5 - %cmp = icmp slt i32 %a, %b - br i1 %cmp, label %true, label %false - -true: - store i32 %a, i32* %tmp, align 4 - call void asm sideeffect "nop", "~{x19},~{x20},~{x21},~{x22},~{x23},~{x24},~{x25},~{x26},~{x27},~{x28}"() nounwind - br label %false - -false: - store i32 %tmp1, i32* %ptr1, align 4 - store i32 %tmp2, i32* %ptr2, align 4 - store i32 %tmp3, i32* %ptr3, align 4 - store i32 %tmp4, i32* %ptr4, align 4 - store i32 %tmp5, i32* %ptr5, align 4 - store i32 %tmp6, i32* %ptr6, align 4 - %idx1 = getelementptr inbounds i32, i32* %ptr1, i64 1 - store i32 %a, i32* %idx1, align 4 - %idx2 = getelementptr inbounds i32, i32* %ptr1, i64 2 - store i32 %b, i32* %idx2, align 4 - %idx3 = getelementptr inbounds i32, i32* %ptr1, i64 3 - store i32 %tmp7, i32* %idx3, align 4 - %idx4 = getelementptr inbounds i32, i32* %ptr1, i64 4 - store i32 %tmp8, i32* %idx4, align 4 - %idx5 = getelementptr inbounds i32, i32* %ptr1, i64 5 - store i32 %tmp9, i32* %idx5, align 4 - %idx6 = getelementptr inbounds i32, i32* %ptr1, i64 6 - store i32 %tmp10, i32* %idx6, align 4 - - ret void -} |
