
mflr is kind of expensive on Power version smaller than 10, so we should schedule the store for the mflr's def away from mflr. In epilogue, the expensive mtlr has no user for its def, so it doesn't matter that the load and the mtlr are back-to-back. Reviewed By: RolandF Differential Revision: https://reviews.llvm.org/D137423
260 lines
8.9 KiB
LLVM
260 lines
8.9 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
|
; RUN: llc -verify-machineinstrs -ppc-vsr-nums-as-vr -ppc-asm-full-reg-names \
|
|
; RUN: -mtriple=powerpc64le-unknown-linux-gnu -mcpu=pwr9 < %s | FileCheck %s --check-prefix=CHECK-PWR9
|
|
; RUN: llc -verify-machineinstrs -ppc-vsr-nums-as-vr -ppc-asm-full-reg-names \
|
|
; RUN: -mtriple=powerpc64-unknown-linux-gnu -mcpu=pwr8 < %s | FileCheck %s
|
|
|
|
; Check CSR split can work properly for tests below.
|
|
|
|
@a = dso_local local_unnamed_addr global i32 0, align 4
|
|
|
|
define dso_local signext i32 @test1(ptr %b) local_unnamed_addr {
|
|
; CHECK-PWR9-LABEL: test1:
|
|
; CHECK-PWR9: # %bb.0: # %entry
|
|
; CHECK-PWR9-NEXT: mflr r0
|
|
; CHECK-PWR9-NEXT: .cfi_def_cfa_offset 48
|
|
; CHECK-PWR9-NEXT: .cfi_offset lr, 16
|
|
; CHECK-PWR9-NEXT: .cfi_offset r30, -16
|
|
; CHECK-PWR9-NEXT: std r30, -16(r1) # 8-byte Folded Spill
|
|
; CHECK-PWR9-NEXT: stdu r1, -48(r1)
|
|
; CHECK-PWR9-NEXT: mr r30, r3
|
|
; CHECK-PWR9-NEXT: addis r3, r2, a@toc@ha
|
|
; CHECK-PWR9-NEXT: std r0, 64(r1)
|
|
; CHECK-PWR9-NEXT: lwa r3, a@toc@l(r3)
|
|
; CHECK-PWR9-NEXT: cmpld r3, r30
|
|
; CHECK-PWR9-NEXT: # implicit-def: $r3
|
|
; CHECK-PWR9-NEXT: bne cr0, .LBB0_2
|
|
; CHECK-PWR9-NEXT: # %bb.1: # %if.then
|
|
; CHECK-PWR9-NEXT: bl callVoid
|
|
; CHECK-PWR9-NEXT: nop
|
|
; CHECK-PWR9-NEXT: mr r3, r30
|
|
; CHECK-PWR9-NEXT: bl callNonVoid
|
|
; CHECK-PWR9-NEXT: nop
|
|
; CHECK-PWR9-NEXT: .LBB0_2: # %if.end
|
|
; CHECK-PWR9-NEXT: extsw r3, r3
|
|
; CHECK-PWR9-NEXT: addi r1, r1, 48
|
|
; CHECK-PWR9-NEXT: ld r0, 16(r1)
|
|
; CHECK-PWR9-NEXT: ld r30, -16(r1) # 8-byte Folded Reload
|
|
; CHECK-PWR9-NEXT: mtlr r0
|
|
; CHECK-PWR9-NEXT: blr
|
|
;
|
|
; CHECK-LABEL: test1:
|
|
; CHECK: # %bb.0: # %entry
|
|
; CHECK-NEXT: mflr r0
|
|
; CHECK-NEXT: stdu r1, -128(r1)
|
|
; CHECK-NEXT: std r0, 144(r1)
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 128
|
|
; CHECK-NEXT: .cfi_offset lr, 16
|
|
; CHECK-NEXT: .cfi_offset r30, -16
|
|
; CHECK-NEXT: addis r4, r2, a@toc@ha
|
|
; CHECK-NEXT: std r30, 112(r1) # 8-byte Folded Spill
|
|
; CHECK-NEXT: mr r30, r3
|
|
; CHECK-NEXT: lwa r4, a@toc@l(r4)
|
|
; CHECK-NEXT: cmpld r4, r3
|
|
; CHECK-NEXT: # implicit-def: $r3
|
|
; CHECK-NEXT: bne cr0, .LBB0_2
|
|
; CHECK-NEXT: # %bb.1: # %if.then
|
|
; CHECK-NEXT: bl callVoid
|
|
; CHECK-NEXT: nop
|
|
; CHECK-NEXT: mr r3, r30
|
|
; CHECK-NEXT: bl callNonVoid
|
|
; CHECK-NEXT: nop
|
|
; CHECK-NEXT: .LBB0_2: # %if.end
|
|
; CHECK-NEXT: ld r30, 112(r1) # 8-byte Folded Reload
|
|
; CHECK-NEXT: extsw r3, r3
|
|
; CHECK-NEXT: addi r1, r1, 128
|
|
; CHECK-NEXT: ld r0, 16(r1)
|
|
; CHECK-NEXT: mtlr r0
|
|
; CHECK-NEXT: blr
|
|
entry:
|
|
%0 = load i32, ptr @a, align 4, !tbaa !2
|
|
%conv = sext i32 %0 to i64
|
|
%1 = inttoptr i64 %conv to ptr
|
|
%cmp = icmp eq ptr %1, %b
|
|
br i1 %cmp, label %if.then, label %if.end
|
|
|
|
if.then: ; preds = %entry
|
|
%call = tail call signext i32 @callVoid()
|
|
%call2 = tail call signext i32 @callNonVoid(ptr %b)
|
|
br label %if.end
|
|
|
|
if.end: ; preds = %if.then, %entry
|
|
%retval.0 = phi i32 [ %call2, %if.then ], [ undef, %entry ]
|
|
ret i32 %retval.0
|
|
}
|
|
|
|
declare signext i32 @callVoid(...) local_unnamed_addr
|
|
|
|
declare signext i32 @callNonVoid(ptr) local_unnamed_addr
|
|
|
|
define dso_local signext i32 @test2(ptr %p1) local_unnamed_addr {
|
|
; CHECK-PWR9-LABEL: test2:
|
|
; CHECK-PWR9: # %bb.0: # %entry
|
|
; CHECK-PWR9-NEXT: mflr r0
|
|
; CHECK-PWR9-NEXT: .cfi_def_cfa_offset 48
|
|
; CHECK-PWR9-NEXT: .cfi_offset lr, 16
|
|
; CHECK-PWR9-NEXT: .cfi_offset r30, -16
|
|
; CHECK-PWR9-NEXT: std r30, -16(r1) # 8-byte Folded Spill
|
|
; CHECK-PWR9-NEXT: stdu r1, -48(r1)
|
|
; CHECK-PWR9-NEXT: mr r30, r3
|
|
; CHECK-PWR9-NEXT: li r3, 0
|
|
; CHECK-PWR9-NEXT: std r0, 64(r1)
|
|
; CHECK-PWR9-NEXT: cmpldi r30, 0
|
|
; CHECK-PWR9-NEXT: beq cr0, .LBB1_3
|
|
; CHECK-PWR9-NEXT: # %bb.1: # %if.end
|
|
; CHECK-PWR9-NEXT: addis r4, r2, a@toc@ha
|
|
; CHECK-PWR9-NEXT: lwa r4, a@toc@l(r4)
|
|
; CHECK-PWR9-NEXT: cmpld r4, r30
|
|
; CHECK-PWR9-NEXT: bne cr0, .LBB1_3
|
|
; CHECK-PWR9-NEXT: # %bb.2: # %if.then2
|
|
; CHECK-PWR9-NEXT: bl callVoid
|
|
; CHECK-PWR9-NEXT: nop
|
|
; CHECK-PWR9-NEXT: mr r3, r30
|
|
; CHECK-PWR9-NEXT: bl callNonVoid
|
|
; CHECK-PWR9-NEXT: nop
|
|
; CHECK-PWR9-NEXT: .LBB1_3: # %return
|
|
; CHECK-PWR9-NEXT: addi r1, r1, 48
|
|
; CHECK-PWR9-NEXT: ld r0, 16(r1)
|
|
; CHECK-PWR9-NEXT: ld r30, -16(r1) # 8-byte Folded Reload
|
|
; CHECK-PWR9-NEXT: mtlr r0
|
|
; CHECK-PWR9-NEXT: blr
|
|
;
|
|
; CHECK-LABEL: test2:
|
|
; CHECK: # %bb.0: # %entry
|
|
; CHECK-NEXT: mflr r0
|
|
; CHECK-NEXT: stdu r1, -128(r1)
|
|
; CHECK-NEXT: std r0, 144(r1)
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 128
|
|
; CHECK-NEXT: .cfi_offset lr, 16
|
|
; CHECK-NEXT: .cfi_offset r30, -16
|
|
; CHECK-NEXT: std r30, 112(r1) # 8-byte Folded Spill
|
|
; CHECK-NEXT: mr r30, r3
|
|
; CHECK-NEXT: cmpldi r3, 0
|
|
; CHECK-NEXT: li r3, 0
|
|
; CHECK-NEXT: beq cr0, .LBB1_3
|
|
; CHECK-NEXT: # %bb.1: # %if.end
|
|
; CHECK-NEXT: addis r4, r2, a@toc@ha
|
|
; CHECK-NEXT: lwa r4, a@toc@l(r4)
|
|
; CHECK-NEXT: cmpld r4, r30
|
|
; CHECK-NEXT: bne cr0, .LBB1_3
|
|
; CHECK-NEXT: # %bb.2: # %if.then2
|
|
; CHECK-NEXT: bl callVoid
|
|
; CHECK-NEXT: nop
|
|
; CHECK-NEXT: mr r3, r30
|
|
; CHECK-NEXT: bl callNonVoid
|
|
; CHECK-NEXT: nop
|
|
; CHECK-NEXT: .LBB1_3: # %return
|
|
; CHECK-NEXT: ld r30, 112(r1) # 8-byte Folded Reload
|
|
; CHECK-NEXT: addi r1, r1, 128
|
|
; CHECK-NEXT: ld r0, 16(r1)
|
|
; CHECK-NEXT: mtlr r0
|
|
; CHECK-NEXT: blr
|
|
entry:
|
|
%tobool = icmp eq ptr %p1, null
|
|
br i1 %tobool, label %return, label %if.end
|
|
|
|
if.end: ; preds = %entry
|
|
%0 = load i32, ptr @a, align 4, !tbaa !2
|
|
%conv = sext i32 %0 to i64
|
|
%1 = inttoptr i64 %conv to ptr
|
|
%cmp = icmp eq ptr %1, %p1
|
|
br i1 %cmp, label %if.then2, label %return
|
|
|
|
if.then2: ; preds = %if.end
|
|
%call = tail call signext i32 @callVoid()
|
|
%call3 = tail call signext i32 @callNonVoid(ptr nonnull %p1)
|
|
br label %return
|
|
|
|
return: ; preds = %if.end, %entry, %if.then2
|
|
%retval.0 = phi i32 [ %call3, %if.then2 ], [ 0, %entry ], [ 0, %if.end ]
|
|
ret i32 %retval.0
|
|
}
|
|
|
|
|
|
define dso_local ptr @test3(ptr nocapture %p1, i8 zeroext %p2) local_unnamed_addr {
|
|
; CHECK-PWR9-LABEL: test3:
|
|
; CHECK-PWR9: # %bb.0: # %entry
|
|
; CHECK-PWR9-NEXT: mflr r0
|
|
; CHECK-PWR9-NEXT: .cfi_def_cfa_offset 64
|
|
; CHECK-PWR9-NEXT: .cfi_offset lr, 16
|
|
; CHECK-PWR9-NEXT: .cfi_offset r29, -24
|
|
; CHECK-PWR9-NEXT: .cfi_offset r30, -16
|
|
; CHECK-PWR9-NEXT: std r29, -24(r1) # 8-byte Folded Spill
|
|
; CHECK-PWR9-NEXT: std r30, -16(r1) # 8-byte Folded Spill
|
|
; CHECK-PWR9-NEXT: stdu r1, -64(r1)
|
|
; CHECK-PWR9-NEXT: std r0, 80(r1)
|
|
; CHECK-PWR9-NEXT: ld r30, 0(r3)
|
|
; CHECK-PWR9-NEXT: cmpldi r30, 0
|
|
; CHECK-PWR9-NEXT: beq cr0, .LBB2_2
|
|
; CHECK-PWR9-NEXT: # %bb.1: # %land.rhs
|
|
; CHECK-PWR9-NEXT: mr r29, r3
|
|
; CHECK-PWR9-NEXT: mr r3, r30
|
|
; CHECK-PWR9-NEXT: bl bar
|
|
; CHECK-PWR9-NEXT: nop
|
|
; CHECK-PWR9-NEXT: std r3, 0(r29)
|
|
; CHECK-PWR9-NEXT: .LBB2_2: # %land.end
|
|
; CHECK-PWR9-NEXT: mr r3, r30
|
|
; CHECK-PWR9-NEXT: addi r1, r1, 64
|
|
; CHECK-PWR9-NEXT: ld r0, 16(r1)
|
|
; CHECK-PWR9-NEXT: ld r30, -16(r1) # 8-byte Folded Reload
|
|
; CHECK-PWR9-NEXT: ld r29, -24(r1) # 8-byte Folded Reload
|
|
; CHECK-PWR9-NEXT: mtlr r0
|
|
; CHECK-PWR9-NEXT: blr
|
|
;
|
|
; CHECK-LABEL: test3:
|
|
; CHECK: # %bb.0: # %entry
|
|
; CHECK-NEXT: mflr r0
|
|
; CHECK-NEXT: stdu r1, -144(r1)
|
|
; CHECK-NEXT: std r0, 160(r1)
|
|
; CHECK-NEXT: .cfi_def_cfa_offset 144
|
|
; CHECK-NEXT: .cfi_offset lr, 16
|
|
; CHECK-NEXT: .cfi_offset r29, -24
|
|
; CHECK-NEXT: .cfi_offset r30, -16
|
|
; CHECK-NEXT: std r30, 128(r1) # 8-byte Folded Spill
|
|
; CHECK-NEXT: ld r30, 0(r3)
|
|
; CHECK-NEXT: std r29, 120(r1) # 8-byte Folded Spill
|
|
; CHECK-NEXT: cmpldi r30, 0
|
|
; CHECK-NEXT: beq cr0, .LBB2_2
|
|
; CHECK-NEXT: # %bb.1: # %land.rhs
|
|
; CHECK-NEXT: mr r29, r3
|
|
; CHECK-NEXT: mr r3, r30
|
|
; CHECK-NEXT: bl bar
|
|
; CHECK-NEXT: nop
|
|
; CHECK-NEXT: std r3, 0(r29)
|
|
; CHECK-NEXT: .LBB2_2: # %land.end
|
|
; CHECK-NEXT: mr r3, r30
|
|
; CHECK-NEXT: ld r30, 128(r1) # 8-byte Folded Reload
|
|
; CHECK-NEXT: ld r29, 120(r1) # 8-byte Folded Reload
|
|
; CHECK-NEXT: addi r1, r1, 144
|
|
; CHECK-NEXT: ld r0, 16(r1)
|
|
; CHECK-NEXT: mtlr r0
|
|
; CHECK-NEXT: blr
|
|
entry:
|
|
%0 = load ptr, ptr %p1, align 8, !tbaa !6
|
|
%tobool = icmp eq ptr %0, null
|
|
br i1 %tobool, label %land.end, label %land.rhs
|
|
|
|
land.rhs: ; preds = %entry
|
|
%call = tail call ptr @bar(ptr nonnull %0, i8 zeroext %p2)
|
|
store ptr %call, ptr %p1, align 8, !tbaa !6
|
|
br label %land.end
|
|
|
|
land.end: ; preds = %entry, %land.rhs
|
|
ret ptr %0
|
|
}
|
|
|
|
declare ptr @bar(ptr, i8 zeroext) local_unnamed_addr
|
|
|
|
|
|
!llvm.module.flags = !{!0}
|
|
!llvm.ident = !{!1}
|
|
|
|
!0 = !{i32 1, !"wchar_size", i32 4}
|
|
!1 = !{!"clang version 10.0.0 (trunk 367381) (llvm/trunk 367388)"}
|
|
!2 = !{!3, !3, i64 0}
|
|
!3 = !{!"int", !4, i64 0}
|
|
!4 = !{!"omnipotent char", !5, i64 0}
|
|
!5 = !{!"Simple C/C++ TBAA"}
|
|
!6 = !{!7, !7, i64 0}
|
|
!7 = !{!"any pointer", !4, i64 0}
|