[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:
Michael Maitland 2025-04-14 09:58:46 -04:00 committed by GitHub
parent efe9cb0f79
commit 74e8f29f31
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
20 changed files with 149 additions and 137 deletions

View File

@ -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.

View File

@ -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

View 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
...

View File

@ -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
}

View File

@ -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

View File

@ -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: pop r29
; CHECK-NEXT: pop r28
; CHECK-NEXT: pop r8
; CHECK-NEXT: in r28, 61
; CHECK-NEXT: in r29, 62
; 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: ret
%c = extractvalue [17 x i8] %a, 0
%d = sub i8 %c, %b

View File

@ -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

View File

@ -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:

View File

@ -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

View File

@ -143,28 +143,28 @@ 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-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
; SOFT-NEXT: call floatarg
; SOFT: std %o0, [%i4]
; 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, %o3
; SOFT-NEXT: mov %i2, %o4
; SOFT-NEXT: mov %i1, %o5
; SOFT-NEXT: call floatarg
; SOFT: std %o0, [%i4]
; CHECK: restore
define void @call_floatarg(float %f1, double %d2, float %f5, ptr %p) {
%r = call double @floatarg(double %d2, float %f1, double %d2, double %d2,
@ -228,16 +228,16 @@ 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
; CHECK-NEXT: mov %i1, %o3
; CHECK-NEXT: mov %i2, %o4
; CHECK-NEXT: mov %i1, %o5
; CHECK-NEXT: call i64arg
; CHECK: std %o0, [%i3]
; CHECK-NEXT: restore

View File

@ -118,12 +118,10 @@ 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
; SOFT: mov %i2, %o5
; SOFT: mov %i1, %o2
; SOFT: mov %i1, %o3
; SOFT: mov %i2, %o4
; SOFT: mov %i2, %o5
; CHECK: call floatarg
; CHECK-NOT: add %sp
; CHECK: restore
@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -1,12 +1,10 @@
; RUN: llc < %s -mtriple=sparcv9 | FileCheck %s
; CHECK-LABEL: test
; CHECK: srl %i1, 0, %o2
; CHECK-NEXT: mov %i2, %o0
; CHECK-NEXT: call __ashlti3
; CHECK-NEXT: mov %i3, %o1
; CHECK-NEXT: mov %o0, %i0
; CHECK: mov %i3, %o1
; CHECK-NEXT: mov %i2, %o0
; CHECK-NEXT: call __ashlti3
; CHECK-NEXT: srl %i1, 0, %o2
define i128 @test(i128 %a, i128 %b) {
entry:
%tmp = shl i128 %b, %a

View File

@ -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:

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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