diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2015-06-09 19:06:30 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2015-06-09 19:06:30 +0000 |
| commit | 85d8b2bbe386bcfe669575d05b61482d7be07e5d (patch) | |
| tree | 1dc5e75ab222a9ead44c699eceafab7a6ca7b310 /test/CodeGen/Mips | |
| parent | 5a5ac124e1efaf208671f01c46edb15f29ed2a0b (diff) | |
Notes
Diffstat (limited to 'test/CodeGen/Mips')
| -rw-r--r-- | test/CodeGen/Mips/Fast-ISel/bswap1.ll | 58 | ||||
| -rw-r--r-- | test/CodeGen/Mips/Fast-ISel/div1.ll | 55 | ||||
| -rw-r--r-- | test/CodeGen/Mips/Fast-ISel/memtest1.ll | 74 | ||||
| -rw-r--r-- | test/CodeGen/Mips/Fast-ISel/mul1.ll | 18 | ||||
| -rw-r--r-- | test/CodeGen/Mips/Fast-ISel/rem1.ll | 56 | ||||
| -rw-r--r-- | test/CodeGen/Mips/Fast-ISel/sel1.ll | 91 | ||||
| -rw-r--r-- | test/CodeGen/Mips/dynamic-stack-realignment.ll | 299 | ||||
| -rw-r--r-- | test/CodeGen/Mips/ehframe-indirect.ll | 26 | ||||
| -rw-r--r-- | test/CodeGen/Mips/emergency-spill-slot-near-fp.ll | 4 |
9 files changed, 672 insertions, 9 deletions
diff --git a/test/CodeGen/Mips/Fast-ISel/bswap1.ll b/test/CodeGen/Mips/Fast-ISel/bswap1.ll new file mode 100644 index 000000000000..8ac9753fa463 --- /dev/null +++ b/test/CodeGen/Mips/Fast-ISel/bswap1.ll @@ -0,0 +1,58 @@ +; RUN: llc < %s -march=mipsel -mcpu=mips32 -O0 -relocation-model=pic \ +; RUN: -fast-isel=true -mips-fast-isel -fast-isel-abort=1 | FileCheck %s \ +; RUN: -check-prefix=ALL -check-prefix=32R1 +; RUN: llc < %s -march=mipsel -mcpu=mips32r2 -O0 -relocation-model=pic \ +; RUN: -fast-isel=true -mips-fast-isel -fast-isel-abort=1 | FileCheck %s \ +; RUN: -check-prefix=ALL -check-prefix=32R2 + +@a = global i16 -21829, align 2 +@b = global i32 -1430532899, align 4 +@a1 = common global i16 0, align 2 +@b1 = common global i32 0, align 4 + +declare i16 @llvm.bswap.i16(i16) +declare i32 @llvm.bswap.i32(i32) + +define void @b16() { + ; ALL-LABEL: b16: + + ; ALL: lw $[[A_ADDR:[0-9]+]], %got(a)($[[GOT_ADDR:[0-9]+]]) + ; ALL: lhu $[[A_VAL:[0-9]+]], 0($[[A_ADDR]]) + + ; 32R1: sll $[[TMP1:[0-9]+]], $[[A_VAL]], 8 + ; 32R1: srl $[[TMP2:[0-9]+]], $[[A_VAL]], 8 + ; 32R1: or $[[TMP3:[0-9]+]], $[[TMP1]], $[[TMP2]] + ; 32R1: andi $[[TMP4:[0-9]+]], $[[TMP3]], 65535 + + ; 32R2: wsbh $[[RESULT:[0-9]+]], $[[A_VAL]] + + %1 = load i16, i16* @a, align 2 + %2 = call i16 @llvm.bswap.i16(i16 %1) + store i16 %2, i16* @a1, align 2 + ret void +} + +define void @b32() { + ; ALL-LABEL: b32: + + ; ALL: lw $[[B_ADDR:[0-9]+]], %got(b)($[[GOT_ADDR:[0-9]+]]) + ; ALL: lw $[[B_VAL:[0-9]+]], 0($[[B_ADDR]]) + + ; 32R1: srl $[[TMP1:[0-9]+]], $[[B_VAL]], 8 + ; 32R1: srl $[[TMP2:[0-9]+]], $[[B_VAL]], 24 + ; 32R1: andi $[[TMP3:[0-9]+]], $[[TMP1]], 65280 + ; 32R1: or $[[TMP4:[0-9]+]], $[[TMP2]], $[[TMP3]] + ; 32R1: andi $[[TMP5:[0-9]+]], $[[B_VAL]], 65280 + ; 32R1: sll $[[TMP6:[0-9]+]], $[[TMP5]], 8 + ; 32R1: sll $[[TMP7:[0-9]+]], $[[B_VAL]], 24 + ; 32R1: or $[[TMP8:[0-9]+]], $[[TMP4]], $[[TMP6]] + ; 32R1: or $[[RESULT:[0-9]+]], $[[TMP7]], $[[TMP8]] + + ; 32R2: wsbh $[[TMP:[0-9]+]], $[[B_VAL]] + ; 32R2: rotr $[[RESULT:[0-9]+]], $[[TMP]], 16 + + %1 = load i32, i32* @b, align 4 + %2 = call i32 @llvm.bswap.i32(i32 %1) + store i32 %2, i32* @b1, align 4 + ret void +} diff --git a/test/CodeGen/Mips/Fast-ISel/div1.ll b/test/CodeGen/Mips/Fast-ISel/div1.ll new file mode 100644 index 000000000000..89e7f211251f --- /dev/null +++ b/test/CodeGen/Mips/Fast-ISel/div1.ll @@ -0,0 +1,55 @@ +; RUN: llc < %s -march=mipsel -mcpu=mips32 -O0 -relocation-model=pic \ +; RUN: -fast-isel=true -mips-fast-isel -fast-isel-abort=1 | FileCheck %s +; RUN: llc < %s -march=mipsel -mcpu=mips32r2 -O0 -relocation-model=pic \ +; RUN: -fast-isel=true -mips-fast-isel -fast-isel-abort=1 | FileCheck %s + +@sj = global i32 200000, align 4 +@sk = global i32 -47, align 4 +@uj = global i32 200000, align 4 +@uk = global i32 43, align 4 +@si = common global i32 0, align 4 +@ui = common global i32 0, align 4 + +define void @divs() { + ; CHECK-LABEL: divs: + + ; CHECK: lui $[[GOT1:[0-9]+]], %hi(_gp_disp) + ; CHECK: addiu $[[GOT2:[0-9]+]], $[[GOT1]], %lo(_gp_disp) + ; CHECK: addu $[[GOT:[0-9]+]], $[[GOT2:[0-9]+]], $25 + ; CHECK-DAG: lw $[[I_ADDR:[0-9]+]], %got(si)($[[GOT]]) + ; CHECK-DAG: lw $[[K_ADDR:[0-9]+]], %got(sk)($[[GOT]]) + ; CHECK-DAG: lw $[[J_ADDR:[0-9]+]], %got(sj)($[[GOT]]) + ; CHECK-DAG: lw $[[J:[0-9]+]], 0($[[J_ADDR]]) + ; CHECK-DAG: lw $[[K:[0-9]+]], 0($[[K_ADDR]]) + ; CHECK-DAG: div $zero, $[[J]], $[[K]] + ; CHECK_DAG: teq $[[K]], $zero, 7 + ; CHECK-DAG: mflo $[[RESULT:[0-9]+]] + ; CHECK: sw $[[RESULT]], 0($[[I_ADDR]]) + %1 = load i32, i32* @sj, align 4 + %2 = load i32, i32* @sk, align 4 + %div = sdiv i32 %1, %2 + store i32 %div, i32* @si, align 4 + ret void +} + +define void @divu() { + ; CHECK-LABEL: divu: + + ; CHECK: lui $[[GOT1:[0-9]+]], %hi(_gp_disp) + ; CHECK: addiu $[[GOT2:[0-9]+]], $[[GOT1]], %lo(_gp_disp) + ; CHECK: addu $[[GOT:[0-9]+]], $[[GOT2:[0-9]+]], $25 + ; CHECK-DAG: lw $[[I_ADDR:[0-9]+]], %got(ui)($[[GOT]]) + ; CHECK-DAG: lw $[[K_ADDR:[0-9]+]], %got(uk)($[[GOT]]) + ; CHECK-DAG: lw $[[J_ADDR:[0-9]+]], %got(uj)($[[GOT]]) + ; CHECK-DAG: lw $[[J:[0-9]+]], 0($[[J_ADDR]]) + ; CHECK-DAG: lw $[[K:[0-9]+]], 0($[[K_ADDR]]) + ; CHECK-DAG: divu $zero, $[[J]], $[[K]] + ; CHECK_DAG: teq $[[K]], $zero, 7 + ; CHECK-DAG: mflo $[[RESULT:[0-9]+]] + ; CHECK: sw $[[RESULT]], 0($[[I_ADDR]]) + %1 = load i32, i32* @uj, align 4 + %2 = load i32, i32* @uk, align 4 + %div = udiv i32 %1, %2 + store i32 %div, i32* @ui, align 4 + ret void +} diff --git a/test/CodeGen/Mips/Fast-ISel/memtest1.ll b/test/CodeGen/Mips/Fast-ISel/memtest1.ll new file mode 100644 index 000000000000..a3fc4a32981c --- /dev/null +++ b/test/CodeGen/Mips/Fast-ISel/memtest1.ll @@ -0,0 +1,74 @@ +; RUN: llc < %s -march=mipsel -mcpu=mips32 -O0 -relocation-model=pic \ +; RUN: -fast-isel=true -mips-fast-isel -fast-isel-abort=1 | FileCheck %s \ +; RUN: -check-prefix=ALL -check-prefix=32R1 +; RUN: llc < %s -march=mipsel -mcpu=mips32r2 -O0 -relocation-model=pic \ +; RUN: -fast-isel=true -mips-fast-isel -fast-isel-abort=1 | FileCheck %s \ +; RUN: -check-prefix=ALL -check-prefix=32R2 + +@str = private unnamed_addr constant [12 x i8] c"hello there\00", align 1 +@src = global i8* getelementptr inbounds ([12 x i8], [12 x i8]* @str, i32 0, i32 0), align 4 +@i = global i32 12, align 4 +@dest = common global [50 x i8] zeroinitializer, align 1 + +declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture readonly, i32, i32, i1) +declare void @llvm.memmove.p0i8.p0i8.i32(i8* nocapture, i8* nocapture readonly, i32, i32, i1) +declare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i32, i1) + +define void @cpy(i8* %src, i32 %i) { + ; ALL-LABEL: cpy: + + ; ALL-DAG: lw $[[T0:[0-9]+]], %got(dest)(${{[0-9]+}}) + ; ALL-DAG: sw $4, 24($sp) + ; ALL-DAG: move $4, $[[T0]] + ; ALL-DAG: sw $5, 20($sp) + ; ALL-DAG: lw $[[T1:[0-9]+]], 24($sp) + ; ALL-DAG: move $5, $[[T1]] + ; ALL-DAG: lw $6, 20($sp) + ; ALL-DAG: lw $[[T2:[0-9]+]], %got(memcpy)(${{[0-9]+}}) + ; ALL: jalr $[[T2]] + ; ALL-NEXT: nop + ; ALL-NOT: {{.*}}$2{{.*}} + call void @llvm.memcpy.p0i8.p0i8.i32(i8* getelementptr inbounds ([50 x i8], [50 x i8]* @dest, i32 0, i32 0), + i8* %src, i32 %i, i32 1, i1 false) + ret void +} + +define void @mov(i8* %src, i32 %i) { + ; ALL-LABEL: mov: + + + ; ALL-DAG: lw $[[T0:[0-9]+]], %got(dest)(${{[0-9]+}}) + ; ALL-DAG: sw $4, 24($sp) + ; ALL-DAG: move $4, $[[T0]] + ; ALL-DAG: sw $5, 20($sp) + ; ALL-DAG: lw $[[T1:[0-9]+]], 24($sp) + ; ALL-DAG: move $5, $[[T1]] + ; ALL-DAG: lw $6, 20($sp) + ; ALL-DAG: lw $[[T2:[0-9]+]], %got(memmove)(${{[0-9]+}}) + ; ALL: jalr $[[T2]] + ; ALL-NEXT: nop + ; ALL-NOT: {{.*}}$2{{.*}} + call void @llvm.memmove.p0i8.p0i8.i32(i8* getelementptr inbounds ([50 x i8], [50 x i8]* @dest, i32 0, i32 0), + i8* %src, i32 %i, i32 1, i1 false) + ret void +} + +define void @clear(i32 %i) { + ; ALL-LABEL: clear: + + ; ALL-DAG: lw $[[T0:[0-9]+]], %got(dest)(${{[0-9]+}}) + ; ALL-DAG: sw $4, 16($sp) + ; ALL-DAG: move $4, $[[T0]] + ; ALL-DAG: addiu $[[T1:[0-9]+]], $zero, 42 + ; 32R1-DAG: sll $[[T2:[0-9]+]], $[[T1]], 24 + ; 32R1-DAG: sra $5, $[[T2]], 24 + ; 32R2-DAG: seb $5, $[[T1]] + ; ALL-DAG: lw $6, 16($sp) + ; ALL-DAG: lw $[[T2:[0-9]+]], %got(memset)(${{[0-9]+}}) + ; ALL: jalr $[[T2]] + ; ALL-NEXT: nop + ; ALL-NOT: {{.*}}$2{{.*}} + call void @llvm.memset.p0i8.i32(i8* getelementptr inbounds ([50 x i8], [50 x i8]* @dest, i32 0, i32 0), + i8 42, i32 %i, i32 1, i1 false) + ret void +} diff --git a/test/CodeGen/Mips/Fast-ISel/mul1.ll b/test/CodeGen/Mips/Fast-ISel/mul1.ll new file mode 100644 index 000000000000..0ee044bea0a7 --- /dev/null +++ b/test/CodeGen/Mips/Fast-ISel/mul1.ll @@ -0,0 +1,18 @@ +; RUN: llc < %s -march=mipsel -mcpu=mips32 -O0 \ +; RUN: -fast-isel -mips-fast-isel -relocation-model=pic +; RUN: llc < %s -march=mipsel -mcpu=mips32r2 -O0 \ +; RUN: -fast-isel -mips-fast-isel -relocation-model=pic + +; The test is just to make sure it is able to allocate +; registers for this example. There was an issue with allocating AC0 +; after a mul instruction. + +declare { i32, i1 } @llvm.smul.with.overflow.i32(i32, i32) + +define i32 @foo(i32 %a, i32 %b) { +entry: + %0 = mul i32 %a, %b + %1 = call { i32, i1 } @llvm.smul.with.overflow.i32(i32 %0, i32 %b) + %2 = extractvalue { i32, i1 } %1, 0 + ret i32 %2 +} diff --git a/test/CodeGen/Mips/Fast-ISel/rem1.ll b/test/CodeGen/Mips/Fast-ISel/rem1.ll new file mode 100644 index 000000000000..9b5e440d0eaa --- /dev/null +++ b/test/CodeGen/Mips/Fast-ISel/rem1.ll @@ -0,0 +1,56 @@ +; RUN: llc < %s -march=mipsel -mcpu=mips32 -O0 -relocation-model=pic \ +; RUN: -fast-isel=true -mips-fast-isel -fast-isel-abort=1 | FileCheck %s +; RUN: llc < %s -march=mipsel -mcpu=mips32r2 -O0 -relocation-model=pic \ +; RUN: -fast-isel=true -mips-fast-isel -fast-isel-abort=1 | FileCheck %s + +@sj = global i32 200, align 4 +@sk = global i32 -47, align 4 +@uj = global i32 200, align 4 +@uk = global i32 43, align 4 +@si = common global i32 0, align 4 +@ui = common global i32 0, align 4 + +define void @rems() { + ; CHECK-LABEL: rems: + + ; CHECK: lui $[[GOT1:[0-9]+]], %hi(_gp_disp) + ; CHECK: addiu $[[GOT2:[0-9]+]], $[[GOT1]], %lo(_gp_disp) + ; CHECK: addu $[[GOT:[0-9]+]], $[[GOT2:[0-9]+]], $25 + ; CHECK-DAG: lw $[[I_ADDR:[0-9]+]], %got(si)($[[GOT]]) + ; CHECK-DAG: lw $[[K_ADDR:[0-9]+]], %got(sk)($[[GOT]]) + ; CHECK-DAG: lw $[[J_ADDR:[0-9]+]], %got(sj)($[[GOT]]) + ; CHECK-DAG: lw $[[J:[0-9]+]], 0($[[J_ADDR]]) + ; CHECK-DAG: lw $[[K:[0-9]+]], 0($[[K_ADDR]]) + ; CHECK-DAG: div $zero, $[[J]], $[[K]] + ; CHECK_DAG: teq $[[K]], $zero, 7 + ; CHECK-DAG: mfhi $[[RESULT:[0-9]+]] + ; CHECK: sw $[[RESULT]], 0($[[I_ADDR]]) + %1 = load i32, i32* @sj, align 4 + %2 = load i32, i32* @sk, align 4 + %rem = srem i32 %1, %2 + store i32 %rem, i32* @si, align 4 + ret void +} + +; Function Attrs: noinline nounwind +define void @remu() { + ; CHECK-LABEL: remu: + + ; CHECK: lui $[[GOT1:[0-9]+]], %hi(_gp_disp) + ; CHECK: addiu $[[GOT2:[0-9]+]], $[[GOT1]], %lo(_gp_disp) + ; CHECK: addu $[[GOT:[0-9]+]], $[[GOT2:[0-9]+]], $25 + ; CHECK-DAG: lw $[[I_ADDR:[0-9]+]], %got(ui)($[[GOT]]) + ; CHECK-DAG: lw $[[K_ADDR:[0-9]+]], %got(uk)($[[GOT]]) + ; CHECK-DAG: lw $[[J_ADDR:[0-9]+]], %got(uj)($[[GOT]]) + ; CHECK-DAG: lw $[[J:[0-9]+]], 0($[[J_ADDR]]) + ; CHECK-DAG: lw $[[K:[0-9]+]], 0($[[K_ADDR]]) + ; CHECK-DAG: divu $zero, $[[J]], $[[K]] + ; CHECK_DAG: teq $[[K]], $zero, 7 + ; CHECK-DAG: mfhi $[[RESULT:[0-9]+]] + ; CHECK: sw $[[RESULT]], 0($[[I_ADDR]]) + %1 = load i32, i32* @uj, align 4 + %2 = load i32, i32* @uk, align 4 + %rem = urem i32 %1, %2 + store i32 %rem, i32* @ui, align 4 + ret void +} diff --git a/test/CodeGen/Mips/Fast-ISel/sel1.ll b/test/CodeGen/Mips/Fast-ISel/sel1.ll new file mode 100644 index 000000000000..47b6a895cde8 --- /dev/null +++ b/test/CodeGen/Mips/Fast-ISel/sel1.ll @@ -0,0 +1,91 @@ +; RUN: llc < %s -march=mipsel -mcpu=mips32r2 -O2 -relocation-model=pic \ +; RUN: -fast-isel -mips-fast-isel -fast-isel-abort=1 | FileCheck %s + +define i1 @sel_i1(i1 %j, i1 %k, i1 %l) { +entry: + ; CHECK-LABEL: sel_i1: + + ; FIXME: The following instruction is redundant. + ; CHECK: xor $[[T0:[0-9]+]], $4, $zero + ; CHECK-NEXT: sltu $[[T1:[0-9]+]], $zero, $[[T0]] + ; CHECK-NEXT: movn $6, $5, $[[T1]] + ; CHECK: move $2, $6 + %cond = icmp ne i1 %j, 0 + %res = select i1 %cond, i1 %k, i1 %l + ret i1 %res +} + +define i8 @sel_i8(i8 %j, i8 %k, i8 %l) { +entry: + ; CHECK-LABEL: sel_i8: + + ; CHECK-DAG: seb $[[T0:[0-9]+]], $4 + ; FIXME: The following 2 instructions are redundant. + ; CHECK-DAG: seb $[[T1:[0-9]+]], $zero + ; CHECK: xor $[[T2:[0-9]+]], $[[T0]], $[[T1]] + ; CHECK-NEXT: sltu $[[T3:[0-9]+]], $zero, $[[T2]] + ; CHECK-NEXT: movn $6, $5, $[[T3]] + ; CHECK: move $2, $6 + %cond = icmp ne i8 %j, 0 + %res = select i1 %cond, i8 %k, i8 %l + ret i8 %res +} + +define i16 @sel_i16(i16 %j, i16 %k, i16 %l) { +entry: + ; CHECK-LABEL: sel_i16: + + ; CHECK-DAG: seh $[[T0:[0-9]+]], $4 + ; FIXME: The following 2 instructions are redundant. + ; CHECK-DAG: seh $[[T1:[0-9]+]], $zero + ; CHECK: xor $[[T2:[0-9]+]], $[[T0]], $[[T1]] + ; CHECK-NEXT: sltu $[[T3:[0-9]+]], $zero, $[[T2]] + ; CHECK-NEXT: movn $6, $5, $[[T3]] + ; CHECK: move $2, $6 + %cond = icmp ne i16 %j, 0 + %res = select i1 %cond, i16 %k, i16 %l + ret i16 %res +} + +define i32 @sel_i32(i32 %j, i32 %k, i32 %l) { +entry: + ; CHECK-LABEL: sel_i32: + + ; FIXME: The following instruction is redundant. + ; CHECK: xor $[[T0:[0-9]+]], $4, $zero + ; CHECK-NEXT: sltu $[[T1:[0-9]+]], $zero, $[[T0]] + ; CHECK-NEXT: movn $6, $5, $[[T1]] + ; CHECK: move $2, $6 + %cond = icmp ne i32 %j, 0 + %res = select i1 %cond, i32 %k, i32 %l + ret i32 %res +} + +define float @sel_float(i32 %j, float %k, float %l) { +entry: + ; CHECK-LABEL: sel_float: + + ; CHECK-DAG: mtc1 $6, $f0 + ; CHECK-DAG: mtc1 $5, $f1 + ; CHECK-DAG: xor $[[T0:[0-9]+]], $4, $zero + ; CHECK: sltu $[[T1:[0-9]+]], $zero, $[[T0]] + ; CHECK: movn.s $f0, $f1, $[[T1]] + %cond = icmp ne i32 %j, 0 + %res = select i1 %cond, float %k, float %l + ret float %res +} + +define double @sel_double(i32 %j, double %k, double %l) { +entry: + ; CHECK-LABEL: sel_double: + + ; CHECK-DAG: mtc1 $6, $f2 + ; CHECK-DAG: mthc1 $7, $f2 + ; CHECK-DAG: ldc1 $f0, 16($sp) + ; CHECK-DAG: xor $[[T0:[0-9]+]], $4, $zero + ; CHECK: sltu $[[T1:[0-9]+]], $zero, $[[T0]] + ; CHECK: movn.d $f0, $f2, $[[T1]] + %cond = icmp ne i32 %j, 0 + %res = select i1 %cond, double %k, double %l + ret double %res +} diff --git a/test/CodeGen/Mips/dynamic-stack-realignment.ll b/test/CodeGen/Mips/dynamic-stack-realignment.ll new file mode 100644 index 000000000000..777930a37ad5 --- /dev/null +++ b/test/CodeGen/Mips/dynamic-stack-realignment.ll @@ -0,0 +1,299 @@ +; RUN: llc < %s -march=mips -mcpu=mips2 | FileCheck %s \ +; RUN: --check-prefix=ALL --check-prefix=GP32 +; RUN: llc < %s -march=mips -mcpu=mips32 | FileCheck %s \ +; RUN: --check-prefix=ALL --check-prefix=GP32 +; RUN: llc < %s -march=mips -mcpu=mips32r6 | FileCheck %s \ +; RUN: --check-prefix=ALL --check-prefix=GP32 +; RUN: llc < %s -march=mips64 -mcpu=mips3 | FileCheck %s \ +; RUN: --check-prefix=ALL --check-prefix=GP64 -check-prefix=N64 +; RUN: llc < %s -march=mips64 -mcpu=mips64 | FileCheck %s \ +; RUN: --check-prefix=ALL --check-prefix=GP64 -check-prefix=N64 +; RUN: llc < %s -march=mips64 -mcpu=mips64r6 | FileCheck %s \ +; RUN: --check-prefix=ALL --check-prefix=GP64 -check-prefix=N64 +; RUN: llc < %s -march=mips64 -mcpu=mips3 -target-abi n32 | FileCheck %s \ +; RUN: --check-prefix=ALL --check-prefix=GP64 -check-prefix=N32 +; RUN: llc < %s -march=mips64 -mcpu=mips64 -target-abi n32 | FileCheck %s \ +; RUN: --check-prefix=ALL --check-prefix=GP64 -check-prefix=N32 +; RUN: llc < %s -march=mips64 -mcpu=mips64r6 -target-abi n32 | FileCheck %s \ +; RUN: --check-prefix=ALL --check-prefix=GP64 -check-prefix=N32 + +; Check dynamic stack realignment in functions without variable-sized objects. + +declare void @helper_01(i32, i32, i32, i32, i32*) + +; O32 ABI +define void @func_01() { +entry: +; GP32-LABEL: func_01: + + ; prologue + ; FIXME: We are currently over-allocating stack space. This particular case + ; needs a frame of up to between 16 and 512-bytes but currently + ; allocates between 1024 and 1536 bytes + ; GP32: addiu $sp, $sp, -1024 + ; GP32: sw $ra, 1020($sp) + ; GP32: sw $fp, 1016($sp) + ; + ; GP32: move $fp, $sp + ; GP32: addiu $[[T0:[0-9]+|ra|gp]], $zero, -512 + ; GP32-NEXT: and $sp, $sp, $[[T0]] + + ; body + ; GP32: addiu $[[T1:[0-9]+]], $sp, 512 + ; GP32: sw $[[T1]], 16($sp) + + ; epilogue + ; GP32: move $sp, $fp + ; GP32: lw $fp, 1016($sp) + ; GP32: lw $ra, 1020($sp) + ; GP32: addiu $sp, $sp, 1024 + + %a = alloca i32, align 512 + call void @helper_01(i32 0, i32 0, i32 0, i32 0, i32* %a) + ret void +} + +declare void @helper_02(i32, i32, i32, i32, + i32, i32, i32, i32, i32*) + +; N32/N64 ABIs +define void @func_02() { +entry: +; GP64-LABEL: func_02: + + ; prologue + ; FIXME: We are currently over-allocating stack space. This particular case + ; needs a frame of up to between 16 and 512-bytes but currently + ; allocates between 1024 and 1536 bytes + ; N32: addiu $sp, $sp, -1024 + ; N64: daddiu $sp, $sp, -1024 + ; GP64: sd $ra, 1016($sp) + ; GP64: sd $fp, 1008($sp) + ; N32: sd $gp, 1000($sp) + ; + ; GP64: move $fp, $sp + ; N32: addiu $[[T0:[0-9]+|ra]], $zero, -512 + ; N64: daddiu $[[T0:[0-9]+|ra]], $zero, -512 + ; GP64-NEXT: and $sp, $sp, $[[T0]] + + ; body + ; N32: addiu $[[T1:[0-9]+]], $sp, 512 + ; N64: daddiu $[[T1:[0-9]+]], $sp, 512 + ; GP64: sd $[[T1]], 0($sp) + + ; epilogue + ; GP64: move $sp, $fp + ; N32: ld $gp, 1000($sp) + ; GP64: ld $fp, 1008($sp) + ; GP64: ld $ra, 1016($sp) + ; N32: addiu $sp, $sp, 1024 + ; N64: daddiu $sp, $sp, 1024 + + %a = alloca i32, align 512 + call void @helper_02(i32 0, i32 0, i32 0, i32 0, + i32 0, i32 0, i32 0, i32 0, i32* %a) + ret void +} + +; Verify that we use $fp for referencing incoming arguments. + +declare void @helper_03(i32, i32, i32, i32, i32*, i32*) + +; O32 ABI +define void @func_03(i32 %p0, i32 %p1, i32 %p2, i32 %p3, i32* %b) { +entry: +; GP32-LABEL: func_03: + + ; body + ; FIXME: We are currently over-allocating stack space. + ; GP32-DAG: addiu $[[T0:[0-9]+]], $sp, 512 + ; GP32-DAG: sw $[[T0]], 16($sp) + ; GP32-DAG: lw $[[T1:[0-9]+]], 1040($fp) + ; GP32-DAG: sw $[[T1]], 20($sp) + + %a = alloca i32, align 512 + call void @helper_03(i32 0, i32 0, i32 0, i32 0, i32* %a, i32* %b) + ret void +} + +declare void @helper_04(i32, i32, i32, i32, + i32, i32, i32, i32, i32*, i32*) + +; N32/N64 ABIs +define void @func_04(i32 %p0, i32 %p1, i32 %p2, i32 %p3, + i32 %p4, i32 %p5, i32 %p6, i32 %p7, + i32* %b) { +entry: +; GP64-LABEL: func_04: + + ; body + ; FIXME: We are currently over-allocating stack space. + ; N32-DAG: addiu $[[T0:[0-9]+]], $sp, 512 + ; N64-DAG: daddiu $[[T0:[0-9]+]], $sp, 512 + ; GP64-DAG: sd $[[T0]], 0($sp) + ; GP64-DAG: ld $[[T1:[0-9]+]], 1024($fp) + ; GP64-DAG: sd $[[T1]], 8($sp) + + %a = alloca i32, align 512 + call void @helper_04(i32 0, i32 0, i32 0, i32 0, + i32 0, i32 0, i32 0, i32 0, i32* %a, i32* %b) + ret void +} + +; Check dynamic stack realignment in functions with variable-sized objects. + +; O32 ABI +define void @func_05(i32 %sz) { +entry: +; GP32-LABEL: func_05: + + ; prologue + ; FIXME: We are currently over-allocating stack space. + ; GP32: addiu $sp, $sp, -1024 + ; GP32: sw $fp, 1020($sp) + ; GP32: sw $23, 1016($sp) + ; + ; GP32: move $fp, $sp + ; GP32: addiu $[[T0:[0-9]+|gp]], $zero, -512 + ; GP32-NEXT: and $sp, $sp, $[[T0]] + ; GP32-NEXT: move $23, $sp + + ; body + ; GP32: addiu $[[T1:[0-9]+]], $zero, 222 + ; GP32: sw $[[T1]], 508($23) + + ; epilogue + ; GP32: move $sp, $fp + ; GP32: lw $23, 1016($sp) + ; GP32: lw $fp, 1020($sp) + ; GP32: addiu $sp, $sp, 1024 + + %a0 = alloca i32, i32 %sz, align 512 + %a1 = alloca i32, align 4 + + store volatile i32 111, i32* %a0, align 512 + store volatile i32 222, i32* %a1, align 4 + + ret void +} + +; N32/N64 ABIs +define void @func_06(i32 %sz) { +entry: +; GP64-LABEL: func_06: + + ; prologue + ; FIXME: We are currently over-allocating stack space. + ; N32: addiu $sp, $sp, -1024 + ; N64: daddiu $sp, $sp, -1024 + ; GP64: sd $fp, 1016($sp) + ; GP64: sd $23, 1008($sp) + ; + ; GP64: move $fp, $sp + ; GP64: addiu $[[T0:[0-9]+|gp]], $zero, -512 + ; GP64-NEXT: and $sp, $sp, $[[T0]] + ; GP64-NEXT: move $23, $sp + + ; body + ; GP64: addiu $[[T1:[0-9]+]], $zero, 222 + ; GP64: sw $[[T1]], 508($23) + + ; epilogue + ; GP64: move $sp, $fp + ; GP64: ld $23, 1008($sp) + ; GP64: ld $fp, 1016($sp) + ; N32: addiu $sp, $sp, 1024 + ; N64: daddiu $sp, $sp, 1024 + + %a0 = alloca i32, i32 %sz, align 512 + %a1 = alloca i32, align 4 + + store volatile i32 111, i32* %a0, align 512 + store volatile i32 222, i32* %a1, align 4 + + ret void +} + +; Verify that we use $fp for referencing incoming arguments and $sp for +; building outbound arguments for nested function calls. + +; O32 ABI +define void @func_07(i32 %p0, i32 %p1, i32 %p2, i32 %p3, i32 %sz) { +entry: +; GP32-LABEL: func_07: + + ; body + ; FIXME: We are currently over-allocating stack space. + ; GP32-DAG: lw $[[T0:[0-9]+]], 1040($fp) + ; + ; GP32-DAG: addiu $[[T1:[0-9]+]], $zero, 222 + ; GP32-DAG: sw $[[T1]], 508($23) + ; + ; GP32-DAG: sw $[[T2:[0-9]+]], 16($sp) + + %a0 = alloca i32, i32 %sz, align 512 + %a1 = alloca i32, align 4 + + store volatile i32 111, i32* %a0, align 512 + store volatile i32 222, i32* %a1, align 4 + + call void @helper_01(i32 0, i32 0, i32 0, i32 0, i32* %a1) + + ret void +} + +; N32/N64 ABIs +define void @func_08(i32 %p0, i32 %p1, i32 %p2, i32 %p3, + i32 %p4, i32 %p5, i32 %p6, i32 %p7, + i32 %sz) { +entry: +; GP64-LABEL: func_08: + + ; body + ; FIXME: We are currently over-allocating stack space. + ; N32-DAG: lw $[[T0:[0-9]+]], 1028($fp) + ; N64-DAG: lwu $[[T0:[0-9]+]], 1028($fp) + ; + ; GP64-DAG: addiu $[[T1:[0-9]+]], $zero, 222 + ; GP64-DAG: sw $[[T1]], 508($23) + ; + ; GP64-DAG: sd $[[T2:[0-9]+]], 0($sp) + + %a0 = alloca i32, i32 %sz, align 512 + %a1 = alloca i32, align 4 + + store volatile i32 111, i32* %a0, align 512 + store volatile i32 222, i32* %a1, align 4 + + call void @helper_02(i32 0, i32 0, i32 0, i32 0, + i32 0, i32 0, i32 0, i32 0, i32* %a1) + ret void +} + +; Check that we do not perform dynamic stack realignment in the presence of +; the "no-realign-stack" function attribute. +define void @func_09() "no-realign-stack" { +entry: +; ALL-LABEL: func_09: + + ; ALL-NOT: and $sp, $sp, $[[T0:[0-9]+|ra|gp]] + + %a = alloca i32, align 512 + call void @helper_01(i32 0, i32 0, i32 0, i32 0, i32* %a) + ret void +} + +define void @func_10(i32 %sz) "no-realign-stack" { +entry: +; ALL-LABEL: func_10: + + ; ALL-NOT: and $sp, $sp, $[[T0:[0-9]+|ra|gp]] + + %a0 = alloca i32, i32 %sz, align 512 + %a1 = alloca i32, align 4 + + store volatile i32 111, i32* %a0, align 512 + store volatile i32 222, i32* %a1, align 4 + + ret void +} diff --git a/test/CodeGen/Mips/ehframe-indirect.ll b/test/CodeGen/Mips/ehframe-indirect.ll index f124881a472f..dc06ef7840ff 100644 --- a/test/CodeGen/Mips/ehframe-indirect.ll +++ b/test/CodeGen/Mips/ehframe-indirect.ll @@ -1,9 +1,11 @@ -; RUN: llc -mtriple=mipsel-linux-gnu < %s | FileCheck -check-prefix=ALL -check-prefix=O32 %s -; RUN: llc -mtriple=mipsel-linux-android < %s | FileCheck -check-prefix=ALL -check-prefix=O32 %s -; RUN: llc -mtriple=mips64el-linux-gnu -target-abi=n32 < %s | FileCheck -check-prefix=ALL -check-prefix=N32 %s -; RUN: llc -mtriple=mips64el-linux-android -target-abi=n32 < %s | FileCheck -check-prefix=ALL -check-prefix=N32 %s -; RUN: llc -mtriple=mips64el-linux-gnu < %s | FileCheck -check-prefix=ALL -check-prefix=N64 %s -; RUN: llc -mtriple=mips64el-linux-android < %s | FileCheck -check-prefix=ALL -check-prefix=N64 %s +; RUN: llc -mtriple=mipsel-linux-gnu < %s -asm-verbose | FileCheck -check-prefix=ALL -check-prefix=O32 %s +; RUN: llc -mtriple=mipsel-linux-android < %s -asm-verbose | FileCheck -check-prefix=ALL -check-prefix=O32 %s +; RUN: llc -mtriple=mips64el-linux-gnu -target-abi=n32 < %s -asm-verbose | FileCheck -check-prefix=ALL -check-prefix=N32 %s +; RUN: llc -mtriple=mips64el-linux-android -target-abi=n32 < %s -asm-verbose | FileCheck -check-prefix=ALL -check-prefix=N32 %s +; RUN: llc -mtriple=mips64el-linux-gnu < %s -asm-verbose | FileCheck -check-prefix=ALL -check-prefix=N64 %s +; RUN: llc -mtriple=mips64el-linux-android < %s -asm-verbose | FileCheck -check-prefix=ALL -check-prefix=N64 %s + +@_ZTISt9exception = external constant i8* define i32 @main() { ; ALL: .cfi_startproc @@ -16,7 +18,9 @@ entry: lpad: %0 = landingpad { i8*, i32 } personality i8* - bitcast (i32 (...)* @__gxx_personality_v0 to i8*) catch i8* null + bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + catch i8* null + catch i8* bitcast (i8** @_ZTISt9exception to i8*) ret i32 0 cont: @@ -28,6 +32,14 @@ declare i32 @__gxx_personality_v0(...) declare void @foo() +; ALL: GCC_except_table{{[0-9]+}}: +; ALL: .byte 155 # @TType Encoding = indirect pcrel sdata4 +; ALL: $[[PC_LABEL:tmp[0-9]+]]: +; ALL: .4byte ($_ZTISt9exception.DW.stub)-($[[PC_LABEL]]) +; ALL: $_ZTISt9exception.DW.stub: +; O32: .4byte _ZTISt9exception +; N32: .4byte _ZTISt9exception +; N64: .8byte _ZTISt9exception ; ALL: .hidden DW.ref.__gxx_personality_v0 ; ALL: .weak DW.ref.__gxx_personality_v0 ; ALL: .section .data.DW.ref.__gxx_personality_v0,"aGw",@progbits,DW.ref.__gxx_personality_v0,comdat diff --git a/test/CodeGen/Mips/emergency-spill-slot-near-fp.ll b/test/CodeGen/Mips/emergency-spill-slot-near-fp.ll index 3dc1cde77095..779620e10128 100644 --- a/test/CodeGen/Mips/emergency-spill-slot-near-fp.ll +++ b/test/CodeGen/Mips/emergency-spill-slot-near-fp.ll @@ -1,8 +1,8 @@ ; Check that register scavenging spill slot is close to $fp. ; RUN: llc -march=mipsel -O0 < %s | FileCheck %s -; CHECK: sw ${{.*}}, 4($fp) -; CHECK: lw ${{.*}}, 4($fp) +; CHECK: sw ${{.*}}, 4($sp) +; CHECK: lw ${{.*}}, 4($sp) define i32 @main(i32 signext %argc, i8** %argv) "no-frame-pointer-elim"="true" { entry: |
