1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \ 3; RUN: -mcpu=pwr10 -ppc-asm-full-reg-names < %s | FileCheck %s 4 5; The purpose of this test is to check the call protocols for the situation 6; where the caller has PC Relative disabled, the callee has PC Relative 7; enabled and both functions are in the same file. 8; Note that the callee does not know if it clobbers the TOC because it 9; contains an external call to @externalFunc. 10 11@global = external local_unnamed_addr global i32, align 4 12 13define dso_local signext i32 @callee(i32 signext %a) local_unnamed_addr #0 { 14; CHECK-LABEL: callee: 15; CHECK: .localentry callee, 1 16; CHECK-NEXT: # %bb.0: # %entry 17; CHECK-NEXT: mflr r0 18; CHECK-NEXT: std r30, -16(r1) # 8-byte Folded Spill 19; CHECK-NEXT: std r0, 16(r1) 20; CHECK-NEXT: stdu r1, -48(r1) 21; CHECK-NEXT: mr r30, r3 22; CHECK-NEXT: bl externalFunc@notoc 23; CHECK-NEXT: add r3, r3, r30 24; CHECK-NEXT: extsw r3, r3 25; CHECK-NEXT: addi r1, r1, 48 26; CHECK-NEXT: ld r0, 16(r1) 27; CHECK-NEXT: ld r30, -16(r1) # 8-byte Folded Reload 28; CHECK-NEXT: mtlr r0 29; CHECK-NEXT: blr 30entry: 31 %call = tail call signext i32 @externalFunc(i32 signext %a) #3 32 %add = add nsw i32 %call, %a 33 ret i32 %add 34} 35 36declare signext i32 @externalFunc(i32 signext) local_unnamed_addr #1 37 38define dso_local void @caller(i32 signext %a) local_unnamed_addr #2 { 39; CHECK-LABEL: caller: 40; CHECK: # %bb.0: # %entry 41; CHECK-NEXT: mflr r0 42; CHECK-NEXT: std r30, -16(r1) # 8-byte Folded Spill 43; CHECK-NEXT: std r0, 16(r1) 44; CHECK-NEXT: stdu r1, -48(r1) 45; CHECK-NEXT: addis r4, r2, .LC0@toc@ha 46; CHECK-NEXT: ld r30, .LC0@toc@l(r4) 47; CHECK-NEXT: lwz r4, 0(r30) 48; CHECK-NEXT: add r3, r4, r3 49; CHECK-NEXT: extsw r3, r3 50; CHECK-NEXT: bl callee 51; CHECK-NEXT: nop 52; CHECK-NEXT: mullw r3, r3, r3 53; CHECK-NEXT: stw r3, 0(r30) 54; CHECK-NEXT: addi r1, r1, 48 55; CHECK-NEXT: ld r0, 16(r1) 56; CHECK-NEXT: ld r30, -16(r1) # 8-byte Folded Reload 57; CHECK-NEXT: mtlr r0 58; CHECK-NEXT: blr 59entry: 60 %0 = load i32, i32* @global, align 4 61 %add = add nsw i32 %0, %a 62 %call = tail call signext i32 @callee(i32 signext %add) 63 %mul = mul nsw i32 %call, %call 64 store i32 %mul, i32* @global, align 4 65 ret void 66} 67 68define dso_local signext i32 @tail_caller(i32 signext %a) local_unnamed_addr #2 { 69; CHECK-LABEL: tail_caller: 70; CHECK: # %bb.0: # %entry 71; CHECK-NEXT: mflr r0 72; CHECK-NEXT: std r0, 16(r1) 73; CHECK-NEXT: stdu r1, -32(r1) 74; CHECK-NEXT: addis r4, r2, .LC0@toc@ha 75; CHECK-NEXT: ld r4, .LC0@toc@l(r4) 76; CHECK-NEXT: lwz r4, 0(r4) 77; CHECK-NEXT: add r3, r4, r3 78; CHECK-NEXT: extsw r3, r3 79; CHECK-NEXT: bl callee 80; CHECK-NEXT: nop 81; CHECK-NEXT: addi r1, r1, 32 82; CHECK-NEXT: ld r0, 16(r1) 83; CHECK-NEXT: mtlr r0 84; CHECK-NEXT: blr 85entry: 86 %0 = load i32, i32* @global, align 4 87 %add = add nsw i32 %0, %a 88 %call = tail call signext i32 @callee(i32 signext %add) 89 ret i32 %call 90} 91 92 93; Left the target features in this test because it is important that caller has 94; -pcrelative-memops while callee has +pcrelative-memops 95attributes #0 = { nounwind "target-features"="+altivec,+bpermd,+crypto,+direct-move,+extdiv,+pcrelative-memops,+power8-vector,+power9-vector,+vsx,-htm,-qpx,-spe" } 96attributes #1 = { "target-features"="+altivec,+bpermd,+crypto,+direct-move,+extdiv,+pcrelative-memops,+power8-vector,+power9-vector,+vsx,-htm,-qpx,-spe" } 97attributes #2 = { nounwind "target-features"="+altivec,+bpermd,+crypto,+direct-move,+extdiv,+power8-vector,+power9-vector,+vsx,-htm,-pcrelative-memops,-qpx,-spe" } 98attributes #3 = { nounwind } 99