[RegAlloc] Sort CopyHint by IsCSR (#131046)
`weightCalcHelper` is responsible for adding hints to MRI. Prior to this PR, we fell back on register ID as the last tie breaker for sorting hints. However, there is an opportunity to add an additional sorting characteristic: whether or not a register is a callee-saved-register. I thought of this idea because I saw that `AllocationOrder::create` calls `RegisterClassInfo::getOrder`, which returns a list of registers such that the registers which alias callee-saved-registers come last. From this, I conclude that the register allocator prefers an order such that callee-saved-registers are allocated after non-callee-saved-registers to avoid having to spill the CSR. This sorting characteristic occurs only as a tie breaker to the Weight calculation. This is a good idea since the weight calculation is pretty complex and I'm sure it is a pretty stable metric. I think its pretty reasonable to agree that whether a register is callee-saved or not is a better tie breaker than register ID. I think this is evident by the test diff, since the changes all seem to have no impact or improve the register allocation.
This commit is contained in:
parent
efe9cb0f79
commit
74e8f29f31
@ -210,13 +210,18 @@ float VirtRegAuxInfo::weightCalcHelper(LiveInterval &LI, SlotIndex *Start,
|
||||
struct CopyHint {
|
||||
Register Reg;
|
||||
float Weight;
|
||||
CopyHint(Register R, float W) : Reg(R), Weight(W) {}
|
||||
bool IsCSR;
|
||||
CopyHint(Register R, float W, bool IsCSR)
|
||||
: Reg(R), Weight(W), IsCSR(IsCSR) {}
|
||||
bool operator<(const CopyHint &Rhs) const {
|
||||
// Always prefer any physreg hint.
|
||||
if (Reg.isPhysical() != Rhs.Reg.isPhysical())
|
||||
return Reg.isPhysical();
|
||||
if (Weight != Rhs.Weight)
|
||||
return (Weight > Rhs.Weight);
|
||||
// Prefer non-CSR to CSR.
|
||||
if (Reg.isPhysical() && IsCSR != Rhs.IsCSR)
|
||||
return !IsCSR;
|
||||
return Reg.id() < Rhs.Reg.id(); // Tie-breaker.
|
||||
}
|
||||
};
|
||||
@ -299,10 +304,12 @@ float VirtRegAuxInfo::weightCalcHelper(LiveInterval &LI, SlotIndex *Start,
|
||||
SmallVector<CopyHint, 8> RegHints;
|
||||
for (const auto &[Reg, Weight] : Hint) {
|
||||
if (Reg != SkipReg)
|
||||
RegHints.emplace_back(Reg, Weight);
|
||||
RegHints.emplace_back(
|
||||
Reg, Weight,
|
||||
Reg.isPhysical() ? TRI.isCalleeSavedPhysReg(Reg, MF) : false);
|
||||
}
|
||||
sort(RegHints);
|
||||
for (const auto &[Reg, Weight] : RegHints)
|
||||
for (const auto &[Reg, _, __] : RegHints)
|
||||
MRI.addRegAllocationHint(LI.reg(), Reg);
|
||||
|
||||
// Weakly boost the spill weight of hinted registers.
|
||||
|
@ -15,10 +15,8 @@ entry:
|
||||
; CHECK-NEXT: mov x0, x30
|
||||
; CHECK-NEXT: ldr x30, [sp], #16
|
||||
; CHECK-NEXT: ret
|
||||
; CHECKV83: str x30, [sp, #-16]!
|
||||
; CHECKV83-NEXT: xpaci x30
|
||||
; CHECKV83-NEXT: mov x0, x30
|
||||
; CHECKV83-NEXT: ldr x30, [sp], #16
|
||||
; CHECKV83: mov x0, x30
|
||||
; CHECKV83-NEXT: xpaci x0
|
||||
; CHECKV83-NEXT: ret
|
||||
%0 = tail call ptr @llvm.returnaddress(i32 0)
|
||||
ret ptr %0
|
||||
@ -35,10 +33,8 @@ entry:
|
||||
; CHECK-NEXT: hint #29
|
||||
; CHECK-NEXT: ret
|
||||
; CHECKV83: paciasp
|
||||
; CHECKV83-NEXT: str x30, [sp, #-16]!
|
||||
; CHECKV83-NEXT: xpaci x30
|
||||
; CHECKV83-NEXT: mov x0, x30
|
||||
; CHECKV83-NEXT: ldr x30, [sp], #16
|
||||
; CHECKV83-NEXT: xpaci x0
|
||||
; CHECKV83-NEXT: retaa
|
||||
%0 = tail call ptr @llvm.returnaddress(i32 0)
|
||||
ret ptr %0
|
||||
|
22
llvm/test/CodeGen/AArch64/csr-copy-hint.mir
Normal file
22
llvm/test/CodeGen/AArch64/csr-copy-hint.mir
Normal file
@ -0,0 +1,22 @@
|
||||
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5
|
||||
# RUN: llc -mtriple=arm64-eabi -mattr=v8.3a -stop-after=virtregmap -o - %s | FileCheck %s
|
||||
|
||||
---
|
||||
name: ra0
|
||||
tracksRegLiveness: true
|
||||
isSSA: true
|
||||
body: |
|
||||
bb.0.entry:
|
||||
liveins: $lr
|
||||
|
||||
; CHECK-LABEL: name: ra0
|
||||
; CHECK: liveins: $lr
|
||||
; CHECK-NEXT: {{ $}}
|
||||
; CHECK-NEXT: $x0 = ORRXrs $xzr, $lr, 0
|
||||
; CHECK-NEXT: renamable $x0 = XPACI killed renamable $x0
|
||||
; CHECK-NEXT: RET undef $lr, implicit killed $x0
|
||||
%0:gpr64 = COPY killed $lr
|
||||
%1:gpr64 = XPACI killed %0
|
||||
$x0 = COPY killed %1
|
||||
RET_ReallyLR implicit killed $x0
|
||||
...
|
@ -112,12 +112,9 @@ define void @test_noframe() #0 {
|
||||
define ptr @test_returnaddress_0() #0 {
|
||||
; CHECK-LABEL: test_returnaddress_0:
|
||||
; CHECK: %bb.0:
|
||||
; CHECK-NEXT: pacibsp
|
||||
; CHECK-NEXT: str x30, [sp, #-16]!
|
||||
; CHECK-NEXT: xpaci x30
|
||||
; CHECK-NEXT: mov x0, x30
|
||||
; CHECK-NEXT: ldr x30, [sp], #16
|
||||
; CHECK-NEXT: retab
|
||||
; CHECK-NEXT: xpaci x0
|
||||
; CHECK-NEXT: ret
|
||||
%r = call ptr @llvm.returnaddress(i32 0)
|
||||
ret ptr %r
|
||||
}
|
||||
|
@ -132,17 +132,15 @@ define i8 @foo2([6 x i8] %0, [6 x i8] %1, [6 x i8] %2) {
|
||||
define i8 @foo3([9 x i8] %0, [9 x i8] %1) {
|
||||
; CHECK-LABEL: foo3:
|
||||
; CHECK: ; %bb.0:
|
||||
; CHECK-NEXT: push r16
|
||||
; CHECK-NEXT: push r28
|
||||
; CHECK-NEXT: push r29
|
||||
; CHECK-NEXT: in r28, 61
|
||||
; CHECK-NEXT: in r29, 62
|
||||
; CHECK-NEXT: ldd r24, Y+6
|
||||
; CHECK-NEXT: sub r16, r24
|
||||
; CHECK-NEXT: mov r24, r16
|
||||
; CHECK-NEXT: ldd r25, Y+5
|
||||
; CHECK-NEXT: sub r24, r25
|
||||
; CHECK-NEXT: pop r29
|
||||
; CHECK-NEXT: pop r28
|
||||
; CHECK-NEXT: pop r16
|
||||
; CHECK-NEXT: ret
|
||||
%3 = extractvalue [9 x i8] %0, 0
|
||||
%4 = extractvalue [9 x i8] %1, 0
|
||||
|
@ -74,17 +74,15 @@ define i8 @foo1([19 x i8] %a, i8 %b) {
|
||||
define i8 @foo2([17 x i8] %a, i8 %b) {
|
||||
; CHECK-LABEL: foo2:
|
||||
; CHECK: ; %bb.0:
|
||||
; CHECK-NEXT: push r8
|
||||
; CHECK-NEXT: push r28
|
||||
; CHECK-NEXT: push r29
|
||||
; CHECK-NEXT: in r28, 61
|
||||
; CHECK-NEXT: in r29, 62
|
||||
; CHECK-NEXT: ldd r24, Y+6
|
||||
; CHECK-NEXT: sub r8, r24
|
||||
; CHECK-NEXT: mov r24, r8
|
||||
; CHECK-NEXT: ldd r25, Y+5
|
||||
; CHECK-NEXT: sub r24, r25
|
||||
; CHECK-NEXT: pop r29
|
||||
; CHECK-NEXT: pop r28
|
||||
; CHECK-NEXT: pop r8
|
||||
; CHECK-NEXT: ret
|
||||
%c = extractvalue [17 x i8] %a, 0
|
||||
%d = sub i8 %c, %b
|
||||
|
@ -64,16 +64,16 @@ define void @dynalloca2(i16 %x) {
|
||||
; CHECK-NEXT: out 63, r0
|
||||
; CHECK-NEXT: out 61, {{.*}}
|
||||
; Store values on the stack
|
||||
; CHECK: ldi r16, 0
|
||||
; CHECK: ldi r17, 0
|
||||
; CHECK: std Z+8, r17
|
||||
; CHECK: std Z+7, r16
|
||||
; CHECK: std Z+6, r17
|
||||
; CHECK: std Z+5, r16
|
||||
; CHECK: std Z+4, r17
|
||||
; CHECK: std Z+3, r16
|
||||
; CHECK: std Z+2, r17
|
||||
; CHECK: std Z+1, r16
|
||||
; CHECK: ldi r20, 0
|
||||
; CHECK: ldi r21, 0
|
||||
; CHECK: std Z+8, r21
|
||||
; CHECK: std Z+7, r20
|
||||
; CHECK: std Z+6, r21
|
||||
; CHECK: std Z+5, r20
|
||||
; CHECK: std Z+4, r21
|
||||
; CHECK: std Z+3, r20
|
||||
; CHECK: std Z+2, r21
|
||||
; CHECK: std Z+1, r20
|
||||
; CHECK: call
|
||||
; Call frame restore
|
||||
; CHECK-NEXT: in r30, 61
|
||||
|
@ -126,8 +126,8 @@ define i32 @return32_arg(i32 %x) {
|
||||
define i32 @return32_arg2(i32 %x, i32 %y, i32 %z) {
|
||||
; AVR-LABEL: return32_arg2:
|
||||
; AVR: ; %bb.0:
|
||||
; AVR-NEXT: movw r22, r14
|
||||
; AVR-NEXT: movw r24, r16
|
||||
; AVR-NEXT: movw r22, r14
|
||||
; AVR-NEXT: ret
|
||||
;
|
||||
; TINY-LABEL: return32_arg2:
|
||||
|
@ -60,7 +60,7 @@ entry:
|
||||
;CHECK: sethi
|
||||
;CHECK: !NO_APP
|
||||
;CHECK-NEXT: ble
|
||||
;CHECK-NEXT: mov
|
||||
;CHECK-NEXT: nop
|
||||
tail call void asm sideeffect "sethi 0, %g0", ""() nounwind
|
||||
%0 = icmp slt i32 %a, 0
|
||||
br i1 %0, label %bb, label %bb1
|
||||
|
@ -143,23 +143,23 @@ define double @floatarg(double %a0, ; %i0,%i1
|
||||
; CHECK-LABEL: call_floatarg:
|
||||
; HARD: save %sp, -112, %sp
|
||||
; HARD: mov %i2, %o1
|
||||
; HARD-NEXT: mov %i0, %o2
|
||||
; HARD-NEXT: mov %i1, %o0
|
||||
; HARD-NEXT: st %i0, [%sp+104]
|
||||
; HARD-NEXT: std %o0, [%sp+96]
|
||||
; HARD-NEXT: st %o1, [%sp+92]
|
||||
; HARD-NEXT: mov %i0, %o2
|
||||
; HARD-NEXT: mov %i1, %o3
|
||||
; HARD-NEXT: mov %o1, %o4
|
||||
; HARD-NEXT: mov %i1, %o5
|
||||
; HARD-NEXT: call floatarg
|
||||
; HARD: std %f0, [%i4]
|
||||
; SOFT: st %i0, [%sp+104]
|
||||
; SOFT: mov %i2, %o1
|
||||
; SOFT-NEXT: mov %i1, %o0
|
||||
; SOFT-NEXT: mov %i0, %o2
|
||||
; SOFT-NEXT: st %i0, [%sp+104]
|
||||
; SOFT-NEXT: st %i2, [%sp+100]
|
||||
; SOFT-NEXT: st %i1, [%sp+96]
|
||||
; SOFT-NEXT: st %i2, [%sp+92]
|
||||
; SOFT-NEXT: mov %i1, %o0
|
||||
; SOFT-NEXT: mov %i2, %o1
|
||||
; SOFT-NEXT: mov %i0, %o2
|
||||
; SOFT-NEXT: mov %i1, %o3
|
||||
; SOFT-NEXT: mov %i2, %o4
|
||||
; SOFT-NEXT: mov %i1, %o5
|
||||
@ -228,13 +228,13 @@ define i64 @i64arg(i64 %a0, ; %i0,%i1
|
||||
|
||||
; CHECK-LABEL: call_i64arg:
|
||||
; CHECK: save %sp, -112, %sp
|
||||
; CHECK: st %i0, [%sp+104]
|
||||
; CHECK: mov %i2, %o1
|
||||
; CHECK-NEXT: mov %i1, %o0
|
||||
; CHECK-NEXT: mov %i0, %o2
|
||||
; CHECK-NEXT: st %i0, [%sp+104]
|
||||
; CHECK-NEXT: st %i2, [%sp+100]
|
||||
; CHECK-NEXT: st %i1, [%sp+96]
|
||||
; CHECK-NEXT: st %i2, [%sp+92]
|
||||
; CHECK-NEXT: mov %i1, %o0
|
||||
; CHECK-NEXT: mov %i2, %o1
|
||||
; CHECK-NEXT: mov %i0, %o2
|
||||
; CHECK-NEXT: mov %i1, %o3
|
||||
; CHECK-NEXT: mov %i2, %o4
|
||||
; CHECK-NEXT: mov %i1, %o5
|
||||
|
@ -118,8 +118,6 @@ define double @floatarg(float %a0, ; %f1
|
||||
; SOFT: stx %i2, [%sp+2239]
|
||||
; SOFT: stx %i2, [%sp+2231]
|
||||
; SOFT: stx %i2, [%sp+2223]
|
||||
; SOFT: mov %i2, %o0
|
||||
; SOFT: mov %i1, %o1
|
||||
; SOFT: mov %i1, %o2
|
||||
; SOFT: mov %i1, %o3
|
||||
; SOFT: mov %i2, %o4
|
||||
@ -174,11 +172,9 @@ define void @mixedarg(i8 %a0, ; %i0
|
||||
|
||||
; CHECK-LABEL: call_mixedarg:
|
||||
; CHECK: stx %i2, [%sp+2247]
|
||||
; SOFT: stx %i1, [%sp+2239]
|
||||
; CHECK: stx %i0, [%sp+2223]
|
||||
; HARD: fmovd %f2, %f6
|
||||
; HARD: fmovd %f2, %f16
|
||||
; SOFT: mov %i1, %o3
|
||||
; CHECK: call mixedarg
|
||||
; CHECK-NOT: add %sp
|
||||
; CHECK: restore
|
||||
@ -262,8 +258,8 @@ define i32 @inreg_if(float inreg %a0, ; %f0
|
||||
}
|
||||
|
||||
; CHECK-LABEL: call_inreg_if:
|
||||
; HARD: fmovs %f3, %f0
|
||||
; HARD: mov %i2, %o0
|
||||
; HARD: fmovs %f3, %f0
|
||||
; SOFT: srl %i2, 0, %i0
|
||||
; SOFT: sllx %i1, 32, %i1
|
||||
; SOFT: or %i1, %i0, %o0
|
||||
|
@ -92,9 +92,9 @@ define i32 @call_ret_i32_arr(i32 %0) {
|
||||
; SPARC-NEXT: .cfi_def_cfa_register %fp
|
||||
; SPARC-NEXT: .cfi_window_save
|
||||
; SPARC-NEXT: .cfi_register %o7, %i7
|
||||
; SPARC-NEXT: add %fp, -64, %i1
|
||||
; SPARC-NEXT: st %i1, [%sp+64]
|
||||
; SPARC-NEXT: mov %i0, %o0
|
||||
; SPARC-NEXT: add %fp, -64, %i0
|
||||
; SPARC-NEXT: st %i0, [%sp+64]
|
||||
; SPARC-NEXT: call ret_i32_arr
|
||||
; SPARC-NEXT: nop
|
||||
; SPARC-NEXT: unimp 64
|
||||
@ -110,8 +110,8 @@ define i32 @call_ret_i32_arr(i32 %0) {
|
||||
; SPARC64-NEXT: .cfi_def_cfa_register %fp
|
||||
; SPARC64-NEXT: .cfi_window_save
|
||||
; SPARC64-NEXT: .cfi_register %o7, %i7
|
||||
; SPARC64-NEXT: add %fp, 1983, %o0
|
||||
; SPARC64-NEXT: mov %i0, %o1
|
||||
; SPARC64-NEXT: add %fp, 1983, %o0
|
||||
; SPARC64-NEXT: call ret_i32_arr
|
||||
; SPARC64-NEXT: nop
|
||||
; SPARC64-NEXT: ld [%fp+2043], %i0
|
||||
@ -220,10 +220,10 @@ define i64 @call_ret_i64_arr(i64 %0) {
|
||||
; SPARC-NEXT: .cfi_def_cfa_register %fp
|
||||
; SPARC-NEXT: .cfi_window_save
|
||||
; SPARC-NEXT: .cfi_register %o7, %i7
|
||||
; SPARC-NEXT: add %fp, -128, %i2
|
||||
; SPARC-NEXT: st %i2, [%sp+64]
|
||||
; SPARC-NEXT: mov %i0, %o0
|
||||
; SPARC-NEXT: mov %i1, %o1
|
||||
; SPARC-NEXT: mov %i0, %o0
|
||||
; SPARC-NEXT: add %fp, -128, %i0
|
||||
; SPARC-NEXT: st %i0, [%sp+64]
|
||||
; SPARC-NEXT: call ret_i64_arr
|
||||
; SPARC-NEXT: nop
|
||||
; SPARC-NEXT: unimp 128
|
||||
@ -239,8 +239,8 @@ define i64 @call_ret_i64_arr(i64 %0) {
|
||||
; SPARC64-NEXT: .cfi_def_cfa_register %fp
|
||||
; SPARC64-NEXT: .cfi_window_save
|
||||
; SPARC64-NEXT: .cfi_register %o7, %i7
|
||||
; SPARC64-NEXT: add %fp, 1919, %o0
|
||||
; SPARC64-NEXT: mov %i0, %o1
|
||||
; SPARC64-NEXT: add %fp, 1919, %o0
|
||||
; SPARC64-NEXT: call ret_i64_arr
|
||||
; SPARC64-NEXT: nop
|
||||
; SPARC64-NEXT: ldx [%fp+2039], %i0
|
||||
|
@ -10,9 +10,9 @@ define float @fmuladd_intrinsic_f32(float %a, float %b, float %c) #0 {
|
||||
; SOFT-FLOAT-32-NEXT: .cfi_def_cfa_register %fp
|
||||
; SOFT-FLOAT-32-NEXT: .cfi_window_save
|
||||
; SOFT-FLOAT-32-NEXT: .cfi_register %o7, %i7
|
||||
; SOFT-FLOAT-32-NEXT: mov %i0, %o0
|
||||
; SOFT-FLOAT-32-NEXT: call __mulsf3
|
||||
; SOFT-FLOAT-32-NEXT: mov %i1, %o1
|
||||
; SOFT-FLOAT-32-NEXT: call __mulsf3
|
||||
; SOFT-FLOAT-32-NEXT: mov %i0, %o0
|
||||
; SOFT-FLOAT-32-NEXT: call __addsf3
|
||||
; SOFT-FLOAT-32-NEXT: mov %i2, %o1
|
||||
; SOFT-FLOAT-32-NEXT: ret
|
||||
@ -44,11 +44,11 @@ define double @fmuladd_intrinsic_f64(double %a, double %b, double %c) #0 {
|
||||
; SOFT-FLOAT-32-NEXT: .cfi_def_cfa_register %fp
|
||||
; SOFT-FLOAT-32-NEXT: .cfi_window_save
|
||||
; SOFT-FLOAT-32-NEXT: .cfi_register %o7, %i7
|
||||
; SOFT-FLOAT-32-NEXT: mov %i0, %o0
|
||||
; SOFT-FLOAT-32-NEXT: mov %i1, %o1
|
||||
; SOFT-FLOAT-32-NEXT: mov %i2, %o2
|
||||
; SOFT-FLOAT-32-NEXT: call __muldf3
|
||||
; SOFT-FLOAT-32-NEXT: mov %i3, %o3
|
||||
; SOFT-FLOAT-32-NEXT: mov %i2, %o2
|
||||
; SOFT-FLOAT-32-NEXT: mov %i1, %o1
|
||||
; SOFT-FLOAT-32-NEXT: call __muldf3
|
||||
; SOFT-FLOAT-32-NEXT: mov %i0, %o0
|
||||
; SOFT-FLOAT-32-NEXT: mov %i4, %o2
|
||||
; SOFT-FLOAT-32-NEXT: call __adddf3
|
||||
; SOFT-FLOAT-32-NEXT: mov %i5, %o3
|
||||
@ -63,9 +63,9 @@ define double @fmuladd_intrinsic_f64(double %a, double %b, double %c) #0 {
|
||||
; SOFT-FLOAT-64-NEXT: .cfi_def_cfa_register %fp
|
||||
; SOFT-FLOAT-64-NEXT: .cfi_window_save
|
||||
; SOFT-FLOAT-64-NEXT: .cfi_register %o7, %i7
|
||||
; SOFT-FLOAT-64-NEXT: mov %i0, %o0
|
||||
; SOFT-FLOAT-64-NEXT: call __muldf3
|
||||
; SOFT-FLOAT-64-NEXT: mov %i1, %o1
|
||||
; SOFT-FLOAT-64-NEXT: call __muldf3
|
||||
; SOFT-FLOAT-64-NEXT: mov %i0, %o0
|
||||
; SOFT-FLOAT-64-NEXT: call __adddf3
|
||||
; SOFT-FLOAT-64-NEXT: mov %i2, %o1
|
||||
; SOFT-FLOAT-64-NEXT: ret
|
||||
@ -82,9 +82,9 @@ define float @fmuladd_contract_f32(float %a, float %b, float %c) #0 {
|
||||
; SOFT-FLOAT-32-NEXT: .cfi_def_cfa_register %fp
|
||||
; SOFT-FLOAT-32-NEXT: .cfi_window_save
|
||||
; SOFT-FLOAT-32-NEXT: .cfi_register %o7, %i7
|
||||
; SOFT-FLOAT-32-NEXT: mov %i0, %o0
|
||||
; SOFT-FLOAT-32-NEXT: call __mulsf3
|
||||
; SOFT-FLOAT-32-NEXT: mov %i1, %o1
|
||||
; SOFT-FLOAT-32-NEXT: call __mulsf3
|
||||
; SOFT-FLOAT-32-NEXT: mov %i0, %o0
|
||||
; SOFT-FLOAT-32-NEXT: call __addsf3
|
||||
; SOFT-FLOAT-32-NEXT: mov %i2, %o1
|
||||
; SOFT-FLOAT-32-NEXT: ret
|
||||
@ -117,11 +117,11 @@ define double @fmuladd_contract_f64(double %a, double %b, double %c) #0 {
|
||||
; SOFT-FLOAT-32-NEXT: .cfi_def_cfa_register %fp
|
||||
; SOFT-FLOAT-32-NEXT: .cfi_window_save
|
||||
; SOFT-FLOAT-32-NEXT: .cfi_register %o7, %i7
|
||||
; SOFT-FLOAT-32-NEXT: mov %i0, %o0
|
||||
; SOFT-FLOAT-32-NEXT: mov %i1, %o1
|
||||
; SOFT-FLOAT-32-NEXT: mov %i2, %o2
|
||||
; SOFT-FLOAT-32-NEXT: call __muldf3
|
||||
; SOFT-FLOAT-32-NEXT: mov %i3, %o3
|
||||
; SOFT-FLOAT-32-NEXT: mov %i2, %o2
|
||||
; SOFT-FLOAT-32-NEXT: mov %i1, %o1
|
||||
; SOFT-FLOAT-32-NEXT: call __muldf3
|
||||
; SOFT-FLOAT-32-NEXT: mov %i0, %o0
|
||||
; SOFT-FLOAT-32-NEXT: mov %i4, %o2
|
||||
; SOFT-FLOAT-32-NEXT: call __adddf3
|
||||
; SOFT-FLOAT-32-NEXT: mov %i5, %o3
|
||||
@ -136,9 +136,9 @@ define double @fmuladd_contract_f64(double %a, double %b, double %c) #0 {
|
||||
; SOFT-FLOAT-64-NEXT: .cfi_def_cfa_register %fp
|
||||
; SOFT-FLOAT-64-NEXT: .cfi_window_save
|
||||
; SOFT-FLOAT-64-NEXT: .cfi_register %o7, %i7
|
||||
; SOFT-FLOAT-64-NEXT: mov %i0, %o0
|
||||
; SOFT-FLOAT-64-NEXT: call __muldf3
|
||||
; SOFT-FLOAT-64-NEXT: mov %i1, %o1
|
||||
; SOFT-FLOAT-64-NEXT: call __muldf3
|
||||
; SOFT-FLOAT-64-NEXT: mov %i0, %o0
|
||||
; SOFT-FLOAT-64-NEXT: call __adddf3
|
||||
; SOFT-FLOAT-64-NEXT: mov %i2, %o1
|
||||
; SOFT-FLOAT-64-NEXT: ret
|
||||
@ -162,9 +162,9 @@ define <4 x float> @fmuladd_contract_v4f32(<4 x float> %a, <4 x float> %b, <4 x
|
||||
; SOFT-FLOAT-32-NEXT: ld [%fp+112], %l3
|
||||
; SOFT-FLOAT-32-NEXT: ld [%fp+96], %l4
|
||||
; SOFT-FLOAT-32-NEXT: ld [%fp+92], %l5
|
||||
; SOFT-FLOAT-32-NEXT: mov %i0, %o0
|
||||
; SOFT-FLOAT-32-NEXT: call __mulsf3
|
||||
; SOFT-FLOAT-32-NEXT: mov %i4, %o1
|
||||
; SOFT-FLOAT-32-NEXT: call __mulsf3
|
||||
; SOFT-FLOAT-32-NEXT: mov %i0, %o0
|
||||
; SOFT-FLOAT-32-NEXT: mov %o0, %i0
|
||||
; SOFT-FLOAT-32-NEXT: mov %i1, %o0
|
||||
; SOFT-FLOAT-32-NEXT: call __mulsf3
|
||||
|
@ -86,12 +86,12 @@ entry:
|
||||
; CHECK-LABEL: leaf_proc_give_up
|
||||
; CHECK: save %sp, -96, %sp
|
||||
; CHECK: ld [%fp+92], %o5
|
||||
; CHECK: mov %i0, %g1
|
||||
; CHECK: mov %i1, %o0
|
||||
; CHECK: mov %i2, %o1
|
||||
; CHECK: mov %i3, %o2
|
||||
; CHECK: mov %i4, %o3
|
||||
; CHECK: mov %i5, %o4
|
||||
; CHECK: mov %i4, %o3
|
||||
; CHECK: mov %i3, %o2
|
||||
; CHECK: mov %i2, %o1
|
||||
; CHECK: mov %i1, %o0
|
||||
; CHECK: mov %i0, %g1
|
||||
; CHECK: ret
|
||||
; CHECK-NEXT: restore %g0, %o0, %o0
|
||||
|
||||
|
@ -1,12 +1,10 @@
|
||||
; RUN: llc < %s -mtriple=sparcv9 | FileCheck %s
|
||||
|
||||
; CHECK-LABEL: test
|
||||
; CHECK: srl %i1, 0, %o2
|
||||
; CHECK: mov %i3, %o1
|
||||
; CHECK-NEXT: mov %i2, %o0
|
||||
; CHECK-NEXT: call __ashlti3
|
||||
; CHECK-NEXT: mov %i3, %o1
|
||||
; CHECK-NEXT: mov %o0, %i0
|
||||
|
||||
; CHECK-NEXT: srl %i1, 0, %o2
|
||||
define i128 @test(i128 %a, i128 %b) {
|
||||
entry:
|
||||
%tmp = shl i128 %b, %a
|
||||
|
@ -253,13 +253,13 @@ define void @ret_large_struct(ptr noalias sret(%struct.big) %agg.result) #0 {
|
||||
; V9-LABEL: ret_large_struct:
|
||||
; V9: ! %bb.0: ! %entry
|
||||
; V9-NEXT: save %sp, -176, %sp
|
||||
; V9-NEXT: sethi %h44(bigstruct), %i1
|
||||
; V9-NEXT: add %i1, %m44(bigstruct), %i1
|
||||
; V9-NEXT: sllx %i1, 12, %i1
|
||||
; V9-NEXT: add %i1, %l44(bigstruct), %o1
|
||||
; V9-NEXT: mov 400, %o2
|
||||
; V9-NEXT: call memcpy
|
||||
; V9-NEXT: mov %i0, %o0
|
||||
; V9-NEXT: sethi %h44(bigstruct), %i0
|
||||
; V9-NEXT: add %i0, %m44(bigstruct), %i0
|
||||
; V9-NEXT: sllx %i0, 12, %i0
|
||||
; V9-NEXT: add %i0, %l44(bigstruct), %o1
|
||||
; V9-NEXT: call memcpy
|
||||
; V9-NEXT: mov 400, %o2
|
||||
; V9-NEXT: ret
|
||||
; V9-NEXT: restore
|
||||
entry:
|
||||
|
@ -160,6 +160,7 @@ define { i128, i8 } @muloti_test(i128 %l, i128 %r) nounwind {
|
||||
; SPARC64-NEXT: .register %g3, #scratch
|
||||
; SPARC64-NEXT: ! %bb.0: ! %start
|
||||
; SPARC64-NEXT: save %sp, -176, %sp
|
||||
; SPARC64-NEXT: mov %i0, %l1
|
||||
; SPARC64-NEXT: mov %g0, %o0
|
||||
; SPARC64-NEXT: mov %i2, %o1
|
||||
; SPARC64-NEXT: mov %g0, %o2
|
||||
@ -173,30 +174,29 @@ define { i128, i8 } @muloti_test(i128 %l, i128 %r) nounwind {
|
||||
; SPARC64-NEXT: call __multi3
|
||||
; SPARC64-NEXT: mov %i3, %o3
|
||||
; SPARC64-NEXT: mov %o0, %l0
|
||||
; SPARC64-NEXT: add %o1, %i5, %i5
|
||||
; SPARC64-NEXT: add %o1, %i5, %i0
|
||||
; SPARC64-NEXT: mov %g0, %o0
|
||||
; SPARC64-NEXT: mov %i1, %o1
|
||||
; SPARC64-NEXT: mov %g0, %o2
|
||||
; SPARC64-NEXT: call __multi3
|
||||
; SPARC64-NEXT: mov %i3, %o3
|
||||
; SPARC64-NEXT: mov %g0, %i1
|
||||
; SPARC64-NEXT: mov %g0, %i3
|
||||
; SPARC64-NEXT: mov %g0, %i5
|
||||
; SPARC64-NEXT: mov %g0, %g2
|
||||
; SPARC64-NEXT: mov %g0, %g3
|
||||
; SPARC64-NEXT: mov %g0, %g4
|
||||
; SPARC64-NEXT: mov %g0, %g5
|
||||
; SPARC64-NEXT: add %o0, %i5, %i1
|
||||
; SPARC64-NEXT: cmp %i1, %o0
|
||||
; SPARC64-NEXT: movrnz %l0, 1, %g2
|
||||
; SPARC64-NEXT: movrnz %i2, 1, %g3
|
||||
; SPARC64-NEXT: movrnz %i0, 1, %g4
|
||||
; SPARC64-NEXT: movcs %xcc, 1, %i3
|
||||
; SPARC64-NEXT: and %g4, %g3, %i0
|
||||
; SPARC64-NEXT: or %i0, %g2, %i0
|
||||
; SPARC64-NEXT: movrnz %i4, 1, %g5
|
||||
; SPARC64-NEXT: or %i0, %g5, %i0
|
||||
; SPARC64-NEXT: or %i0, %i3, %i0
|
||||
; SPARC64-NEXT: srl %i0, 0, %i2
|
||||
; SPARC64-NEXT: mov %i1, %i0
|
||||
; SPARC64-NEXT: add %o0, %i0, %i0
|
||||
; SPARC64-NEXT: cmp %i0, %o0
|
||||
; SPARC64-NEXT: movrnz %l0, 1, %i3
|
||||
; SPARC64-NEXT: movrnz %i2, 1, %i5
|
||||
; SPARC64-NEXT: movrnz %l1, 1, %g2
|
||||
; SPARC64-NEXT: movcs %xcc, 1, %i1
|
||||
; SPARC64-NEXT: and %g2, %i5, %i2
|
||||
; SPARC64-NEXT: or %i2, %i3, %i2
|
||||
; SPARC64-NEXT: movrnz %i4, 1, %g3
|
||||
; SPARC64-NEXT: or %i2, %g3, %i2
|
||||
; SPARC64-NEXT: or %i2, %i1, %i1
|
||||
; SPARC64-NEXT: srl %i1, 0, %i2
|
||||
; SPARC64-NEXT: ret
|
||||
; SPARC64-NEXT: restore %g0, %o1, %o1
|
||||
start:
|
||||
|
@ -54,9 +54,9 @@ entry:
|
||||
; USE_BASE_32-NEXT: movq [[SAVE_rbx]], %rbx
|
||||
|
||||
; Pass mwaitx 3 arguments in eax, ecx, ebx
|
||||
; NO_BASE_64: movl %r8d, %ebx
|
||||
; NO_BASE_64: movl %ecx, %eax
|
||||
; NO_BASE_64: movl %edx, %ecx
|
||||
; NO_BASE_64: movl %r8d, %ebx
|
||||
; No need to save base pointer.
|
||||
; NO_BASE_64-NOT: movq %rbx
|
||||
; NO_BASE_64: mwaitx
|
||||
@ -65,9 +65,9 @@ entry:
|
||||
; NO_BASE_64-NEXT: {{.+$}}
|
||||
|
||||
; Pass mwaitx 3 arguments in eax, ecx, ebx
|
||||
; NO_BASE_32: movl %r8d, %ebx
|
||||
; NO_BASE_32: movl %ecx, %eax
|
||||
; NO_BASE_32: movl %edx, %ecx
|
||||
; NO_BASE_32: movl %r8d, %ebx
|
||||
; No need to save base pointer.
|
||||
; NO_BASE_32-NOT: movl %ebx
|
||||
; NO_BASE_32: mwaitx
|
||||
@ -123,9 +123,9 @@ if.end:
|
||||
; USE_BASE_32-NEXT: movq [[SAVE_rbx]], %rbx
|
||||
|
||||
; Pass mwaitx 3 arguments in eax, ecx, ebx
|
||||
; NO_BASE_64: movl %edx, %ebx
|
||||
; NO_BASE_64: movl %esi, %eax
|
||||
; NO_BASE_64: movl %edi, %ecx
|
||||
; NO_BASE_64: movl %edx, %ebx
|
||||
; No need to save base pointer.
|
||||
; NO_BASE_64-NOT: movq %rbx
|
||||
; NO_BASE_64: mwaitx
|
||||
@ -133,9 +133,9 @@ if.end:
|
||||
; NO_BASE_64-NEXT: {{.+$}}
|
||||
|
||||
; Pass mwaitx 3 arguments in eax, ecx, ebx
|
||||
; NO_BASE_32: movl %edx, %ebx
|
||||
; NO_BASE_32: movl %esi, %eax
|
||||
; NO_BASE_32: movl %edi, %ecx
|
||||
; NO_BASE_32: movl %edx, %ebx
|
||||
; No need to save base pointer.
|
||||
; NO_BASE_32-NOT: movl %ebx
|
||||
; NO_BASE_32: mwaitx
|
||||
@ -191,9 +191,9 @@ if.end:
|
||||
; USE_BASE_32-NEXT: movq [[SAVE_rbx]], %rbx
|
||||
|
||||
; Pass mwaitx 3 arguments in eax, ecx, ebx
|
||||
; NO_BASE_64: movl %edx, %ebx
|
||||
; NO_BASE_64: movl %esi, %eax
|
||||
; NO_BASE_64: movl %edi, %ecx
|
||||
; NO_BASE_64: movl %edx, %ebx
|
||||
; No need to save base pointer.
|
||||
; NO_BASE_64-NOT: movq %rbx
|
||||
; NO_BASE_64: mwaitx
|
||||
@ -201,9 +201,9 @@ if.end:
|
||||
; NO_BASE_64-NEXT: {{.+$}}
|
||||
|
||||
; Pass mwaitx 3 arguments in eax, ecx, ebx
|
||||
; NO_BASE_32: movl %edx, %ebx
|
||||
; NO_BASE_32: movl %esi, %eax
|
||||
; NO_BASE_32: movl %edi, %ecx
|
||||
; NO_BASE_32: movl %edx, %ebx
|
||||
; No need to save base pointer.
|
||||
; NO_BASE_32-NOT: movl %ebx
|
||||
; NO_BASE_32: mwaitx
|
||||
|
@ -22,8 +22,8 @@
|
||||
|
||||
define void @zap(i64 %a, i64 %b) nounwind {
|
||||
entry:
|
||||
; CHECK: movq %rsi, %rbp
|
||||
; CHECK-NEXT: movq %rdi, %r13
|
||||
; CHECK: movq %rdi, %r13
|
||||
; CHECK-NEXT: movq %rsi, %rbp
|
||||
; CHECK-NEXT: callq addtwo
|
||||
%0 = call ghccc i64 @addtwo(i64 %a, i64 %b)
|
||||
; CHECK: callq foo
|
||||
|
@ -30,9 +30,9 @@ define void @bar(i32 %E, i32 %H, i32 %C) nounwind {
|
||||
; CHECK-LABEL: bar:
|
||||
; CHECK: # %bb.0: # %entry
|
||||
; CHECK-NEXT: pushq %rbx
|
||||
; CHECK-NEXT: movl %edx, %ebx
|
||||
; CHECK-NEXT: movl %esi, %eax
|
||||
; CHECK-NEXT: movl %edi, %ecx
|
||||
; CHECK-NEXT: movl %edx, %ebx
|
||||
; CHECK-NEXT: mwaitx
|
||||
; CHECK-NEXT: popq %rbx
|
||||
; CHECK-NEXT: retq
|
||||
@ -40,8 +40,8 @@ define void @bar(i32 %E, i32 %H, i32 %C) nounwind {
|
||||
; WIN64-LABEL: bar:
|
||||
; WIN64: # %bb.0: # %entry
|
||||
; WIN64-NEXT: pushq %rbx
|
||||
; WIN64-NEXT: movl %r8d, %ebx
|
||||
; WIN64-NEXT: movl %edx, %eax
|
||||
; WIN64-NEXT: movl %r8d, %ebx
|
||||
; WIN64-NEXT: mwaitx
|
||||
; WIN64-NEXT: popq %rbx
|
||||
; WIN64-NEXT: retq
|
||||
|
Loading…
x
Reference in New Issue
Block a user