diff options
Diffstat (limited to 'test/CodeGen/Mips')
46 files changed, 5166 insertions, 1017 deletions
diff --git a/test/CodeGen/Mips/2008-08-01-AsmInline.ll b/test/CodeGen/Mips/2008-08-01-AsmInline.ll index e274bc0..3c1bb39 100644 --- a/test/CodeGen/Mips/2008-08-01-AsmInline.ll +++ b/test/CodeGen/Mips/2008-08-01-AsmInline.ll @@ -1,4 +1,4 @@ -; RUN: llc -march=mips < %s | FileCheck %s +; RUN: llc -march=mips -mcpu=mips32 < %s | FileCheck %s ; RUN: llc -march=mips64el -mcpu=mips64r2 -mattr=n64 < %s | FileCheck %s %struct.DWstruct = type { i32, i32 } diff --git a/test/CodeGen/Mips/2013-11-18-fp64-const0.ll b/test/CodeGen/Mips/2013-11-18-fp64-const0.ll index f8390d9..6a210a0 100644 --- a/test/CodeGen/Mips/2013-11-18-fp64-const0.ll +++ b/test/CodeGen/Mips/2013-11-18-fp64-const0.ll @@ -1,5 +1,5 @@ ; RUN: llc -march=mips -mattr=-fp64 < %s | FileCheck -check-prefix=CHECK-FP32 %s -; RUN: llc -march=mips -mattr=+fp64 < %s | FileCheck -check-prefix=CHECK-FP64 %s +; RUN: llc -march=mips -mcpu=mips32r2 -mattr=+fp64 < %s | FileCheck -check-prefix=CHECK-FP64 %s ; This test case is a simplified version of an llvm-stress generated test with ; seed=3718491962. diff --git a/test/CodeGen/Mips/Fast-ISel/loadstore2.ll b/test/CodeGen/Mips/Fast-ISel/loadstore2.ll new file mode 100644 index 0000000..f113a0e --- /dev/null +++ b/test/CodeGen/Mips/Fast-ISel/loadstore2.ll @@ -0,0 +1,83 @@ +; ModuleID = 'loadstore2.c' +target datalayout = "E-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64" +target triple = "mips--linux-gnu" + +@c2 = common global i8 0, align 1 +@c1 = common global i8 0, align 1 +; RUN: llc -march=mipsel -relocation-model=pic -O0 -mips-fast-isel -fast-isel-abort -mcpu=mips32r2 \ +; RUN: < %s | FileCheck %s + +@s2 = common global i16 0, align 2 +@s1 = common global i16 0, align 2 +@i2 = common global i32 0, align 4 +@i1 = common global i32 0, align 4 +@f2 = common global float 0.000000e+00, align 4 +@f1 = common global float 0.000000e+00, align 4 +@d2 = common global double 0.000000e+00, align 8 +@d1 = common global double 0.000000e+00, align 8 + +; Function Attrs: nounwind +define void @cfoo() #0 { +entry: + %0 = load i8* @c2, align 1 + store i8 %0, i8* @c1, align 1 +; CHECK-LABEL: cfoo: +; CHECK: lbu $[[REGc:[0-9]+]], 0(${{[0-9]+}}) +; CHECK: sb $[[REGc]], 0(${{[0-9]+}}) + + + ret void +} + +; Function Attrs: nounwind +define void @sfoo() #0 { +entry: + %0 = load i16* @s2, align 2 + store i16 %0, i16* @s1, align 2 +; CHECK-LABEL: sfoo: +; CHECK: lhu $[[REGs:[0-9]+]], 0(${{[0-9]+}}) +; CHECK: sh $[[REGs]], 0(${{[0-9]+}}) + + ret void +} + +; Function Attrs: nounwind +define void @ifoo() #0 { +entry: + %0 = load i32* @i2, align 4 + store i32 %0, i32* @i1, align 4 +; CHECK-LABEL: ifoo: +; CHECK: lw $[[REGi:[0-9]+]], 0(${{[0-9]+}}) +; CHECK: sw $[[REGi]], 0(${{[0-9]+}}) + + ret void +} + +; Function Attrs: nounwind +define void @ffoo() #0 { +entry: + %0 = load float* @f2, align 4 + store float %0, float* @f1, align 4 +; CHECK-LABEL: ffoo: +; CHECK: lwc1 $f[[REGf:[0-9]+]], 0(${{[0-9]+}}) +; CHECK: swc1 $f[[REGf]], 0(${{[0-9]+}}) + + + ret void +} + +; Function Attrs: nounwind +define void @dfoo() #0 { +entry: + %0 = load double* @d2, align 8 + store double %0, double* @d1, align 8 +; CHECK-LABEL: dfoo: +; CHECK: ldc1 $f[[REGd:[0-9]+]], 0(${{[0-9]+}}) +; CHECK: sdc1 $f[[REGd]], 0(${{[0-9]+}}) +; CHECK: .end dfoo + ret void +} + +attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } + + diff --git a/test/CodeGen/Mips/Fast-ISel/simplestorefp1.ll b/test/CodeGen/Mips/Fast-ISel/simplestorefp1.ll new file mode 100644 index 0000000..6759c01 --- /dev/null +++ b/test/CodeGen/Mips/Fast-ISel/simplestorefp1.ll @@ -0,0 +1,38 @@ +; RUN: llc -march=mipsel -relocation-model=pic -O0 -mips-fast-isel -fast-isel-abort -mcpu=mips32r2 \ +; RUN: < %s | FileCheck %s + +@f = common global float 0.000000e+00, align 4 +@de = common global double 0.000000e+00, align 8 + +; Function Attrs: nounwind +define void @f1() #0 { +entry: + store float 0x3FFA76C8C0000000, float* @f, align 4 + ret void +; CHECK: .ent f1 +; CHECK: lui $[[REG1:[0-9]+]], 16339 +; CHECK: ori $[[REG2:[0-9]+]], $[[REG1]], 46662 +; CHECK: mtc1 $[[REG2]], $f[[REG3:[0-9]+]] +; CHECK: lw $[[REG4:[0-9]+]], %got(f)(${{[0-9]+}}) +; CHECK: swc1 $f[[REG3]], 0($[[REG4]]) +; CHECK: .end f1 + +} + +; Function Attrs: nounwind +define void @d1() #0 { +entry: + store double 1.234567e+00, double* @de, align 8 +; CHECK: .ent d1 +; CHECK: lui $[[REG1a:[0-9]+]], 16371 +; CHECK: ori $[[REG2a:[0-9]+]], $[[REG1a]], 49353 +; CHECK: lui $[[REG1b:[0-9]+]], 21403 +; CHECK: ori $[[REG2b:[0-9]+]], $[[REG1b]], 34951 +; CHECK: mtc1 $[[REG2b]], $f[[REG3:[0-9]+]] +; CHECK: mthc1 $[[REG2a]], $f[[REG3]] +; CHECK: sdc1 $f[[REG3]], 0(${{[0-9]+}}) +; CHECK: .end d1 + ret void +} + +attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } diff --git a/test/CodeGen/Mips/abiflags-xx.ll b/test/CodeGen/Mips/abiflags-xx.ll new file mode 100644 index 0000000..b8aa071 --- /dev/null +++ b/test/CodeGen/Mips/abiflags-xx.ll @@ -0,0 +1,6 @@ +; RUN: llc -filetype=asm -mtriple mipsel-unknown-linux -mcpu=mips32 -mattr=fpxx %s -o - | FileCheck %s +; XFAIL: * + +; CHECK: .nan legacy +; CHECK: .module fp=xx + diff --git a/test/CodeGen/Mips/abiflags32.ll b/test/CodeGen/Mips/abiflags32.ll new file mode 100644 index 0000000..093964f --- /dev/null +++ b/test/CodeGen/Mips/abiflags32.ll @@ -0,0 +1,12 @@ +; RUN: llc -filetype=asm -mtriple mipsel-unknown-linux -mcpu=mips32 %s -o - | FileCheck %s +; RUN: llc -filetype=asm -mtriple mipsel-unknown-linux -mcpu=mips32 -mattr=fp64 %s -o - | FileCheck -check-prefix=CHECK-64 %s +; RUN: llc -filetype=asm -mtriple mipsel-unknown-linux -mcpu=mips64 -mattr=-n64,n32 %s -o - | FileCheck -check-prefix=CHECK-64n %s + +; CHECK: .nan legacy +; CHECK: .module fp=32 + +; CHECK-64: .nan legacy +; CHECK-64: .module fp=64 + +; CHECK-64n: .nan legacy +; CHECK-64n: .module fp=64 diff --git a/test/CodeGen/Mips/analyzebranch.ll b/test/CodeGen/Mips/analyzebranch.ll index 8ec5d93..4b5d097 100644 --- a/test/CodeGen/Mips/analyzebranch.ll +++ b/test/CodeGen/Mips/analyzebranch.ll @@ -1,9 +1,25 @@ -; RUN: llc -march=mips < %s | FileCheck %s +; RUN: llc -march=mips -mcpu=mips32 < %s | FileCheck %s -check-prefix=ALL -check-prefix=FCC +; RUN: llc -march=mips -mcpu=mips32r2 < %s | FileCheck %s -check-prefix=ALL -check-prefix=FCC +; RUN: llc -march=mips -mcpu=mips32r6 < %s | FileCheck %s -check-prefix=ALL -check-prefix=GPR -check-prefix=32-GPR +; RUN: llc -march=mips64 -mcpu=mips4 < %s | FileCheck %s -check-prefix=ALL -check-prefix=FCC +; RUN: llc -march=mips64 -mcpu=mips64 < %s | FileCheck %s -check-prefix=ALL -check-prefix=FCC +; RUN: llc -march=mips64 -mcpu=mips64r2 < %s | FileCheck %s -check-prefix=ALL -check-prefix=FCC +; RUN: llc -march=mips64 -mcpu=mips64r6 < %s | FileCheck %s -check-prefix=ALL -check-prefix=GPR -check-prefix=64-GPR define double @foo(double %a, double %b) nounwind readnone { entry: -; CHECK: bc1f $BB -; CHECK: nop +; ALL-LABEL: foo: + +; FCC: bc1f $BB +; FCC: nop + +; 32-GPR: mtc1 $zero, $[[Z:f[0-9]]] +; 32-GPR: mthc1 $zero, $[[Z:f[0-9]]] +; 64-GPR: dmtc1 $zero, $[[Z:f[0-9]]] +; GPR: cmp.lt.d $[[FGRCC:f[0-9]+]], $[[Z]], $f12 +; GPR: mfc1 $[[GPRCC:[0-9]+]], $[[FGRCC]] +; GPR-NOT: not $[[GPRCC]], $[[GPRCC]] +; GPR: bnez $[[GPRCC]], $BB %cmp = fcmp ogt double %a, 0.000000e+00 br i1 %cmp, label %if.end6, label %if.else @@ -25,8 +41,17 @@ return: ; preds = %if.else, %if.end6 define void @f1(float %f) nounwind { entry: -; CHECK: bc1f $BB -; CHECK: nop +; ALL-LABEL: f1: + +; FCC: bc1f $BB +; FCC: nop + +; GPR: mtc1 $zero, $[[Z:f[0-9]]] +; GPR: cmp.eq.s $[[FGRCC:f[0-9]+]], $f12, $[[Z]] +; GPR: mfc1 $[[GPRCC:[0-9]+]], $[[FGRCC]] +; GPR-NOT: not $[[GPRCC]], $[[GPRCC]] +; GPR: beqz $[[GPRCC]], $BB + %cmp = fcmp une float %f, 0.000000e+00 br i1 %cmp, label %if.then, label %if.end diff --git a/test/CodeGen/Mips/atomic.ll b/test/CodeGen/Mips/atomic.ll index 77d7bf3..066d42c 100644 --- a/test/CodeGen/Mips/atomic.ll +++ b/test/CodeGen/Mips/atomic.ll @@ -1,5 +1,14 @@ -; RUN: llc -march=mipsel --disable-machine-licm < %s | FileCheck %s -check-prefix=CHECK-EL -; RUN: llc -march=mips --disable-machine-licm < %s | FileCheck %s -check-prefix=CHECK-EB +; RUN: llc -march=mipsel --disable-machine-licm -mcpu=mips32 < %s | FileCheck %s -check-prefix=ALL -check-prefix=MIPS32-ANY -check-prefix=NO-SEB-SEH -check-prefix=CHECK-EL +; RUN: llc -march=mipsel --disable-machine-licm -mcpu=mips32r2 < %s | FileCheck %s -check-prefix=ALL -check-prefix=MIPS32-ANY -check-prefix=HAS-SEB-SEH -check-prefix=CHECK-EL +; RUN: llc -march=mipsel --disable-machine-licm -mcpu=mips32r6 < %s | FileCheck %s -check-prefix=ALL -check-prefix=MIPS32-ANY -check-prefix=HAS-SEB-SEH -check-prefix=CHECK-EL +; RUN: llc -march=mips64el --disable-machine-licm -mcpu=mips4 < %s | FileCheck %s -check-prefix=ALL -check-prefix=MIPS64-ANY -check-prefix=NO-SEB-SEH -check-prefix=CHECK-EL +; RUN: llc -march=mips64el --disable-machine-licm -mcpu=mips64 < %s | FileCheck %s -check-prefix=ALL -check-prefix=MIPS64-ANY -check-prefix=NO-SEB-SEH -check-prefix=CHECK-EL +; RUN: llc -march=mips64el --disable-machine-licm -mcpu=mips64r2 < %s | FileCheck %s -check-prefix=ALL -check-prefix=MIPS64-ANY -check-prefix=HAS-SEB-SEH -check-prefix=CHECK-EL +; RUN: llc -march=mips64el --disable-machine-licm -mcpu=mips64r6 < %s | FileCheck %s -check-prefix=ALL -check-prefix=MIPS64-ANY -check-prefix=HAS-SEB-SEH -check-prefix=CHECK-EL + +; Keep one big-endian check so that we don't reduce testing, but don't add more +; since endianness doesn't affect the body of the atomic operations. +; RUN: llc -march=mips --disable-machine-licm -mcpu=mips32 < %s | FileCheck %s -check-prefix=ALL -check-prefix=MIPS32-ANY -check-prefix=CHECK-EB @x = common global i32 0, align 4 @@ -8,21 +17,16 @@ entry: %0 = atomicrmw add i32* @x, i32 %incr monotonic ret i32 %0 -; CHECK-EL-LABEL: AtomicLoadAdd32: -; CHECK-EL: lw $[[R0:[0-9]+]], %got(x) -; CHECK-EL: $[[BB0:[A-Z_0-9]+]]: -; CHECK-EL: ll $[[R1:[0-9]+]], 0($[[R0]]) -; CHECK-EL: addu $[[R2:[0-9]+]], $[[R1]], $4 -; CHECK-EL: sc $[[R2]], 0($[[R0]]) -; CHECK-EL: beqz $[[R2]], $[[BB0]] - -; CHECK-EB-LABEL: AtomicLoadAdd32: -; CHECK-EB: lw $[[R0:[0-9]+]], %got(x) -; CHECK-EB: $[[BB0:[A-Z_0-9]+]]: -; CHECK-EB: ll $[[R1:[0-9]+]], 0($[[R0]]) -; CHECK-EB: addu $[[R2:[0-9]+]], $[[R1]], $4 -; CHECK-EB: sc $[[R2]], 0($[[R0]]) -; CHECK-EB: beqz $[[R2]], $[[BB0]] +; ALL-LABEL: AtomicLoadAdd32: + +; MIPS32-ANY: lw $[[R0:[0-9]+]], %got(x) +; MIPS64-ANY: ld $[[R0:[0-9]+]], %got_disp(x)( + +; ALL: $[[BB0:[A-Z_0-9]+]]: +; ALL: ll $[[R1:[0-9]+]], 0($[[R0]]) +; ALL: addu $[[R2:[0-9]+]], $[[R1]], $4 +; ALL: sc $[[R2]], 0($[[R0]]) +; ALL: beqz $[[R2]], $[[BB0]] } define i32 @AtomicLoadNand32(i32 %incr) nounwind { @@ -30,23 +34,17 @@ entry: %0 = atomicrmw nand i32* @x, i32 %incr monotonic ret i32 %0 -; CHECK-EL-LABEL: AtomicLoadNand32: -; CHECK-EL: lw $[[R0:[0-9]+]], %got(x) -; CHECK-EL: $[[BB0:[A-Z_0-9]+]]: -; CHECK-EL: ll $[[R1:[0-9]+]], 0($[[R0]]) -; CHECK-EL: and $[[R3:[0-9]+]], $[[R1]], $4 -; CHECK-EL: nor $[[R2:[0-9]+]], $zero, $[[R3]] -; CHECK-EL: sc $[[R2]], 0($[[R0]]) -; CHECK-EL: beqz $[[R2]], $[[BB0]] - -; CHECK-EB-LABEL: AtomicLoadNand32: -; CHECK-EB: lw $[[R0:[0-9]+]], %got(x) -; CHECK-EB: $[[BB0:[A-Z_0-9]+]]: -; CHECK-EB: ll $[[R1:[0-9]+]], 0($[[R0]]) -; CHECK-EB: and $[[R3:[0-9]+]], $[[R1]], $4 -; CHECK-EB: nor $[[R2:[0-9]+]], $zero, $[[R3]] -; CHECK-EB: sc $[[R2]], 0($[[R0]]) -; CHECK-EB: beqz $[[R2]], $[[BB0]] +; ALL-LABEL: AtomicLoadNand32: + +; MIPS32-ANY: lw $[[R0:[0-9]+]], %got(x) +; MIPS64-ANY: ld $[[R0:[0-9]+]], %got_disp(x)( + +; ALL: $[[BB0:[A-Z_0-9]+]]: +; ALL: ll $[[R1:[0-9]+]], 0($[[R0]]) +; ALL: and $[[R3:[0-9]+]], $[[R1]], $4 +; ALL: nor $[[R2:[0-9]+]], $zero, $[[R3]] +; ALL: sc $[[R2]], 0($[[R0]]) +; ALL: beqz $[[R2]], $[[BB0]] } define i32 @AtomicSwap32(i32 %newval) nounwind { @@ -57,19 +55,15 @@ entry: %0 = atomicrmw xchg i32* @x, i32 %tmp monotonic ret i32 %0 -; CHECK-EL-LABEL: AtomicSwap32: -; CHECK-EL: lw $[[R0:[0-9]+]], %got(x) -; CHECK-EL: $[[BB0:[A-Z_0-9]+]]: -; CHECK-EL: ll ${{[0-9]+}}, 0($[[R0]]) -; CHECK-EL: sc $[[R2:[0-9]+]], 0($[[R0]]) -; CHECK-EL: beqz $[[R2]], $[[BB0]] - -; CHECK-EB-LABEL: AtomicSwap32: -; CHECK-EB: lw $[[R0:[0-9]+]], %got(x) -; CHECK-EB: $[[BB0:[A-Z_0-9]+]]: -; CHECK-EB: ll ${{[0-9]+}}, 0($[[R0]]) -; CHECK-EB: sc $[[R2:[0-9]+]], 0($[[R0]]) -; CHECK-EB: beqz $[[R2]], $[[BB0]] +; ALL-LABEL: AtomicSwap32: + +; MIPS32-ANY: lw $[[R0:[0-9]+]], %got(x) +; MIPS64-ANY: ld $[[R0:[0-9]+]], %got_disp(x) + +; ALL: $[[BB0:[A-Z_0-9]+]]: +; ALL: ll ${{[0-9]+}}, 0($[[R0]]) +; ALL: sc $[[R2:[0-9]+]], 0($[[R0]]) +; ALL: beqz $[[R2]], $[[BB0]] } define i32 @AtomicCmpSwap32(i32 %oldval, i32 %newval) nounwind { @@ -78,25 +72,20 @@ entry: store i32 %newval, i32* %newval.addr, align 4 %tmp = load i32* %newval.addr, align 4 %0 = cmpxchg i32* @x, i32 %oldval, i32 %tmp monotonic monotonic - ret i32 %0 + %1 = extractvalue { i32, i1 } %0, 0 + ret i32 %1 + +; ALL-LABEL: AtomicCmpSwap32: -; CHECK-EL-LABEL: AtomicCmpSwap32: -; CHECK-EL: lw $[[R0:[0-9]+]], %got(x) -; CHECK-EL: $[[BB0:[A-Z_0-9]+]]: -; CHECK-EL: ll $2, 0($[[R0]]) -; CHECK-EL: bne $2, $4, $[[BB1:[A-Z_0-9]+]] -; CHECK-EL: sc $[[R2:[0-9]+]], 0($[[R0]]) -; CHECK-EL: beqz $[[R2]], $[[BB0]] -; CHECK-EL: $[[BB1]]: - -; CHECK-EB-LABEL: AtomicCmpSwap32: -; CHECK-EB: lw $[[R0:[0-9]+]], %got(x) -; CHECK-EB: $[[BB0:[A-Z_0-9]+]]: -; CHECK-EB: ll $2, 0($[[R0]]) -; CHECK-EB: bne $2, $4, $[[BB1:[A-Z_0-9]+]] -; CHECK-EB: sc $[[R2:[0-9]+]], 0($[[R0]]) -; CHECK-EB: beqz $[[R2]], $[[BB0]] -; CHECK-EB: $[[BB1]]: +; MIPS32-ANY: lw $[[R0:[0-9]+]], %got(x) +; MIPS64-ANY: ld $[[R0:[0-9]+]], %got_disp(x)( + +; ALL: $[[BB0:[A-Z_0-9]+]]: +; ALL: ll $2, 0($[[R0]]) +; ALL: bne $2, $4, $[[BB1:[A-Z_0-9]+]] +; ALL: sc $[[R2:[0-9]+]], 0($[[R0]]) +; ALL: beqz $[[R2]], $[[BB0]] +; ALL: $[[BB1]]: } @@ -108,56 +97,38 @@ entry: %0 = atomicrmw add i8* @y, i8 %incr monotonic ret i8 %0 -; CHECK-EL-LABEL: AtomicLoadAdd8: -; CHECK-EL: lw $[[R0:[0-9]+]], %got(y) -; CHECK-EL: addiu $[[R1:[0-9]+]], $zero, -4 -; CHECK-EL: and $[[R2:[0-9]+]], $[[R0]], $[[R1]] -; CHECK-EL: andi $[[R3:[0-9]+]], $[[R0]], 3 -; CHECK-EL: sll $[[R4:[0-9]+]], $[[R3]], 3 -; CHECK-EL: ori $[[R5:[0-9]+]], $zero, 255 -; CHECK-EL: sllv $[[R6:[0-9]+]], $[[R5]], $[[R4]] -; CHECK-EL: nor $[[R7:[0-9]+]], $zero, $[[R6]] -; CHECK-EL: sllv $[[R9:[0-9]+]], $4, $[[R4]] - -; CHECK-EL: $[[BB0:[A-Z_0-9]+]]: -; CHECK-EL: ll $[[R10:[0-9]+]], 0($[[R2]]) -; CHECK-EL: addu $[[R11:[0-9]+]], $[[R10]], $[[R9]] -; CHECK-EL: and $[[R12:[0-9]+]], $[[R11]], $[[R6]] -; CHECK-EL: and $[[R13:[0-9]+]], $[[R10]], $[[R7]] -; CHECK-EL: or $[[R14:[0-9]+]], $[[R13]], $[[R12]] -; CHECK-EL: sc $[[R14]], 0($[[R2]]) -; CHECK-EL: beqz $[[R14]], $[[BB0]] - -; CHECK-EL: and $[[R15:[0-9]+]], $[[R10]], $[[R6]] -; CHECK-EL: srlv $[[R16:[0-9]+]], $[[R15]], $[[R4]] -; CHECK-EL: sll $[[R17:[0-9]+]], $[[R16]], 24 -; CHECK-EL: sra $2, $[[R17]], 24 - -; CHECK-EB-LABEL: AtomicLoadAdd8: -; CHECK-EB: lw $[[R0:[0-9]+]], %got(y) -; CHECK-EB: addiu $[[R1:[0-9]+]], $zero, -4 -; CHECK-EB: and $[[R2:[0-9]+]], $[[R0]], $[[R1]] -; CHECK-EB: andi $[[R3:[0-9]+]], $[[R0]], 3 -; CHECK-EB: xori $[[R4:[0-9]+]], $[[R3]], 3 -; CHECK-EB: sll $[[R5:[0-9]+]], $[[R4]], 3 -; CHECK-EB: ori $[[R6:[0-9]+]], $zero, 255 -; CHECK-EB: sllv $[[R7:[0-9]+]], $[[R6]], $[[R5]] -; CHECK-EB: nor $[[R8:[0-9]+]], $zero, $[[R7]] -; CHECK-EB: sllv $[[R9:[0-9]+]], $4, $[[R5]] - -; CHECK-EB: $[[BB0:[A-Z_0-9]+]]: -; CHECK-EB: ll $[[R10:[0-9]+]], 0($[[R2]]) -; CHECK-EB: addu $[[R11:[0-9]+]], $[[R10]], $[[R9]] -; CHECK-EB: and $[[R12:[0-9]+]], $[[R11]], $[[R7]] -; CHECK-EB: and $[[R13:[0-9]+]], $[[R10]], $[[R8]] -; CHECK-EB: or $[[R14:[0-9]+]], $[[R13]], $[[R12]] -; CHECK-EB: sc $[[R14]], 0($[[R2]]) -; CHECK-EB: beqz $[[R14]], $[[BB0]] - -; CHECK-EB: and $[[R15:[0-9]+]], $[[R10]], $[[R7]] -; CHECK-EB: srlv $[[R16:[0-9]+]], $[[R15]], $[[R5]] -; CHECK-EB: sll $[[R17:[0-9]+]], $[[R16]], 24 -; CHECK-EB: sra $2, $[[R17]], 24 +; ALL-LABEL: AtomicLoadAdd8: + +; MIPS32-ANY: lw $[[R0:[0-9]+]], %got(y) +; MIPS64-ANY: ld $[[R0:[0-9]+]], %got_disp(y)( + +; ALL: addiu $[[R1:[0-9]+]], $zero, -4 +; ALL: and $[[R2:[0-9]+]], $[[R0]], $[[R1]] +; ALL: andi $[[R3:[0-9]+]], $[[R0]], 3 +; CHECK-EB: xori $[[R4:[0-9]+]], $[[R3]], 3 +; CHECK-EB: sll $[[R5:[0-9]+]], $[[R4]], 3 +; CHECK-EL: sll $[[R5:[0-9]+]], $[[R3]], 3 +; ALL: ori $[[R6:[0-9]+]], $zero, 255 +; ALL: sllv $[[R7:[0-9]+]], $[[R6]], $[[R5]] +; ALL: nor $[[R8:[0-9]+]], $zero, $[[R7]] +; ALL: sllv $[[R9:[0-9]+]], $4, $[[R5]] + +; ALL: $[[BB0:[A-Z_0-9]+]]: +; ALL: ll $[[R10:[0-9]+]], 0($[[R2]]) +; ALL: addu $[[R11:[0-9]+]], $[[R10]], $[[R9]] +; ALL: and $[[R12:[0-9]+]], $[[R11]], $[[R7]] +; ALL: and $[[R13:[0-9]+]], $[[R10]], $[[R8]] +; ALL: or $[[R14:[0-9]+]], $[[R13]], $[[R12]] +; ALL: sc $[[R14]], 0($[[R2]]) +; ALL: beqz $[[R14]], $[[BB0]] + +; ALL: and $[[R15:[0-9]+]], $[[R10]], $[[R7]] +; ALL: srlv $[[R16:[0-9]+]], $[[R15]], $[[R5]] + +; NO-SEB-SEH: sll $[[R17:[0-9]+]], $[[R16]], 24 +; NO-SEB-SEH: sra $2, $[[R17]], 24 + +; HAS-SEB-SEH: seb $2, $[[R16]] } define signext i8 @AtomicLoadSub8(i8 signext %incr) nounwind { @@ -165,56 +136,38 @@ entry: %0 = atomicrmw sub i8* @y, i8 %incr monotonic ret i8 %0 -; CHECK-EL-LABEL: AtomicLoadSub8: -; CHECK-EL: lw $[[R0:[0-9]+]], %got(y) -; CHECK-EL: addiu $[[R1:[0-9]+]], $zero, -4 -; CHECK-EL: and $[[R2:[0-9]+]], $[[R0]], $[[R1]] -; CHECK-EL: andi $[[R3:[0-9]+]], $[[R0]], 3 -; CHECK-EL: sll $[[R4:[0-9]+]], $[[R3]], 3 -; CHECK-EL: ori $[[R5:[0-9]+]], $zero, 255 -; CHECK-EL: sllv $[[R6:[0-9]+]], $[[R5]], $[[R4]] -; CHECK-EL: nor $[[R7:[0-9]+]], $zero, $[[R6]] -; CHECK-EL: sllv $[[R9:[0-9]+]], $4, $[[R4]] - -; CHECK-EL: $[[BB0:[A-Z_0-9]+]]: -; CHECK-EL: ll $[[R10:[0-9]+]], 0($[[R2]]) -; CHECK-EL: subu $[[R11:[0-9]+]], $[[R10]], $[[R9]] -; CHECK-EL: and $[[R12:[0-9]+]], $[[R11]], $[[R6]] -; CHECK-EL: and $[[R13:[0-9]+]], $[[R10]], $[[R7]] -; CHECK-EL: or $[[R14:[0-9]+]], $[[R13]], $[[R12]] -; CHECK-EL: sc $[[R14]], 0($[[R2]]) -; CHECK-EL: beqz $[[R14]], $[[BB0]] - -; CHECK-EL: and $[[R15:[0-9]+]], $[[R10]], $[[R6]] -; CHECK-EL: srlv $[[R16:[0-9]+]], $[[R15]], $[[R4]] -; CHECK-EL: sll $[[R17:[0-9]+]], $[[R16]], 24 -; CHECK-EL: sra $2, $[[R17]], 24 - -; CHECK-EB-LABEL: AtomicLoadSub8: -; CHECK-EB: lw $[[R0:[0-9]+]], %got(y) -; CHECK-EB: addiu $[[R1:[0-9]+]], $zero, -4 -; CHECK-EB: and $[[R2:[0-9]+]], $[[R0]], $[[R1]] -; CHECK-EB: andi $[[R3:[0-9]+]], $[[R0]], 3 +; ALL-LABEL: AtomicLoadSub8: + +; MIPS32-ANY: lw $[[R0:[0-9]+]], %got(y) +; MIPS64-ANY: ld $[[R0:[0-9]+]], %got_disp(y)( + +; ALL: addiu $[[R1:[0-9]+]], $zero, -4 +; ALL: and $[[R2:[0-9]+]], $[[R0]], $[[R1]] +; ALL: andi $[[R3:[0-9]+]], $[[R0]], 3 +; CHECK-EL: sll $[[R5:[0-9]+]], $[[R3]], 3 ; CHECK-EB: xori $[[R4:[0-9]+]], $[[R3]], 3 ; CHECK-EB: sll $[[R5:[0-9]+]], $[[R4]], 3 -; CHECK-EB: ori $[[R6:[0-9]+]], $zero, 255 -; CHECK-EB: sllv $[[R7:[0-9]+]], $[[R6]], $[[R5]] -; CHECK-EB: nor $[[R8:[0-9]+]], $zero, $[[R7]] -; CHECK-EB: sllv $[[R9:[0-9]+]], $4, $[[R5]] - -; CHECK-EB: $[[BB0:[A-Z_0-9]+]]: -; CHECK-EB: ll $[[R10:[0-9]+]], 0($[[R2]]) -; CHECK-EB: subu $[[R11:[0-9]+]], $[[R10]], $[[R9]] -; CHECK-EB: and $[[R12:[0-9]+]], $[[R11]], $[[R7]] -; CHECK-EB: and $[[R13:[0-9]+]], $[[R10]], $[[R8]] -; CHECK-EB: or $[[R14:[0-9]+]], $[[R13]], $[[R12]] -; CHECK-EB: sc $[[R14]], 0($[[R2]]) -; CHECK-EB: beqz $[[R14]], $[[BB0]] - -; CHECK-EB: and $[[R15:[0-9]+]], $[[R10]], $[[R7]] -; CHECK-EB: srlv $[[R16:[0-9]+]], $[[R15]], $[[R5]] -; CHECK-EB: sll $[[R17:[0-9]+]], $[[R16]], 24 -; CHECK-EB: sra $2, $[[R17]], 24 +; ALL: ori $[[R6:[0-9]+]], $zero, 255 +; ALL: sllv $[[R7:[0-9]+]], $[[R6]], $[[R5]] +; ALL: nor $[[R8:[0-9]+]], $zero, $[[R7]] +; ALL: sllv $[[R9:[0-9]+]], $4, $[[R5]] + +; ALL: $[[BB0:[A-Z_0-9]+]]: +; ALL: ll $[[R10:[0-9]+]], 0($[[R2]]) +; ALL: subu $[[R11:[0-9]+]], $[[R10]], $[[R9]] +; ALL: and $[[R12:[0-9]+]], $[[R11]], $[[R7]] +; ALL: and $[[R13:[0-9]+]], $[[R10]], $[[R8]] +; ALL: or $[[R14:[0-9]+]], $[[R13]], $[[R12]] +; ALL: sc $[[R14]], 0($[[R2]]) +; ALL: beqz $[[R14]], $[[BB0]] + +; ALL: and $[[R15:[0-9]+]], $[[R10]], $[[R7]] +; ALL: srlv $[[R16:[0-9]+]], $[[R15]], $[[R5]] + +; NO-SEB-SEH: sll $[[R17:[0-9]+]], $[[R16]], 24 +; NO-SEB-SEH: sra $2, $[[R17]], 24 + +; HAS-SEB-SEH:seb $2, $[[R16]] } define signext i8 @AtomicLoadNand8(i8 signext %incr) nounwind { @@ -222,58 +175,39 @@ entry: %0 = atomicrmw nand i8* @y, i8 %incr monotonic ret i8 %0 -; CHECK-EL-LABEL: AtomicLoadNand8: -; CHECK-EL: lw $[[R0:[0-9]+]], %got(y) -; CHECK-EL: addiu $[[R1:[0-9]+]], $zero, -4 -; CHECK-EL: and $[[R2:[0-9]+]], $[[R0]], $[[R1]] -; CHECK-EL: andi $[[R3:[0-9]+]], $[[R0]], 3 -; CHECK-EL: sll $[[R4:[0-9]+]], $[[R3]], 3 -; CHECK-EL: ori $[[R5:[0-9]+]], $zero, 255 -; CHECK-EL: sllv $[[R6:[0-9]+]], $[[R5]], $[[R4]] -; CHECK-EL: nor $[[R7:[0-9]+]], $zero, $[[R6]] -; CHECK-EL: sllv $[[R9:[0-9]+]], $4, $[[R4]] - -; CHECK-EL: $[[BB0:[A-Z_0-9]+]]: -; CHECK-EL: ll $[[R10:[0-9]+]], 0($[[R2]]) -; CHECK-EL: and $[[R18:[0-9]+]], $[[R10]], $[[R9]] -; CHECK-EL: nor $[[R11:[0-9]+]], $zero, $[[R18]] -; CHECK-EL: and $[[R12:[0-9]+]], $[[R11]], $[[R6]] -; CHECK-EL: and $[[R13:[0-9]+]], $[[R10]], $[[R7]] -; CHECK-EL: or $[[R14:[0-9]+]], $[[R13]], $[[R12]] -; CHECK-EL: sc $[[R14]], 0($[[R2]]) -; CHECK-EL: beqz $[[R14]], $[[BB0]] - -; CHECK-EL: and $[[R15:[0-9]+]], $[[R10]], $[[R6]] -; CHECK-EL: srlv $[[R16:[0-9]+]], $[[R15]], $[[R4]] -; CHECK-EL: sll $[[R17:[0-9]+]], $[[R16]], 24 -; CHECK-EL: sra $2, $[[R17]], 24 - -; CHECK-EB-LABEL: AtomicLoadNand8: -; CHECK-EB: lw $[[R0:[0-9]+]], %got(y) -; CHECK-EB: addiu $[[R1:[0-9]+]], $zero, -4 -; CHECK-EB: and $[[R2:[0-9]+]], $[[R0]], $[[R1]] -; CHECK-EB: andi $[[R3:[0-9]+]], $[[R0]], 3 -; CHECK-EB: xori $[[R4:[0-9]+]], $[[R3]], 3 -; CHECK-EB: sll $[[R5:[0-9]+]], $[[R4]], 3 -; CHECK-EB: ori $[[R6:[0-9]+]], $zero, 255 -; CHECK-EB: sllv $[[R7:[0-9]+]], $[[R6]], $[[R5]] -; CHECK-EB: nor $[[R8:[0-9]+]], $zero, $[[R7]] -; CHECK-EB: sllv $[[R9:[0-9]+]], $4, $[[R5]] - -; CHECK-EB: $[[BB0:[A-Z_0-9]+]]: -; CHECK-EB: ll $[[R10:[0-9]+]], 0($[[R2]]) -; CHECK-EB: and $[[R18:[0-9]+]], $[[R10]], $[[R9]] -; CHECK-EB: nor $[[R11:[0-9]+]], $zero, $[[R18]] -; CHECK-EB: and $[[R12:[0-9]+]], $[[R11]], $[[R7]] -; CHECK-EB: and $[[R13:[0-9]+]], $[[R10]], $[[R8]] -; CHECK-EB: or $[[R14:[0-9]+]], $[[R13]], $[[R12]] -; CHECK-EB: sc $[[R14]], 0($[[R2]]) -; CHECK-EB: beqz $[[R14]], $[[BB0]] - -; CHECK-EB: and $[[R15:[0-9]+]], $[[R10]], $[[R7]] -; CHECK-EB: srlv $[[R16:[0-9]+]], $[[R15]], $[[R5]] -; CHECK-EB: sll $[[R17:[0-9]+]], $[[R16]], 24 -; CHECK-EB: sra $2, $[[R17]], 24 +; ALL-LABEL: AtomicLoadNand8: + +; MIPS32-ANY: lw $[[R0:[0-9]+]], %got(y) +; MIPS64-ANY: ld $[[R0:[0-9]+]], %got_disp(y)( + +; ALL: addiu $[[R1:[0-9]+]], $zero, -4 +; ALL: and $[[R2:[0-9]+]], $[[R0]], $[[R1]] +; ALL: andi $[[R3:[0-9]+]], $[[R0]], 3 +; CHECK-EL: sll $[[R5:[0-9]+]], $[[R3]], 3 +; CHECK-EB: xori $[[R4:[0-9]+]], $[[R3]], 3 +; CHECK-EB: sll $[[R5:[0-9]+]], $[[R4]], 3 +; ALL: ori $[[R6:[0-9]+]], $zero, 255 +; ALL: sllv $[[R7:[0-9]+]], $[[R6]], $[[R5]] +; ALL: nor $[[R8:[0-9]+]], $zero, $[[R7]] +; ALL: sllv $[[R9:[0-9]+]], $4, $[[R5]] + +; ALL: $[[BB0:[A-Z_0-9]+]]: +; ALL: ll $[[R10:[0-9]+]], 0($[[R2]]) +; ALL: and $[[R18:[0-9]+]], $[[R10]], $[[R9]] +; ALL: nor $[[R11:[0-9]+]], $zero, $[[R18]] +; ALL: and $[[R12:[0-9]+]], $[[R11]], $[[R7]] +; ALL: and $[[R13:[0-9]+]], $[[R10]], $[[R8]] +; ALL: or $[[R14:[0-9]+]], $[[R13]], $[[R12]] +; ALL: sc $[[R14]], 0($[[R2]]) +; ALL: beqz $[[R14]], $[[BB0]] + +; ALL: and $[[R15:[0-9]+]], $[[R10]], $[[R7]] +; ALL: srlv $[[R16:[0-9]+]], $[[R15]], $[[R5]] + +; NO-SEB-SEH: sll $[[R17:[0-9]+]], $[[R16]], 24 +; NO-SEB-SEH: sra $2, $[[R17]], 24 + +; HAS-SEB-SEH: seb $2, $[[R16]] } define signext i8 @AtomicSwap8(i8 signext %newval) nounwind { @@ -281,121 +215,126 @@ entry: %0 = atomicrmw xchg i8* @y, i8 %newval monotonic ret i8 %0 -; CHECK-EL-LABEL: AtomicSwap8: -; CHECK-EL: lw $[[R0:[0-9]+]], %got(y) -; CHECK-EL: addiu $[[R1:[0-9]+]], $zero, -4 -; CHECK-EL: and $[[R2:[0-9]+]], $[[R0]], $[[R1]] -; CHECK-EL: andi $[[R3:[0-9]+]], $[[R0]], 3 -; CHECK-EL: sll $[[R4:[0-9]+]], $[[R3]], 3 -; CHECK-EL: ori $[[R5:[0-9]+]], $zero, 255 -; CHECK-EL: sllv $[[R6:[0-9]+]], $[[R5]], $[[R4]] -; CHECK-EL: nor $[[R7:[0-9]+]], $zero, $[[R6]] -; CHECK-EL: sllv $[[R9:[0-9]+]], $4, $[[R4]] - -; CHECK-EL: $[[BB0:[A-Z_0-9]+]]: -; CHECK-EL: ll $[[R10:[0-9]+]], 0($[[R2]]) -; CHECK-EL: and $[[R18:[0-9]+]], $[[R9]], $[[R6]] -; CHECK-EL: and $[[R13:[0-9]+]], $[[R10]], $[[R7]] -; CHECK-EL: or $[[R14:[0-9]+]], $[[R13]], $[[R18]] -; CHECK-EL: sc $[[R14]], 0($[[R2]]) -; CHECK-EL: beqz $[[R14]], $[[BB0]] - -; CHECK-EL: and $[[R15:[0-9]+]], $[[R10]], $[[R6]] -; CHECK-EL: srlv $[[R16:[0-9]+]], $[[R15]], $[[R4]] -; CHECK-EL: sll $[[R17:[0-9]+]], $[[R16]], 24 -; CHECK-EL: sra $2, $[[R17]], 24 - -; CHECK-EB-LABEL: AtomicSwap8: -; CHECK-EB: lw $[[R0:[0-9]+]], %got(y) -; CHECK-EB: addiu $[[R1:[0-9]+]], $zero, -4 -; CHECK-EB: and $[[R2:[0-9]+]], $[[R0]], $[[R1]] -; CHECK-EB: andi $[[R3:[0-9]+]], $[[R0]], 3 -; CHECK-EB: xori $[[R4:[0-9]+]], $[[R3]], 3 -; CHECK-EB: sll $[[R5:[0-9]+]], $[[R4]], 3 -; CHECK-EB: ori $[[R6:[0-9]+]], $zero, 255 -; CHECK-EB: sllv $[[R7:[0-9]+]], $[[R6]], $[[R5]] -; CHECK-EB: nor $[[R8:[0-9]+]], $zero, $[[R7]] -; CHECK-EB: sllv $[[R9:[0-9]+]], $4, $[[R5]] - -; CHECK-EB: $[[BB0:[A-Z_0-9]+]]: -; CHECK-EB: ll $[[R10:[0-9]+]], 0($[[R2]]) -; CHECK-EB: and $[[R18:[0-9]+]], $[[R9]], $[[R7]] -; CHECK-EB: and $[[R13:[0-9]+]], $[[R10]], $[[R8]] -; CHECK-EB: or $[[R14:[0-9]+]], $[[R13]], $[[R18]] -; CHECK-EB: sc $[[R14]], 0($[[R2]]) -; CHECK-EB: beqz $[[R14]], $[[BB0]] - -; CHECK-EB: and $[[R15:[0-9]+]], $[[R10]], $[[R7]] -; CHECK-EB: srlv $[[R16:[0-9]+]], $[[R15]], $[[R5]] -; CHECK-EB: sll $[[R17:[0-9]+]], $[[R16]], 24 -; CHECK-EB: sra $2, $[[R17]], 24 +; ALL-LABEL: AtomicSwap8: + +; MIPS32-ANY: lw $[[R0:[0-9]+]], %got(y) +; MIPS64-ANY: ld $[[R0:[0-9]+]], %got_disp(y)( + +; ALL: addiu $[[R1:[0-9]+]], $zero, -4 +; ALL: and $[[R2:[0-9]+]], $[[R0]], $[[R1]] +; ALL: andi $[[R3:[0-9]+]], $[[R0]], 3 +; CHECK-EL: sll $[[R5:[0-9]+]], $[[R3]], 3 +; CHECK-EB: xori $[[R4:[0-9]+]], $[[R3]], 3 +; CHECK-EB: sll $[[R5:[0-9]+]], $[[R4]], 3 +; ALL: ori $[[R6:[0-9]+]], $zero, 255 +; ALL: sllv $[[R7:[0-9]+]], $[[R6]], $[[R5]] +; ALL: nor $[[R8:[0-9]+]], $zero, $[[R7]] +; ALL: sllv $[[R9:[0-9]+]], $4, $[[R5]] + +; ALL: $[[BB0:[A-Z_0-9]+]]: +; ALL: ll $[[R10:[0-9]+]], 0($[[R2]]) +; ALL: and $[[R18:[0-9]+]], $[[R9]], $[[R7]] +; ALL: and $[[R13:[0-9]+]], $[[R10]], $[[R8]] +; ALL: or $[[R14:[0-9]+]], $[[R13]], $[[R18]] +; ALL: sc $[[R14]], 0($[[R2]]) +; ALL: beqz $[[R14]], $[[BB0]] + +; ALL: and $[[R15:[0-9]+]], $[[R10]], $[[R7]] +; ALL: srlv $[[R16:[0-9]+]], $[[R15]], $[[R5]] + +; NO-SEB-SEH: sll $[[R17:[0-9]+]], $[[R16]], 24 +; NO-SEB-SEH: sra $2, $[[R17]], 24 + +; HAS-SEB-SEH: seb $2, $[[R16]] } define signext i8 @AtomicCmpSwap8(i8 signext %oldval, i8 signext %newval) nounwind { entry: - %0 = cmpxchg i8* @y, i8 %oldval, i8 %newval monotonic monotonic + %pair0 = cmpxchg i8* @y, i8 %oldval, i8 %newval monotonic monotonic + %0 = extractvalue { i8, i1 } %pair0, 0 ret i8 %0 -; CHECK-EL-LABEL: AtomicCmpSwap8: -; CHECK-EL: lw $[[R0:[0-9]+]], %got(y) -; CHECK-EL: addiu $[[R1:[0-9]+]], $zero, -4 -; CHECK-EL: and $[[R2:[0-9]+]], $[[R0]], $[[R1]] -; CHECK-EL: andi $[[R3:[0-9]+]], $[[R0]], 3 -; CHECK-EL: sll $[[R4:[0-9]+]], $[[R3]], 3 -; CHECK-EL: ori $[[R5:[0-9]+]], $zero, 255 -; CHECK-EL: sllv $[[R6:[0-9]+]], $[[R5]], $[[R4]] -; CHECK-EL: nor $[[R7:[0-9]+]], $zero, $[[R6]] -; CHECK-EL: andi $[[R8:[0-9]+]], $4, 255 -; CHECK-EL: sllv $[[R9:[0-9]+]], $[[R8]], $[[R4]] -; CHECK-EL: andi $[[R10:[0-9]+]], $5, 255 -; CHECK-EL: sllv $[[R11:[0-9]+]], $[[R10]], $[[R4]] - -; CHECK-EL: $[[BB0:[A-Z_0-9]+]]: -; CHECK-EL: ll $[[R12:[0-9]+]], 0($[[R2]]) -; CHECK-EL: and $[[R13:[0-9]+]], $[[R12]], $[[R6]] -; CHECK-EL: bne $[[R13]], $[[R9]], $[[BB1:[A-Z_0-9]+]] - -; CHECK-EL: and $[[R14:[0-9]+]], $[[R12]], $[[R7]] -; CHECK-EL: or $[[R15:[0-9]+]], $[[R14]], $[[R11]] -; CHECK-EL: sc $[[R15]], 0($[[R2]]) -; CHECK-EL: beqz $[[R15]], $[[BB0]] - -; CHECK-EL: $[[BB1]]: -; CHECK-EL: srlv $[[R16:[0-9]+]], $[[R13]], $[[R4]] -; CHECK-EL: sll $[[R17:[0-9]+]], $[[R16]], 24 -; CHECK-EL: sra $2, $[[R17]], 24 - -; CHECK-EB-LABEL: AtomicCmpSwap8: -; CHECK-EB: lw $[[R0:[0-9]+]], %got(y) -; CHECK-EB: addiu $[[R1:[0-9]+]], $zero, -4 -; CHECK-EB: and $[[R2:[0-9]+]], $[[R0]], $[[R1]] -; CHECK-EB: andi $[[R3:[0-9]+]], $[[R0]], 3 -; CHECK-EB: xori $[[R4:[0-9]+]], $[[R3]], 3 -; CHECK-EB: sll $[[R5:[0-9]+]], $[[R4]], 3 -; CHECK-EB: ori $[[R6:[0-9]+]], $zero, 255 -; CHECK-EB: sllv $[[R7:[0-9]+]], $[[R6]], $[[R5]] -; CHECK-EB: nor $[[R8:[0-9]+]], $zero, $[[R7]] -; CHECK-EB: andi $[[R9:[0-9]+]], $4, 255 -; CHECK-EB: sllv $[[R10:[0-9]+]], $[[R9]], $[[R5]] -; CHECK-EB: andi $[[R11:[0-9]+]], $5, 255 -; CHECK-EB: sllv $[[R12:[0-9]+]], $[[R11]], $[[R5]] - -; CHECK-EB: $[[BB0:[A-Z_0-9]+]]: -; CHECK-EB: ll $[[R13:[0-9]+]], 0($[[R2]]) -; CHECK-EB: and $[[R14:[0-9]+]], $[[R13]], $[[R7]] -; CHECK-EB: bne $[[R14]], $[[R10]], $[[BB1:[A-Z_0-9]+]] - -; CHECK-EB: and $[[R15:[0-9]+]], $[[R13]], $[[R8]] -; CHECK-EB: or $[[R16:[0-9]+]], $[[R15]], $[[R12]] -; CHECK-EB: sc $[[R16]], 0($[[R2]]) -; CHECK-EB: beqz $[[R16]], $[[BB0]] - -; CHECK-EB: $[[BB1]]: -; CHECK-EB: srlv $[[R17:[0-9]+]], $[[R14]], $[[R5]] -; CHECK-EB: sll $[[R18:[0-9]+]], $[[R17]], 24 -; CHECK-EB: sra $2, $[[R18]], 24 +; ALL-LABEL: AtomicCmpSwap8: + +; MIPS32-ANY: lw $[[R0:[0-9]+]], %got(y) +; MIPS64-ANY: ld $[[R0:[0-9]+]], %got_disp(y)( + +; ALL: addiu $[[R1:[0-9]+]], $zero, -4 +; ALL: and $[[R2:[0-9]+]], $[[R0]], $[[R1]] +; ALL: andi $[[R3:[0-9]+]], $[[R0]], 3 +; CHECK-EL: sll $[[R5:[0-9]+]], $[[R3]], 3 +; CHECK-EB: xori $[[R4:[0-9]+]], $[[R3]], 3 +; CHECK-EB: sll $[[R5:[0-9]+]], $[[R4]], 3 +; ALL: ori $[[R6:[0-9]+]], $zero, 255 +; ALL: sllv $[[R7:[0-9]+]], $[[R6]], $[[R5]] +; ALL: nor $[[R8:[0-9]+]], $zero, $[[R7]] +; ALL: andi $[[R9:[0-9]+]], $4, 255 +; ALL: sllv $[[R10:[0-9]+]], $[[R9]], $[[R5]] +; ALL: andi $[[R11:[0-9]+]], $5, 255 +; ALL: sllv $[[R12:[0-9]+]], $[[R11]], $[[R5]] + +; ALL: $[[BB0:[A-Z_0-9]+]]: +; ALL: ll $[[R13:[0-9]+]], 0($[[R2]]) +; ALL: and $[[R14:[0-9]+]], $[[R13]], $[[R7]] +; ALL: bne $[[R14]], $[[R10]], $[[BB1:[A-Z_0-9]+]] + +; ALL: and $[[R15:[0-9]+]], $[[R13]], $[[R8]] +; ALL: or $[[R16:[0-9]+]], $[[R15]], $[[R12]] +; ALL: sc $[[R16]], 0($[[R2]]) +; ALL: beqz $[[R16]], $[[BB0]] + +; ALL: $[[BB1]]: +; ALL: srlv $[[R17:[0-9]+]], $[[R14]], $[[R5]] + +; NO-SEB-SEH: sll $[[R18:[0-9]+]], $[[R17]], 24 +; NO-SEB-SEH: sra $2, $[[R18]], 24 + +; HAS-SEB-SEH: seb $2, $[[R17]] +} + +; Check one i16 so that we cover the seh sign extend +@z = common global i16 0, align 1 + +define signext i16 @AtomicLoadAdd16(i16 signext %incr) nounwind { +entry: + %0 = atomicrmw add i16* @z, i16 %incr monotonic + ret i16 %0 + +; ALL-LABEL: AtomicLoadAdd16: + +; MIPS32-ANY: lw $[[R0:[0-9]+]], %got(z) +; MIPS64-ANY: ld $[[R0:[0-9]+]], %got_disp(z)( + +; ALL: addiu $[[R1:[0-9]+]], $zero, -4 +; ALL: and $[[R2:[0-9]+]], $[[R0]], $[[R1]] +; ALL: andi $[[R3:[0-9]+]], $[[R0]], 3 +; CHECK-EB: xori $[[R4:[0-9]+]], $[[R3]], 2 +; CHECK-EB: sll $[[R5:[0-9]+]], $[[R4]], 3 +; CHECK-EL: sll $[[R5:[0-9]+]], $[[R3]], 3 +; ALL: ori $[[R6:[0-9]+]], $zero, 65535 +; ALL: sllv $[[R7:[0-9]+]], $[[R6]], $[[R5]] +; ALL: nor $[[R8:[0-9]+]], $zero, $[[R7]] +; ALL: sllv $[[R9:[0-9]+]], $4, $[[R5]] + +; ALL: $[[BB0:[A-Z_0-9]+]]: +; ALL: ll $[[R10:[0-9]+]], 0($[[R2]]) +; ALL: addu $[[R11:[0-9]+]], $[[R10]], $[[R9]] +; ALL: and $[[R12:[0-9]+]], $[[R11]], $[[R7]] +; ALL: and $[[R13:[0-9]+]], $[[R10]], $[[R8]] +; ALL: or $[[R14:[0-9]+]], $[[R13]], $[[R12]] +; ALL: sc $[[R14]], 0($[[R2]]) +; ALL: beqz $[[R14]], $[[BB0]] + +; ALL: and $[[R15:[0-9]+]], $[[R10]], $[[R7]] +; ALL: srlv $[[R16:[0-9]+]], $[[R15]], $[[R5]] + +; NO-SEB-SEH: sll $[[R17:[0-9]+]], $[[R16]], 16 +; NO-SEB-SEH: sra $2, $[[R17]], 16 + +; MIPS32R2: seh $2, $[[R16]] } + @countsint = common global i32 0, align 4 define i32 @CheckSync(i32 %v) nounwind noinline { @@ -403,19 +342,13 @@ entry: %0 = atomicrmw add i32* @countsint, i32 %v seq_cst ret i32 %0 -; CHECK-EL-LABEL: CheckSync: -; CHECK-EL: sync 0 -; CHECK-EL: ll -; CHECK-EL: sc -; CHECK-EL: beq -; CHECK-EL: sync 0 - -; CHECK-EB-LABEL: CheckSync: -; CHECK-EB: sync 0 -; CHECK-EB: ll -; CHECK-EB: sc -; CHECK-EB: beq -; CHECK-EB: sync 0 +; ALL-LABEL: CheckSync: + +; ALL: sync +; ALL: ll +; ALL: sc +; ALL: beq +; ALL: sync } ; make sure that this assertion in @@ -429,8 +362,29 @@ entry: define i32 @zeroreg() nounwind { entry: - %0 = cmpxchg i32* @a, i32 1, i32 0 seq_cst seq_cst + %pair0 = cmpxchg i32* @a, i32 1, i32 0 seq_cst seq_cst + %0 = extractvalue { i32, i1 } %pair0, 0 %1 = icmp eq i32 %0, 1 %conv = zext i1 %1 to i32 ret i32 %conv } + +; Check that MIPS32R6 has the correct offset range. +; FIXME: At the moment, we don't seem to do addr+offset for any atomic load/store. +define i32 @AtomicLoadAdd32_OffGt9Bit(i32 %incr) nounwind { +entry: + %0 = atomicrmw add i32* getelementptr(i32* @x, i32 256), i32 %incr monotonic + ret i32 %0 + +; ALL-LABEL: AtomicLoadAdd32_OffGt9Bit: + +; MIPS32-ANY: lw $[[R0:[0-9]+]], %got(x) +; MIPS64-ANY: ld $[[R0:[0-9]+]], %got_disp(x)( + +; ALL: addiu $[[PTR:[0-9]+]], $[[R0]], 1024 +; ALL: $[[BB0:[A-Z_0-9]+]]: +; ALL: ll $[[R1:[0-9]+]], 0($[[PTR]]) +; ALL: addu $[[R2:[0-9]+]], $[[R1]], $4 +; ALL: sc $[[R2]], 0($[[PTR]]) +; ALL: beqz $[[R2]], $[[BB0]] +} diff --git a/test/CodeGen/Mips/atomicops.ll b/test/CodeGen/Mips/atomicops.ll index dc07c63..c264152 100644 --- a/test/CodeGen/Mips/atomicops.ll +++ b/test/CodeGen/Mips/atomicops.ll @@ -20,7 +20,8 @@ entry: %add.i = add nsw i32 %0, 2 %1 = load volatile i32* %x, align 4 %call1 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([8 x i8]* @.str, i32 0, i32 0), i32 %add.i, i32 %1) nounwind - %2 = cmpxchg i32* %x, i32 1, i32 2 seq_cst seq_cst + %pair = cmpxchg i32* %x, i32 1, i32 2 seq_cst seq_cst + %2 = extractvalue { i32, i1 } %pair, 0 %3 = load volatile i32* %x, align 4 %call2 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([8 x i8]* @.str, i32 0, i32 0), i32 %2, i32 %3) nounwind %4 = atomicrmw xchg i32* %x, i32 1 seq_cst diff --git a/test/CodeGen/Mips/buildpairextractelementf64.ll b/test/CodeGen/Mips/buildpairextractelementf64.ll index b9bf2b6..88d1d07 100644 --- a/test/CodeGen/Mips/buildpairextractelementf64.ll +++ b/test/CodeGen/Mips/buildpairextractelementf64.ll @@ -1,7 +1,7 @@ ; RUN: llc -march=mipsel < %s | FileCheck %s -check-prefix=FP32 -check-prefix=CHECK ; RUN: llc -march=mips < %s | FileCheck %s -check-prefix=FP32 -check-prefix=CHECK -; RUN: llc -march=mipsel -mattr=+fp64 < %s | FileCheck %s -check-prefix=FP64 -check-prefix=CHECK -; RUN: llc -march=mips -mattr=+fp64 < %s | FileCheck %s -check-prefix=FP64 -check-prefix=CHECK +; RUN: llc -march=mipsel -mcpu=mips32r2 -mattr=+fp64 < %s | FileCheck %s -check-prefix=FP64 -check-prefix=CHECK +; RUN: llc -march=mips -mcpu=mips32r2 -mattr=+fp64 < %s | FileCheck %s -check-prefix=FP64 -check-prefix=CHECK @a = external global i32 diff --git a/test/CodeGen/Mips/cconv/callee-saved-fpxx.ll b/test/CodeGen/Mips/cconv/callee-saved-fpxx.ll new file mode 100644 index 0000000..4b28b99 --- /dev/null +++ b/test/CodeGen/Mips/cconv/callee-saved-fpxx.ll @@ -0,0 +1,58 @@ +; RUN: llc -march=mips -mattr=+o32,+fpxx < %s | FileCheck --check-prefix=ALL --check-prefix=O32-FPXX %s +; RUN: llc -march=mipsel -mattr=+o32,+fpxx < %s | FileCheck --check-prefix=ALL --check-prefix=O32-FPXX %s +; RUN: llc -march=mips -mattr=+o32,+fpxx < %s | FileCheck --check-prefix=ALL --check-prefix=O32-FPXX-INV %s +; RUN: llc -march=mipsel -mattr=+o32,+fpxx < %s | FileCheck --check-prefix=ALL --check-prefix=O32-FPXX-INV %s + +; RUN-TODO: llc -march=mips64 -mattr=+o32,+fpxx < %s | FileCheck --check-prefix=ALL --check-prefix=O32-FPXX %s +; RUN-TODO: llc -march=mips64el -mattr=+o32,+fpxx < %s | FileCheck --check-prefix=ALL --check-prefix=O32-FPXX %s +; RUN-TODO: llc -march=mips64 -mattr=+o32,+fpxx < %s | FileCheck --check-prefix=ALL --check-prefix=O32-FPXX-INV --check-prefix=O32-FPXX-INV %s +; RUN-TODO: llc -march=mips64el -mattr=+o32,+fpxx < %s | FileCheck --check-prefix=ALL --check-prefix=O32-FPXX-INV --check-prefix=O32-FPXX-INV %s + +define void @fpu_clobber() nounwind { +entry: + call void asm "# Clobber", "~{$f0},~{$f1},~{$f2},~{$f3},~{$f4},~{$f5},~{$f6},~{$f7},~{$f8},~{$f9},~{$f10},~{$f11},~{$f12},~{$f13},~{$f14},~{$f15},~{$f16},~{$f17},~{$f18},~{$f19},~{$f20},~{$f21},~{$f22},~{$f23},~{$f24},~{$f25},~{$f26},~{$f27},~{$f28},~{$f29},~{$f30},~{$f31}"() + ret void +} + +; O32-FPXX-LABEL: fpu_clobber: +; O32-FPXX-INV-NOT: sdc1 $f0, +; O32-FPXX-INV-NOT: sdc1 $f1, +; O32-FPXX-INV-NOT: sdc1 $f2, +; O32-FPXX-INV-NOT: sdc1 $f3, +; O32-FPXX-INV-NOT: sdc1 $f4, +; O32-FPXX-INV-NOT: sdc1 $f5, +; O32-FPXX-INV-NOT: sdc1 $f6, +; O32-FPXX-INV-NOT: sdc1 $f7, +; O32-FPXX-INV-NOT: sdc1 $f8, +; O32-FPXX-INV-NOT: sdc1 $f9, +; O32-FPXX-INV-NOT: sdc1 $f10, +; O32-FPXX-INV-NOT: sdc1 $f11, +; O32-FPXX-INV-NOT: sdc1 $f12, +; O32-FPXX-INV-NOT: sdc1 $f13, +; O32-FPXX-INV-NOT: sdc1 $f14, +; O32-FPXX-INV-NOT: sdc1 $f15, +; O32-FPXX-INV-NOT: sdc1 $f16, +; O32-FPXX-INV-NOT: sdc1 $f17, +; O32-FPXX-INV-NOT: sdc1 $f18, +; O32-FPXX-INV-NOT: sdc1 $f19, +; O32-FPXX-INV-NOT: sdc1 $f21, +; O32-FPXX-INV-NOT: sdc1 $f23, +; O32-FPXX-INV-NOT: sdc1 $f25, +; O32-FPXX-INV-NOT: sdc1 $f27, +; O32-FPXX-INV-NOT: sdc1 $f29, +; O32-FPXX-INV-NOT: sdc1 $f31, + +; O32-FPXX: addiu $sp, $sp, -48 +; O32-FPXX-DAG: sdc1 [[F20:\$f20]], [[OFF20:[0-9]+]]($sp) +; O32-FPXX-DAG: sdc1 [[F22:\$f22]], [[OFF22:[0-9]+]]($sp) +; O32-FPXX-DAG: sdc1 [[F24:\$f24]], [[OFF24:[0-9]+]]($sp) +; O32-FPXX-DAG: sdc1 [[F26:\$f26]], [[OFF26:[0-9]+]]($sp) +; O32-FPXX-DAG: sdc1 [[F28:\$f28]], [[OFF28:[0-9]+]]($sp) +; O32-FPXX-DAG: sdc1 [[F30:\$f30]], [[OFF30:[0-9]+]]($sp) +; O32-FPXX-DAG: ldc1 [[F20]], [[OFF20]]($sp) +; O32-FPXX-DAG: ldc1 [[F22]], [[OFF22]]($sp) +; O32-FPXX-DAG: ldc1 [[F24]], [[OFF24]]($sp) +; O32-FPXX-DAG: ldc1 [[F26]], [[OFF26]]($sp) +; O32-FPXX-DAG: ldc1 [[F28]], [[OFF28]]($sp) +; O32-FPXX-DAG: ldc1 [[F30]], [[OFF30]]($sp) +; O32-FPXX: addiu $sp, $sp, 48 diff --git a/test/CodeGen/Mips/cconv/callee-saved-fpxx1.ll b/test/CodeGen/Mips/cconv/callee-saved-fpxx1.ll new file mode 100644 index 0000000..489879e --- /dev/null +++ b/test/CodeGen/Mips/cconv/callee-saved-fpxx1.ll @@ -0,0 +1,24 @@ +; RUN: llc -march=mips -mattr=+o32,+fp64 < %s | FileCheck --check-prefix=O32-FP64-INV %s +; RUN: llc -march=mipsel -mattr=+o32,+fp64 < %s | FileCheck --check-prefix=O32-FP64-INV %s + +; RUN: llc -march=mips -mattr=+o32,+fpxx < %s | FileCheck --check-prefix=O32-FPXX %s +; RUN: llc -march=mipsel -mattr=+o32,+fpxx < %s | FileCheck --check-prefix=O32-FPXX %s + +; RUN-TODO: llc -march=mips64 -mattr=+o32,+fpxx < %s | FileCheck --check-prefix=O32-FPXX %s +; RUN-TODO: llc -march=mips64el -mattr=+o32,+fpxx < %s | FileCheck --check-prefix=O32-FPXX %s + +define void @fpu_clobber() nounwind { +entry: + call void asm "# Clobber", "~{$f21}"() + ret void +} + +; O32-FPXX-LABEL: fpu_clobber: + +; O32-FPXX: addiu $sp, $sp, -8 + +; O32-FP64-INV-NOT: sdc1 $f20, +; O32-FPXX-DAG: sdc1 [[F20:\$f20]], [[OFF20:[0-9]+]]($sp) +; O32-FPXX-DAG: ldc1 [[F20]], [[OFF20]]($sp) + +; O32-FPXX: addiu $sp, $sp, 8 diff --git a/test/CodeGen/Mips/cmov.ll b/test/CodeGen/Mips/cmov.ll index b9732eb..999bdb4 100644 --- a/test/CodeGen/Mips/cmov.ll +++ b/test/CodeGen/Mips/cmov.ll @@ -1,17 +1,43 @@ -; RUN: llc -march=mips < %s | FileCheck %s -check-prefix=O32 -; RUN: llc -march=mips -regalloc=basic < %s | FileCheck %s -check-prefix=O32 -; RUN: llc -march=mips64el -mcpu=mips4 -mattr=n64 < %s | FileCheck %s -check-prefix=N64 -; RUN: llc -march=mips64el -mcpu=mips64 -mattr=n64 < %s | FileCheck %s -check-prefix=N64 +; RUN: llc -march=mips -mcpu=mips32 < %s | FileCheck %s -check-prefix=ALL -check-prefix=32-CMOV +; RUN: llc -march=mips -mcpu=mips32 -regalloc=basic < %s | FileCheck %s -check-prefix=ALL -check-prefix=32-CMOV +; RUN: llc -march=mips -mcpu=mips32r2 < %s | FileCheck %s -check-prefix=ALL -check-prefix=32-CMOV +; RUN: llc -march=mips -mcpu=mips32r6 < %s | FileCheck %s -check-prefix=ALL -check-prefix=32-CMP +; RUN: llc -march=mips64el -mcpu=mips4 < %s | FileCheck %s -check-prefix=ALL -check-prefix=64-CMOV +; RUN: llc -march=mips64el -mcpu=mips64 < %s | FileCheck %s -check-prefix=ALL -check-prefix=64-CMOV +; RUN: llc -march=mips64el -mcpu=mips64r6 < %s | FileCheck %s -check-prefix=ALL -check-prefix=64-CMP @i1 = global [3 x i32] [i32 1, i32 2, i32 3], align 4 @i3 = common global i32* null, align 4 -; O32-DAG: lw $[[R0:[0-9]+]], %got(i3) -; O32-DAG: addiu $[[R1:[0-9]+]], ${{[0-9]+}}, %got(i1) -; O32: movn $[[R0]], $[[R1]], ${{[0-9]+}} -; N64-DAG: ldr $[[R0:[0-9]+]] -; N64-DAG: ld $[[R1:[0-9]+]], %got_disp(i1) -; N64: movn $[[R0]], $[[R1]], ${{[0-9]+}} +; ALL-LABEL: cmov1: + +; 32-CMOV-DAG: lw $[[R0:[0-9]+]], %got(i3) +; 32-CMOV-DAG: addiu $[[R1:[0-9]+]], ${{[0-9]+}}, %got(i1) +; 32-CMOV-DAG: movn $[[R0]], $[[R1]], $4 +; 32-CMOV-DAG: lw $2, 0($[[R0]]) + +; 32-CMP-DAG: lw $[[R0:[0-9]+]], %got(i3) +; 32-CMP-DAG: addiu $[[R1:[0-9]+]], ${{[0-9]+}}, %got(i1) +; 32-CMP-DAG: selnez $[[T0:[0-9]+]], $[[R1]], $4 +; 32-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[R0]], $4 +; 32-CMP-DAG: or $[[T2:[0-9]+]], $[[T0]], $[[T1]] +; 32-CMP-DAG: lw $2, 0($[[T2]]) + +; 64-CMOV-DAG: ldr $[[R0:[0-9]+]] +; 64-CMOV-DAG: ld $[[R1:[0-9]+]], %got_disp(i1) +; 64-CMOV-DAG: movn $[[R0]], $[[R1]], $4 + +; 64-CMP-DAG: ld $[[R0:[0-9]+]], %got_disp(i3)( +; 64-CMP-DAG: daddiu $[[R1:[0-9]+]], ${{[0-9]+}}, %got_disp(i1) +; FIXME: This sll works around an implementation detail in the code generator +; (setcc's result is i32 so bits 32-63 are undefined). It's not really +; needed. +; 64-CMP-DAG: sll $[[CC:[0-9]+]], $4, 0 +; 64-CMP-DAG: selnez $[[T0:[0-9]+]], $[[R1]], $[[CC]] +; 64-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[R0]], $[[CC]] +; 64-CMP-DAG: or $[[T2:[0-9]+]], $[[T0]], $[[T1]] +; 64-CMP-DAG: ld $2, 0($[[T2]]) + define i32* @cmov1(i32 %s) nounwind readonly { entry: %tobool = icmp ne i32 %s, 0 @@ -23,14 +49,35 @@ entry: @c = global i32 1, align 4 @d = global i32 0, align 4 -; O32-LABEL: cmov2: -; O32: addiu $[[R1:[0-9]+]], ${{[a-z0-9]+}}, %got(d) -; O32: addiu $[[R0:[0-9]+]], ${{[a-z0-9]+}}, %got(c) -; O32: movn $[[R1]], $[[R0]], ${{[0-9]+}} -; N64-LABEL: cmov2: -; N64: daddiu $[[R1:[0-9]+]], ${{[0-9]+}}, %got_disp(d) -; N64: daddiu $[[R0:[0-9]+]], ${{[0-9]+}}, %got_disp(c) -; N64: movn $[[R1]], $[[R0]], ${{[0-9]+}} +; ALL-LABEL: cmov2: + +; 32-CMOV-DAG: addiu $[[R1:[0-9]+]], ${{[0-9]+}}, %got(d) +; 32-CMOV-DAG: addiu $[[R0:[0-9]+]], ${{[0-9]+}}, %got(c) +; 32-CMOV-DAG: movn $[[R1]], $[[R0]], $4 +; 32-CMOV-DAG: lw $2, 0($[[R0]]) + +; 32-CMP-DAG: addiu $[[R1:[0-9]+]], ${{[0-9]+}}, %got(d) +; 32-CMP-DAG: addiu $[[R0:[0-9]+]], ${{[0-9]+}}, %got(c) +; 32-CMP-DAG: selnez $[[T0:[0-9]+]], $[[R0]], $4 +; 32-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[R1]], $4 +; 32-CMP-DAG: or $[[T2:[0-9]+]], $[[T0]], $[[T1]] +; 32-CMP-DAG: lw $2, 0($[[T2]]) + +; 64-CMOV: daddiu $[[R1:[0-9]+]], ${{[0-9]+}}, %got_disp(d) +; 64-CMOV: daddiu $[[R0:[0-9]+]], ${{[0-9]+}}, %got_disp(c) +; 64-CMOV: movn $[[R1]], $[[R0]], $4 + +; 64-CMP-DAG: daddiu $[[R1:[0-9]+]], ${{[0-9]+}}, %got_disp(d) +; 64-CMP-DAG: daddiu $[[R0:[0-9]+]], ${{[0-9]+}}, %got_disp(c) +; FIXME: This sll works around an implementation detail in the code generator +; (setcc's result is i32 so bits 32-63 are undefined). It's not really +; needed. +; 64-CMP-DAG: sll $[[CC:[0-9]+]], $4, 0 +; 64-CMP-DAG: selnez $[[T0:[0-9]+]], $[[R0]], $[[CC]] +; 64-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[R1]], $[[CC]] +; 64-CMP-DAG: or $[[T2:[0-9]+]], $[[T0]], $[[T1]] +; 64-CMP-DAG: lw $2, 0($[[T2]]) + define i32 @cmov2(i32 %s) nounwind readonly { entry: %tobool = icmp ne i32 %s, 0 @@ -40,9 +87,28 @@ entry: ret i32 %cond } -; O32-LABEL: cmov3: -; O32: xori $[[R0:[0-9]+]], ${{[0-9]+}}, 234 -; O32: movz ${{[0-9]+}}, ${{[0-9]+}}, $[[R0]] +; ALL-LABEL: cmov3: + +; We won't check the result register since we can't know if the move is first +; or last. We do know it will be either one of two registers so we can at least +; check that. + +; 32-CMOV: xori $[[R0:[0-9]+]], $4, 234 +; 32-CMOV: movz ${{[26]}}, $5, $[[R0]] + +; 32-CMP-DAG: xori $[[CC:[0-9]+]], $4, 234 +; 32-CMP-DAG: seleqz $[[T0:[0-9]+]], $5, $[[CC]] +; 32-CMP-DAG: selnez $[[T1:[0-9]+]], $6, $[[CC]] +; 32-CMP-DAG: or $2, $[[T0]], $[[T1]] + +; 64-CMOV: xori $[[R0:[0-9]+]], $4, 234 +; 64-CMOV: movz ${{[26]}}, $5, $[[R0]] + +; 64-CMP-DAG: xori $[[CC:[0-9]+]], $4, 234 +; 64-CMP-DAG: seleqz $[[T0:[0-9]+]], $5, $[[CC]] +; 64-CMP-DAG: selnez $[[T1:[0-9]+]], $6, $[[CC]] +; 64-CMP-DAG: or $2, $[[T0]], $[[T1]] + define i32 @cmov3(i32 %a, i32 %b, i32 %c) nounwind readnone { entry: %cmp = icmp eq i32 %a, 234 @@ -50,9 +116,36 @@ entry: ret i32 %cond } -; N64-LABEL: cmov4: -; N64: xori $[[R0:[0-9]+]], ${{[0-9]+}}, 234 -; N64: movz ${{[0-9]+}}, ${{[0-9]+}}, $[[R0]] +; ALL-LABEL: cmov4: + +; We won't check the result register since we can't know if the move is first +; or last. We do know it will be one of two registers so we can at least check +; that. + +; 32-CMOV-DAG: xori $[[R0:[0-9]+]], $4, 234 +; 32-CMOV-DAG: lw $[[R1:2]], 16($sp) +; 32-CMOV-DAG: lw $[[R2:3]], 20($sp) +; 32-CMOV-DAG: movz $[[R1]], $6, $[[R0]] +; 32-CMOV-DAG: movz $[[R2]], $7, $[[R0]] + +; 32-CMP-DAG: xori $[[R0:[0-9]+]], $4, 234 +; 32-CMP-DAG: lw $[[R1:[0-9]+]], 16($sp) +; 32-CMP-DAG: lw $[[R2:[0-9]+]], 20($sp) +; 32-CMP-DAG: seleqz $[[T0:[0-9]+]], $6, $[[R0]] +; 32-CMP-DAG: seleqz $[[T1:[0-9]+]], $7, $[[R0]] +; 32-CMP-DAG: selnez $[[T2:[0-9]+]], $[[R1]], $[[R0]] +; 32-CMP-DAG: selnez $[[T3:[0-9]+]], $[[R2]], $[[R0]] +; 32-CMP-DAG: or $2, $[[T0]], $[[T2]] +; 32-CMP-DAG: or $3, $[[T1]], $[[T3]] + +; 64-CMOV: xori $[[R0:[0-9]+]], $4, 234 +; 64-CMOV: movz ${{[26]}}, $5, $[[R0]] + +; 64-CMP-DAG: xori $[[R0:[0-9]+]], $4, 234 +; 64-CMP-DAG: seleqz $[[T0:[0-9]+]], $5, $[[R0]] +; 64-CMP-DAG: selnez $[[T1:[0-9]+]], $6, $[[R0]] +; 64-CMP-DAG: or $2, $[[T0]], $[[T1]] + define i64 @cmov4(i32 %a, i64 %b, i64 %c) nounwind readnone { entry: %cmp = icmp eq i32 %a, 234 @@ -68,9 +161,33 @@ entry: ; (movz t, (setlt a, N + 1), f) ; if N + 1 fits in 16-bit. -; O32-LABEL: slti0: -; O32: slti $[[R0:[0-9]+]], ${{[0-9]+}}, 32767 -; O32: movz ${{[0-9]+}}, ${{[0-9]+}}, $[[R0]] +; ALL-LABEL: slti0: + +; 32-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3 +; 32-CMOV-DAG: addiu $[[I5:2]], $zero, 5 +; 32-CMOV-DAG: slti $[[R0:[0-9]+]], $4, 32767 +; 32-CMOV-DAG: movz $[[I5]], $[[I3]], $[[R0]] + +; 32-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3 +; 32-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5 +; 32-CMP-DAG: slti $[[R0:[0-9]+]], $4, 32767 +; FIXME: We can do better than this by using selccz to choose between +0 and +2 +; 32-CMP-DAG: seleqz $[[T0:[0-9]+]], $[[I3]], $[[R0]] +; 32-CMP-DAG: selnez $[[T1:[0-9]+]], $[[I5]], $[[R0]] +; 32-CMP-DAG: or $2, $[[T0]], $[[T1]] + +; 64-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3 +; 64-CMOV-DAG: addiu $[[I5:2]], $zero, 5 +; 64-CMOV-DAG: slti $[[R0:[0-9]+]], $4, 32767 +; 64-CMOV-DAG: movz $[[I5]], $[[I3]], $[[R0]] + +; 64-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3 +; 64-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5 +; 64-CMP-DAG: slti $[[R0:[0-9]+]], $4, 32767 +; FIXME: We can do better than this by using selccz to choose between +0 and +2 +; 64-CMP-DAG: seleqz $[[T0:[0-9]+]], $[[I3]], $[[R0]] +; 64-CMP-DAG: selnez $[[T1:[0-9]+]], $[[I5]], $[[R0]] +; 64-CMP-DAG: or $2, $[[T0]], $[[T1]] define i32 @slti0(i32 %a) { entry: @@ -79,19 +196,72 @@ entry: ret i32 %cond } -; O32-LABEL: slti1: -; O32: slt ${{[0-9]+}} +; ALL-LABEL: slti1: + +; 32-CMOV-DAG: addiu $[[I7:[0-9]+]], $zero, 7 +; 32-CMOV-DAG: addiu $[[I5:2]], $zero, 5 +; 32-CMOV-DAG: addiu $[[R1:[0-9]+]], $zero, 32767 +; 32-CMOV-DAG: slt $[[R0:[0-9]+]], $[[R1]], $4 +; 32-CMOV-DAG: movn $[[I5]], $[[I7]], $[[R0]] + +; 32-CMP-DAG: addiu $[[I7:[0-9]+]], $zero, 7 +; 32-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5 +; 32-CMP-DAG: addiu $[[I32767:[0-9]+]], $zero, 32767 +; 32-CMP-DAG: slt $[[R0:[0-9]+]], $[[I32767]], $4 +; FIXME: We can do better than this by using selccz to choose between -0 and -2 +; 32-CMP-DAG: selnez $[[T0:[0-9]+]], $[[I7]], $[[R0]] +; 32-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]] +; 32-CMP-DAG: or $2, $[[T0]], $[[T1]] + +; 64-CMOV-DAG: addiu $[[I7:[0-9]+]], $zero, 7 +; 64-CMOV-DAG: addiu $[[I5:2]], $zero, 5 +; 64-CMOV-DAG: addiu $[[R1:[0-9]+]], $zero, 32767 +; 64-CMOV-DAG: slt $[[R0:[0-9]+]], $[[R1]], $4 +; 64-CMOV-DAG: movn $[[I5]], $[[I7]], $[[R0]] + +; 64-CMP-DAG: addiu $[[I7:[0-9]+]], $zero, 7 +; 64-CMP-DAG: addiu $[[I5:2]], $zero, 5 +; 64-CMP-DAG: addiu $[[R1:[0-9]+]], $zero, 32767 +; 64-CMP-DAG: slt $[[R0:[0-9]+]], $[[R1]], $4 +; FIXME: We can do better than this by using selccz to choose between -0 and -2 +; 64-CMP-DAG: selnez $[[T0:[0-9]+]], $[[I7]], $[[R0]] +; 64-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]] +; 64-CMP-DAG: or $2, $[[T0]], $[[T1]] define i32 @slti1(i32 %a) { entry: %cmp = icmp sgt i32 %a, 32767 - %cond = select i1 %cmp, i32 3, i32 5 + %cond = select i1 %cmp, i32 7, i32 5 ret i32 %cond } -; O32-LABEL: slti2: -; O32: slti $[[R0:[0-9]+]], ${{[0-9]+}}, -32768 -; O32: movz ${{[0-9]+}}, ${{[0-9]+}}, $[[R0]] +; ALL-LABEL: slti2: + +; 32-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3 +; 32-CMOV-DAG: addiu $[[I5:2]], $zero, 5 +; 32-CMOV-DAG: slti $[[R0:[0-9]+]], $4, -32768 +; 32-CMOV-DAG: movz $[[I5]], $[[I3]], $[[R0]] + +; 32-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3 +; 32-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5 +; 32-CMP-DAG: slti $[[R0:[0-9]+]], $4, -32768 +; FIXME: We can do better than this by using selccz to choose between +0 and +2 +; 32-CMP-DAG: seleqz $[[T0:[0-9]+]], $[[I3]], $[[R0]] +; 32-CMP-DAG: selnez $[[T1:[0-9]+]], $[[I5]], $[[R0]] +; 32-CMP-DAG: or $2, $[[T0]], $[[T1]] + +; 64-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3 +; 64-CMOV-DAG: addiu $[[I5:2]], $zero, 5 +; 64-CMOV-DAG: slti $[[R0:[0-9]+]], $4, -32768 +; 64-CMOV-DAG: movz $[[I5]], $[[I3]], $[[R0]] + +; 64-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3 +; 64-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5 +; 64-CMP-DAG: slti $[[R0:[0-9]+]], $4, -32768 +; FIXME: We can do better than this by using selccz to choose between +0 and +2 +; 64-CMP-DAG: seleqz $[[T0:[0-9]+]], $[[I3]], $[[R0]] +; 64-CMP-DAG: selnez $[[T1:[0-9]+]], $[[I5]], $[[R0]] +; 64-CMP-DAG: or $2, $[[T0]], $[[T1]] define i32 @slti2(i32 %a) { entry: @@ -100,8 +270,41 @@ entry: ret i32 %cond } -; O32-LABEL: slti3: -; O32: slt ${{[0-9]+}} +; ALL-LABEL: slti3: + +; 32-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3 +; 32-CMOV-DAG: addiu $[[I5:2]], $zero, 5 +; 32-CMOV-DAG: lui $[[R1:[0-9]+]], 65535 +; 32-CMOV-DAG: ori $[[R1]], $[[R1]], 32766 +; 32-CMOV-DAG: slt $[[R0:[0-9]+]], $[[R1]], $4 +; 32-CMOV-DAG: movn $[[I5]], $[[I3]], $[[R0]] + +; 32-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3 +; 32-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5 +; 32-CMP-DAG: lui $[[IMM:[0-9]+]], 65535 +; 32-CMP-DAG: ori $[[IMM]], $[[IMM]], 32766 +; 32-CMP-DAG: slt $[[R0:[0-9]+]], $[[I32767]], $4 +; FIXME: We can do better than this by using selccz to choose between -0 and -2 +; 32-CMP-DAG: selnez $[[T0:[0-9]+]], $[[I3]], $[[R0]] +; 32-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]] +; 32-CMP-DAG: or $2, $[[T0]], $[[T1]] + +; 64-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3 +; 64-CMOV-DAG: addiu $[[I5:2]], $zero, 5 +; 64-CMOV-DAG: lui $[[R1:[0-9]+]], 65535 +; 64-CMOV-DAG: ori $[[R1]], $[[R1]], 32766 +; 64-CMOV-DAG: slt $[[R0:[0-9]+]], $[[R1]], $4 +; 64-CMOV-DAG: movn $[[I5]], $[[I3]], $[[R0]] + +; 64-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3 +; 64-CMP-DAG: addiu $[[I5:2]], $zero, 5 +; 64-CMP-DAG: lui $[[IMM:[0-9]+]], 65535 +; 64-CMP-DAG: ori $[[IMM]], $[[IMM]], 32766 +; 64-CMP-DAG: slt $[[R0:[0-9]+]], $[[IMM]], $4 +; FIXME: We can do better than this by using selccz to choose between -0 and -2 +; 64-CMP-DAG: selnez $[[T0:[0-9]+]], $[[I3]], $[[R0]] +; 64-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]] +; 64-CMP-DAG: or $2, $[[T0]], $[[T1]] define i32 @slti3(i32 %a) { entry: @@ -112,30 +315,117 @@ entry: ; 64-bit patterns. -; N64-LABEL: slti64_0: -; N64: slti $[[R0:[0-9]+]], ${{[0-9]+}}, 32767 -; N64: movz ${{[0-9]+}}, ${{[0-9]+}}, $[[R0]] +; ALL-LABEL: slti64_0: + +; 32-CMOV-DAG: slt $[[CC:[0-9]+]], $zero, $4 +; 32-CMOV-DAG: addiu $[[I32766:[0-9]+]], $zero, 32766 +; 32-CMOV-DAG: sltu $[[R1:[0-9]+]], $[[I32766]], $5 +; 32-CMOV-DAG: movz $[[CC:[0-9]+]], $[[R1]], $4 +; 32-CMOV-DAG: addiu $[[I5:[0-9]+]], $zero, 5 +; 32-CMOV-DAG: addiu $[[I4:3]], $zero, 4 +; 32-CMOV-DAG: movn $[[I4]], $[[I5]], $[[CC]] +; 32-CMOV-DAG: addiu $2, $zero, 0 + +; 32-CMP-DAG: slt $[[CC0:[0-9]+]], $zero, $4 +; 32-CMP-DAG: addiu $[[I32766:[0-9]+]], $zero, 32766 +; 32-CMP-DAG: sltu $[[CC1:[0-9]+]], $[[I32766]], $5 +; 32-CMP-DAG: selnez $[[CC2:[0-9]+]], $[[CC0]], $4 +; 32-CMP-DAG: seleqz $[[CC3:[0-9]+]], $[[CC1]], $4 +; 32-CMP: or $[[CC:[0-9]+]], $[[CC3]], $[[CC2]] +; 32-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5 +; 32-CMP-DAG: addiu $[[I4:[0-9]+]], $zero, 4 +; 32-CMP-DAG: seleqz $[[T0:[0-9]+]], $[[I4]], $[[CC]] +; 32-CMP-DAG: selnez $[[T1:[0-9]+]], $[[I5]], $[[CC]] +; 32-CMP-DAG: or $3, $[[T1]], $[[T0]] +; 32-CMP-DAG: addiu $2, $zero, 0 + +; 64-CMOV-DAG: addiu $[[I5:[0-9]+]], $zero, 5 +; 64-CMOV-DAG: addiu $[[I4:2]], $zero, 4 +; 64-CMOV-DAG: slti $[[R0:[0-9]+]], $4, 32767 +; 64-CMOV-DAG: movz $[[I4]], $[[I5]], $[[R0]] + +; 64-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5 +; 64-CMP-DAG: addiu $[[I4:[0-9]+]], $zero, 4 +; 64-CMP-DAG: slti $[[R0:[0-9]+]], $4, 32767 +; FIXME: We can do better than this by adding/subtracting the result of slti +; to/from one of the constants. +; 64-CMP-DAG: seleqz $[[T0:[0-9]+]], $[[I5]], $[[R0]] +; 64-CMP-DAG: selnez $[[T1:[0-9]+]], $[[I4]], $[[R0]] +; 64-CMP-DAG: or $2, $[[T0]], $[[T1]] define i64 @slti64_0(i64 %a) { entry: %cmp = icmp sgt i64 %a, 32766 - %conv = select i1 %cmp, i64 3, i64 4 + %conv = select i1 %cmp, i64 5, i64 4 ret i64 %conv } -; N64-LABEL: slti64_1: -; N64: slt ${{[0-9]+}} +; ALL-LABEL: slti64_1: + +; 32-CMOV-DAG: slt $[[CC:[0-9]+]], $zero, $4 +; 32-CMOV-DAG: addiu $[[I32766:[0-9]+]], $zero, 32767 +; 32-CMOV-DAG: sltu $[[R1:[0-9]+]], $[[I32766]], $5 +; 32-CMOV-DAG: movz $[[CC:[0-9]+]], $[[R1]], $4 +; 32-CMOV-DAG: addiu $[[I5:[0-9]+]], $zero, 5 +; 32-CMOV-DAG: addiu $[[I4:3]], $zero, 4 +; 32-CMOV-DAG: movn $[[I4]], $[[I5]], $[[CC]] +; 32-CMOV-DAG: addiu $2, $zero, 0 + +; 32-CMP-DAG: slt $[[CC0:[0-9]+]], $zero, $4 +; 32-CMP-DAG: addiu $[[I32766:[0-9]+]], $zero, 32767 +; 32-CMP-DAG: sltu $[[CC1:[0-9]+]], $[[I32766]], $5 +; 32-CMP-DAG: selnez $[[CC2:[0-9]+]], $[[CC0]], $4 +; 32-CMP-DAG: seleqz $[[CC3:[0-9]+]], $[[CC1]], $4 +; 32-CMP: or $[[CC:[0-9]+]], $[[CC3]], $[[CC2]] +; 32-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5 +; 32-CMP-DAG: addiu $[[I4:[0-9]+]], $zero, 4 +; 32-CMP-DAG: seleqz $[[T0:[0-9]+]], $[[I4]], $[[CC]] +; 32-CMP-DAG: selnez $[[T1:[0-9]+]], $[[I5]], $[[CC]] +; 32-CMP-DAG: or $3, $[[T1]], $[[T0]] +; 32-CMP-DAG: addiu $2, $zero, 0 + +; 64-CMOV-DAG: daddiu $[[I5:[0-9]+]], $zero, 5 +; 64-CMOV-DAG: daddiu $[[I4:2]], $zero, 4 +; 64-CMOV-DAG: daddiu $[[R1:[0-9]+]], $zero, 32767 +; 64-CMOV-DAG: slt $[[R0:[0-9]+]], $[[R1]], $4 +; 64-CMOV-DAG: movn $[[I4]], $[[I5]], $[[R0]] + +; 64-CMP-DAG: daddiu $[[I5:[0-9]+]], $zero, 5 +; 64-CMP-DAG: daddiu $[[I4:2]], $zero, 4 +; 64-CMP-DAG: daddiu $[[R1:[0-9]+]], $zero, 32767 +; 64-CMP-DAG: slt $[[R0:[0-9]+]], $[[R1]], $4 +; FIXME: We can do better than this by using selccz to choose between -0 and -2 +; 64-CMP-DAG: selnez $[[T0:[0-9]+]], $[[I5]], $[[R0]] +; 64-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I4]], $[[R0]] +; 64-CMP-DAG: or $2, $[[T0]], $[[T1]] define i64 @slti64_1(i64 %a) { entry: %cmp = icmp sgt i64 %a, 32767 - %conv = select i1 %cmp, i64 3, i64 4 + %conv = select i1 %cmp, i64 5, i64 4 ret i64 %conv } -; N64-LABEL: slti64_2: -; N64: slti $[[R0:[0-9]+]], ${{[0-9]+}}, -32768 -; N64: movz ${{[0-9]+}}, ${{[0-9]+}}, $[[R0]] +; ALL-LABEL: slti64_2: + +; FIXME: The 32-bit versions of this test are too complicated to reasonably +; match at the moment. They do show some missing optimizations though +; such as: +; (movz $a, $b, (neg $c)) -> (movn $a, $b, $c) + +; 64-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3 +; 64-CMOV-DAG: addiu $[[I4:2]], $zero, 4 +; 64-CMOV-DAG: slti $[[R0:[0-9]+]], $4, -32768 +; 64-CMOV-DAG: movz $[[I4]], $[[I3]], $[[R0]] + +; 64-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3 +; 64-CMP-DAG: addiu $[[I4:[0-9]+]], $zero, 4 +; 64-CMP-DAG: slti $[[R0:[0-9]+]], $4, -32768 +; FIXME: We can do better than this by adding/subtracting the result of slti +; to/from one of the constants. +; 64-CMP-DAG: seleqz $[[T0:[0-9]+]], $[[I3]], $[[R0]] +; 64-CMP-DAG: selnez $[[T1:[0-9]+]], $[[I4]], $[[R0]] +; 64-CMP-DAG: or $2, $[[T0]], $[[T1]] define i64 @slti64_2(i64 %a) { entry: @@ -144,21 +434,64 @@ entry: ret i64 %conv } -; N64-LABEL: slti64_3: -; N64: slt ${{[0-9]+}} +; ALL-LABEL: slti64_3: + +; FIXME: The 32-bit versions of this test are too complicated to reasonably +; match at the moment. They do show some missing optimizations though +; such as: +; (movz $a, $b, (neg $c)) -> (movn $a, $b, $c) + +; 64-CMOV-DAG: daddiu $[[I5:[0-9]+]], $zero, 5 +; 64-CMOV-DAG: daddiu $[[I4:2]], $zero, 4 +; 64-CMOV-DAG: daddiu $[[R1:[0-9]+]], ${{[0-9]+}}, 32766 +; 64-CMOV-DAG: slt $[[R0:[0-9]+]], $[[R1]], $4 +; 64-CMOV-DAG: movn $[[I4]], $[[I5]], $[[R0]] + +; 64-CMP-DAG: daddiu $[[I5:[0-9]+]], $zero, 5 +; 64-CMP-DAG: daddiu $[[I4:2]], $zero, 4 +; 64-CMP-DAG: daddiu $[[R1:[0-9]+]], ${{[0-9]+}}, 32766 +; 64-CMP-DAG: slt $[[R0:[0-9]+]], $[[R1]], $4 +; FIXME: We can do better than this by using selccz to choose between -0 and -2 +; 64-CMP-DAG: selnez $[[T0:[0-9]+]], $[[I5]], $[[R0]] +; 64-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I4]], $[[R0]] +; 64-CMP-DAG: or $2, $[[T0]], $[[T1]] define i64 @slti64_3(i64 %a) { entry: %cmp = icmp sgt i64 %a, -32770 - %conv = select i1 %cmp, i64 3, i64 4 + %conv = select i1 %cmp, i64 5, i64 4 ret i64 %conv } ; sltiu instructions. -; O32-LABEL: sltiu0: -; O32: sltiu $[[R0:[0-9]+]], ${{[0-9]+}}, 32767 -; O32: movz ${{[0-9]+}}, ${{[0-9]+}}, $[[R0]] +; ALL-LABEL: sltiu0: + +; 32-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3 +; 32-CMOV-DAG: addiu $[[I5:2]], $zero, 5 +; 32-CMOV-DAG: sltiu $[[R0:[0-9]+]], $4, 32767 +; 32-CMOV-DAG: movz $[[I5]], $[[I3]], $[[R0]] + +; 32-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3 +; 32-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5 +; 32-CMP-DAG: sltiu $[[R0:[0-9]+]], $4, 32767 +; FIXME: We can do better than this by using selccz to choose between +0 and +2 +; 32-CMP-DAG: seleqz $[[T0:[0-9]+]], $[[I3]], $[[R0]] +; 32-CMP-DAG: selnez $[[T1:[0-9]+]], $[[I5]], $[[R0]] +; 32-CMP-DAG: or $2, $[[T0]], $[[T1]] + +; 64-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3 +; 64-CMOV-DAG: addiu $[[I5:2]], $zero, 5 +; 64-CMOV-DAG: sltiu $[[R0:[0-9]+]], $4, 32767 +; 64-CMOV-DAG: movz $[[I5]], $[[I3]], $[[R0]] + +; 64-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3 +; 64-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5 +; 64-CMP-DAG: sltiu $[[R0:[0-9]+]], $4, 32767 +; FIXME: We can do better than this by using selccz to choose between +0 and +2 +; 64-CMP-DAG: seleqz $[[T0:[0-9]+]], $[[I3]], $[[R0]] +; 64-CMP-DAG: selnez $[[T1:[0-9]+]], $[[I5]], $[[R0]] +; 64-CMP-DAG: or $2, $[[T0]], $[[T1]] define i32 @sltiu0(i32 %a) { entry: @@ -167,19 +500,72 @@ entry: ret i32 %cond } -; O32-LABEL: sltiu1: -; O32: sltu ${{[0-9]+}} +; ALL-LABEL: sltiu1: + +; 32-CMOV-DAG: addiu $[[I7:[0-9]+]], $zero, 7 +; 32-CMOV-DAG: addiu $[[I5:2]], $zero, 5 +; 32-CMOV-DAG: addiu $[[R1:[0-9]+]], $zero, 32767 +; 32-CMOV-DAG: sltu $[[R0:[0-9]+]], $[[R1]], $4 +; 32-CMOV-DAG: movn $[[I5]], $[[I7]], $[[R0]] + +; 32-CMP-DAG: addiu $[[I7:[0-9]+]], $zero, 7 +; 32-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5 +; 32-CMP-DAG: addiu $[[I32767:[0-9]+]], $zero, 32767 +; 32-CMP-DAG: sltu $[[R0:[0-9]+]], $[[I32767]], $4 +; FIXME: We can do better than this by using selccz to choose between -0 and -2 +; 32-CMP-DAG: selnez $[[T0:[0-9]+]], $[[I7]], $[[R0]] +; 32-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]] +; 32-CMP-DAG: or $2, $[[T0]], $[[T1]] + +; 64-CMOV-DAG: addiu $[[I7:[0-9]+]], $zero, 7 +; 64-CMOV-DAG: addiu $[[I5:2]], $zero, 5 +; 64-CMOV-DAG: addiu $[[R1:[0-9]+]], $zero, 32767 +; 64-CMOV-DAG: sltu $[[R0:[0-9]+]], $[[R1]], $4 +; 64-CMOV-DAG: movn $[[I5]], $[[I7]], $[[R0]] + +; 64-CMP-DAG: addiu $[[I7:[0-9]+]], $zero, 7 +; 64-CMP-DAG: addiu $[[I5:2]], $zero, 5 +; 64-CMP-DAG: addiu $[[R1:[0-9]+]], $zero, 32767 +; 64-CMP-DAG: sltu $[[R0:[0-9]+]], $[[R1]], $4 +; FIXME: We can do better than this by using selccz to choose between -0 and -2 +; 64-CMP-DAG: selnez $[[T0:[0-9]+]], $[[I7]], $[[R0]] +; 64-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]] +; 64-CMP-DAG: or $2, $[[T0]], $[[T1]] define i32 @sltiu1(i32 %a) { entry: %cmp = icmp ugt i32 %a, 32767 - %cond = select i1 %cmp, i32 3, i32 5 + %cond = select i1 %cmp, i32 7, i32 5 ret i32 %cond } -; O32-LABEL: sltiu2: -; O32: sltiu $[[R0:[0-9]+]], ${{[0-9]+}}, -32768 -; O32: movz ${{[0-9]+}}, ${{[0-9]+}}, $[[R0]] +; ALL-LABEL: sltiu2: + +; 32-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3 +; 32-CMOV-DAG: addiu $[[I5:2]], $zero, 5 +; 32-CMOV-DAG: sltiu $[[R0:[0-9]+]], $4, -32768 +; 32-CMOV-DAG: movz $[[I5]], $[[I3]], $[[R0]] + +; 32-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3 +; 32-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5 +; 32-CMP-DAG: sltiu $[[R0:[0-9]+]], $4, -32768 +; FIXME: We can do better than this by using selccz to choose between +0 and +2 +; 32-CMP-DAG: seleqz $[[T0:[0-9]+]], $[[I3]], $[[R0]] +; 32-CMP-DAG: selnez $[[T1:[0-9]+]], $[[I5]], $[[R0]] +; 32-CMP-DAG: or $2, $[[T0]], $[[T1]] + +; 64-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3 +; 64-CMOV-DAG: addiu $[[I5:2]], $zero, 5 +; 64-CMOV-DAG: sltiu $[[R0:[0-9]+]], $4, -32768 +; 64-CMOV-DAG: movz $[[I5]], $[[I3]], $[[R0]] + +; 64-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3 +; 64-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5 +; 64-CMP-DAG: sltiu $[[R0:[0-9]+]], $4, -32768 +; FIXME: We can do better than this by using selccz to choose between +0 and +2 +; 64-CMP-DAG: seleqz $[[T0:[0-9]+]], $[[I3]], $[[R0]] +; 64-CMP-DAG: selnez $[[T1:[0-9]+]], $[[I5]], $[[R0]] +; 64-CMP-DAG: or $2, $[[T0]], $[[T1]] define i32 @sltiu2(i32 %a) { entry: @@ -188,8 +574,41 @@ entry: ret i32 %cond } -; O32-LABEL: sltiu3: -; O32: sltu ${{[0-9]+}} +; ALL-LABEL: sltiu3: + +; 32-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3 +; 32-CMOV-DAG: addiu $[[I5:2]], $zero, 5 +; 32-CMOV-DAG: lui $[[R1:[0-9]+]], 65535 +; 32-CMOV-DAG: ori $[[R1]], $[[R1]], 32766 +; 32-CMOV-DAG: sltu $[[R0:[0-9]+]], $[[R1]], $4 +; 32-CMOV-DAG: movn $[[I5]], $[[I3]], $[[R0]] + +; 32-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3 +; 32-CMP-DAG: addiu $[[I5:[0-9]+]], $zero, 5 +; 32-CMP-DAG: lui $[[IMM:[0-9]+]], 65535 +; 32-CMP-DAG: ori $[[IMM]], $[[IMM]], 32766 +; 32-CMP-DAG: sltu $[[R0:[0-9]+]], $[[I32767]], $4 +; FIXME: We can do better than this by using selccz to choose between -0 and -2 +; 32-CMP-DAG: selnez $[[T0:[0-9]+]], $[[I3]], $[[R0]] +; 32-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]] +; 32-CMP-DAG: or $2, $[[T0]], $[[T1]] + +; 64-CMOV-DAG: addiu $[[I3:[0-9]+]], $zero, 3 +; 64-CMOV-DAG: addiu $[[I5:2]], $zero, 5 +; 64-CMOV-DAG: lui $[[R1:[0-9]+]], 65535 +; 64-CMOV-DAG: ori $[[R1]], $[[R1]], 32766 +; 64-CMOV-DAG: sltu $[[R0:[0-9]+]], $[[R1]], $4 +; 64-CMOV-DAG: movn $[[I5]], $[[I3]], $[[R0]] + +; 64-CMP-DAG: addiu $[[I3:[0-9]+]], $zero, 3 +; 64-CMP-DAG: addiu $[[I5:2]], $zero, 5 +; 64-CMP-DAG: lui $[[IMM:[0-9]+]], 65535 +; 64-CMP-DAG: ori $[[IMM]], $[[IMM]], 32766 +; 64-CMP-DAG: sltu $[[R0:[0-9]+]], $[[IMM]], $4 +; FIXME: We can do better than this by using selccz to choose between -0 and -2 +; 64-CMP-DAG: selnez $[[T0:[0-9]+]], $[[I3]], $[[R0]] +; 64-CMP-DAG: seleqz $[[T1:[0-9]+]], $[[I5]], $[[R0]] +; 64-CMP-DAG: or $2, $[[T0]], $[[T1]] define i32 @sltiu3(i32 %a) { entry: @@ -210,11 +629,25 @@ define i32 @slti4(i32 %a) nounwind readnone { ret i32 %2 } -; O32-LABEL: slti4: -; O32-DAG: slti [[R1:\$[0-9]+]], $4, 7 -; O32-DAG: addiu [[R2:\$[0-9]+]], [[R1]], 3 -; O32-NOT: movn -; O32:.size slti4 +; ALL-LABEL: slti4: + +; 32-CMOV-DAG: slti [[R1:\$[0-9]+]], $4, 7 +; 32-CMOV-DAG: addiu $2, [[R1]], 3 +; 32-CMOV-NOT: movn + +; 32-CMP-DAG: slti [[R1:\$[0-9]+]], $4, 7 +; 32-CMP-DAG: addiu $2, [[R1]], 3 +; 32-CMP-NOT: seleqz +; 32-CMP-NOT: selnez + +; 64-CMOV-DAG: slti [[R1:\$[0-9]+]], $4, 7 +; 64-CMOV-DAG: addiu $2, [[R1]], 3 +; 64-CMOV-NOT: movn + +; 64-CMP-DAG: slti [[R1:\$[0-9]+]], $4, 7 +; 64-CMP-DAG: addiu $2, [[R1]], 3 +; 64-CMP-NOT: seleqz +; 64-CMP-NOT: selnez define i32 @slti5(i32 %a) nounwind readnone { %1 = icmp slt i32 %a, 7 @@ -222,11 +655,25 @@ define i32 @slti5(i32 %a) nounwind readnone { ret i32 %2 } -; O32-LABEL: slti5: -; O32-DAG: slti [[R1:\$[0-9]+]], $4, 7 -; O32-DAG: addiu [[R3:\$[0-9]+]], [[R2:\$[a-z0-9]+]], -4 -; O32-NOT: movn -; O32:.size slti5 +; ALL-LABEL: slti5: + +; 32-CMOV-DAG: slti [[R1:\$[0-9]+]], $4, 7 +; 32-CMOV-DAG: addiu [[R3:\$[0-9]+]], [[R2:\$[a-z0-9]+]], -4 +; 32-CMOV-NOT: movn + +; 32-CMP-DAG: slti [[R1:\$[0-9]+]], $4, 7 +; 32-CMP-DAG: addiu [[R3:\$[0-9]+]], [[R2:\$[a-z0-9]+]], -4 +; 32-CMP-NOT: seleqz +; 32-CMP-NOT: selnez + +; 64-CMOV-DAG: slti [[R1:\$[0-9]+]], $4, 7 +; 64-CMOV-DAG: addiu [[R3:\$[0-9]+]], [[R2:\$[a-z0-9]+]], -4 +; 64-CMOV-NOT: movn + +; 64-CMP-DAG: slti [[R1:\$[0-9]+]], $4, 7 +; 64-CMP-DAG: addiu [[R3:\$[0-9]+]], [[R2:\$[a-z0-9]+]], -4 +; 64-CMP-NOT: seleqz +; 64-CMP-NOT: selnez define i32 @slti6(i32 %a) nounwind readnone { %1 = icmp slt i32 %a, 7 @@ -234,9 +681,26 @@ define i32 @slti6(i32 %a) nounwind readnone { ret i32 %2 } -; O32-LABEL: slti6: -; O32-DAG: slti [[R1:\$[0-9]+]], $4, 7 -; O32-DAG: xori [[R1]], [[R1]], 1 -; O32-DAG: addiu [[R2:\$[0-9]+]], [[R1]], 3 -; O32-NOT: movn -; O32:.size slti6 +; ALL-LABEL: slti6: + +; 32-CMOV-DAG: slti [[R1:\$[0-9]+]], $4, 7 +; 32-CMOV-DAG: xori [[R1]], [[R1]], 1 +; 32-CMOV-DAG: addiu [[R2:\$[0-9]+]], [[R1]], 3 +; 32-CMOV-NOT: movn + +; 32-CMP-DAG: slti [[R1:\$[0-9]+]], $4, 7 +; 32-CMP-DAG: xori [[R1]], [[R1]], 1 +; 32-CMP-DAG: addiu [[R2:\$[0-9]+]], [[R1]], 3 +; 32-CMP-NOT: seleqz +; 32-CMP-NOT: selnez + +; 64-CMOV-DAG: slti [[R1:\$[0-9]+]], $4, 7 +; 64-CMOV-DAG: xori [[R1]], [[R1]], 1 +; 64-CMOV-DAG: addiu [[R2:\$[0-9]+]], [[R1]], 3 +; 64-CMOV-NOT: movn + +; 64-CMP-DAG: slti [[R1:\$[0-9]+]], $4, 7 +; 64-CMP-DAG: xori [[R1]], [[R1]], 1 +; 64-CMP-DAG: addiu [[R2:\$[0-9]+]], [[R1]], 3 +; 64-CMP-NOT: seleqz +; 64-CMP-NOT: selnez diff --git a/test/CodeGen/Mips/countleading.ll b/test/CodeGen/Mips/countleading.ll new file mode 100644 index 0000000..6e63cff --- /dev/null +++ b/test/CodeGen/Mips/countleading.ll @@ -0,0 +1,90 @@ +; RUN: llc -march=mipsel -mcpu=mips32 < %s | FileCheck -check-prefix=ALL -check-prefix=MIPS32-R1-R2 -check-prefix=MIPS32-GT-R1 %s +; RUN: llc -march=mipsel -mcpu=mips32r2 < %s | FileCheck -check-prefix=ALL -check-prefix=MIPS32-R1-R2 -check-prefix=MIPS32-GT-R1 %s +; RUN: llc -march=mipsel -mcpu=mips32r6 < %s | FileCheck -check-prefix=ALL -check-prefix=MIPS32-R6 -check-prefix=MIPS32-GT-R1 %s +; RUN: llc -march=mips64el -mcpu=mips4 < %s | FileCheck -check-prefix=ALL -check-prefix=MIPS4 %s +; RUN: llc -march=mips64el -mcpu=mips64 < %s | FileCheck -check-prefix=ALL -check-prefix=MIPS64-GT-R1 %s +; RUN: llc -march=mips64el -mcpu=mips64r2 < %s | FileCheck -check-prefix=ALL -check-prefix=MIPS64-GT-R1 %s +; R!N: llc -march=mips64el -mcpu=mips64r6 < %s | FileCheck -check-prefix=ALL -check-prefix=MIPS64-GT-R1 %s + +; Prefixes: +; ALL - All +; MIPS32-GT-R1 - MIPS64r1 and above (does not include MIPS64's) +; MIPS64-GT-R1 - MIPS64r1 and above + +define i32 @ctlz_i32(i32 %X) nounwind readnone { +entry: +; ALL-LABEL: ctlz_i32: + +; MIPS4-NOT: clz + +; MIPS32-GT-R1: clz $2, $4 + +; MIPS64-GT-R1: clz $2, $4 + + %tmp1 = tail call i32 @llvm.ctlz.i32(i32 %X, i1 true) + ret i32 %tmp1 +} + +declare i32 @llvm.ctlz.i32(i32, i1) nounwind readnone + +define i32 @ctlo_i32(i32 %X) nounwind readnone { +entry: +; ALL-LABEL: ctlo_i32: + +; MIPS4-NOT: clo + +; MIPS32-GT-R1: clo $2, $4 + +; MIPS64-GT-R1: clo $2, $4 + + %neg = xor i32 %X, -1 + %tmp1 = tail call i32 @llvm.ctlz.i32(i32 %neg, i1 true) + ret i32 %tmp1 +} + +define i64 @ctlz_i64(i64 %X) nounwind readnone { +entry: +; ALL-LABEL: ctlz_i64: + +; MIPS4-NOT: dclz + +; MIPS32-GT-R1-DAG: clz $[[R0:[0-9]+]], $4 +; MIPS32-GT-R1-DAG: clz $[[R1:[0-9]+]], $5 +; MIPS32-GT-R1-DAG: addiu $[[R2:2+]], $[[R0]], 32 +; MIPS32-R1-R2-DAG: movn $[[R2]], $[[R1]], $5 +; MIPS32-R6-DAG: seleqz $[[R5:[0-9]+]], $[[R2]], $5 +; MIPS32-R6-DAG: selnez $[[R6:[0-9]+]], $[[R1]], $5 +; MIPS32-R6-DAG: or $2, $[[R6]], $[[R5]] +; MIPS32-GT-R1-DAG: addiu $3, $zero, 0 + +; MIPS64-GT-R1: dclz $2, $4 + + %tmp1 = tail call i64 @llvm.ctlz.i64(i64 %X, i1 true) + ret i64 %tmp1 +} + +declare i64 @llvm.ctlz.i64(i64, i1) nounwind readnone + +define i64 @ctlo_i64(i64 %X) nounwind readnone { +entry: +; ALL-LABEL: ctlo_i64: + +; MIPS4-NOT: dclo + +; MIPS32-GT-R1-DAG: clo $[[R0:[0-9]+]], $4 +; MIPS32-GT-R1-DAG: clo $[[R1:[0-9]+]], $5 +; MIPS32-GT-R1-DAG: addiu $[[R2:2+]], $[[R0]], 32 +; MIPS32-GT-R1-DAG: addiu $[[R3:[0-9]+]], $zero, -1 +; MIPS32-GT-R1-DAG: xor $[[R4:[0-9]+]], $5, $[[R3]] +; MIPS32-R1-R2-DAG: movn $[[R2]], $[[R1]], $[[R4]] +; MIPS32-R6-DAG: selnez $[[R5:[0-9]+]], $[[R1]], $[[R4]] +; MIPS32-R6-DAG: seleqz $[[R6:[0-9]+]], $[[R2]], $[[R4]] +; MIPS32-R6-DAG: or $2, $[[R5]], $[[R6]] +; MIPS32-GT-R1-DAG: addiu $3, $zero, 0 + +; MIPS64-GT-R1: dclo $2, $4 + + %neg = xor i64 %X, -1 + %tmp1 = tail call i64 @llvm.ctlz.i64(i64 %neg, i1 true) + ret i64 %tmp1 +} diff --git a/test/CodeGen/Mips/divrem.ll b/test/CodeGen/Mips/divrem.ll index b631c3b..97f8360 100644 --- a/test/CodeGen/Mips/divrem.ll +++ b/test/CodeGen/Mips/divrem.ll @@ -1,77 +1,223 @@ -; RUN: llc -march=mips -verify-machineinstrs < %s |\ -; RUN: FileCheck %s -check-prefix=TRAP -; RUN: llc -march=mips -mno-check-zero-division < %s |\ -; RUN: FileCheck %s -check-prefix=NOCHECK +; RUN: llc -march=mips -mcpu=mips32 -verify-machineinstrs < %s | FileCheck %s -check-prefix=ALL -check-prefix=ACC32 -check-prefix=ACC32-TRAP +; RUN: llc -march=mips -mcpu=mips32r2 -verify-machineinstrs < %s | FileCheck %s -check-prefix=ALL -check-prefix=ACC32 -check-prefix=ACC32-TRAP +; RUN: llc -march=mips -mcpu=mips32r6 -verify-machineinstrs < %s | FileCheck %s -check-prefix=ALL -check-prefix=GPR32 -check-prefix=GPR32-TRAP +; RUN: llc -march=mips64 -mcpu=mips64 -verify-machineinstrs < %s | FileCheck %s -check-prefix=ALL -check-prefix=ACC64 -check-prefix=ACC64-TRAP +; RUN: llc -march=mips64 -mcpu=mips64r2 -verify-machineinstrs < %s | FileCheck %s -check-prefix=ALL -check-prefix=ACC64 -check-prefix=ACC64-TRAP +; RUN: llc -march=mips64 -mcpu=mips64r6 -verify-machineinstrs < %s | FileCheck %s -check-prefix=ALL -check-prefix=GPR64 -check-prefix=GPR64-TRAP -; TRAP-LABEL: sdiv1: -; TRAP: div $zero, ${{[0-9]+}}, $[[R0:[0-9]+]] -; TRAP: teq $[[R0]], $zero, 7 -; TRAP: mflo +; RUN: llc -march=mips -mcpu=mips32 -mno-check-zero-division < %s | FileCheck %s -check-prefix=ALL -check-prefix=ACC32 -check-prefix=NOCHECK +; RUN: llc -march=mips -mcpu=mips32r2 -mno-check-zero-division < %s | FileCheck %s -check-prefix=ALL -check-prefix=ACC32 -check-prefix=NOCHECK +; RUN: llc -march=mips -mcpu=mips32r6 -mno-check-zero-division < %s | FileCheck %s -check-prefix=ALL -check-prefix=GPR32 -check-prefix=NOCHECK +; RUN: llc -march=mips64 -mcpu=mips64 -mno-check-zero-division < %s | FileCheck %s -check-prefix=ALL -check-prefix=ACC64 -check-prefix=NOCHECK +; RUN: llc -march=mips64 -mcpu=mips64r2 -mno-check-zero-division < %s | FileCheck %s -check-prefix=ALL -check-prefix=ACC64 -check-prefix=NOCHECK +; RUN: llc -march=mips64 -mcpu=mips64r6 -mno-check-zero-division < %s | FileCheck %s -check-prefix=ALL -check-prefix=GPR64 -check-prefix=NOCHECK -; NOCHECK-LABEL: sdiv1: -; NOCHECK-NOT: teq -; NOCHECK: .end sdiv1 +; FileCheck Prefixes: +; ALL - All targets +; ACC32 - Accumulator based multiply/divide on 32-bit targets +; ACC64 - Same as ACC32 but only for 64-bit targets +; GPR32 - GPR based multiply/divide on 32-bit targets +; GPR64 - Same as GPR32 but only for 64-bit targets +; ACC32-TRAP - Same as TRAP and ACC32 combined +; ACC64-TRAP - Same as TRAP and ACC64 combined +; GPR32-TRAP - Same as TRAP and GPR32 combined +; GPR64-TRAP - Same as TRAP and GPR64 combined +; NOCHECK - Division by zero will not be detected @g0 = common global i32 0, align 4 @g1 = common global i32 0, align 4 define i32 @sdiv1(i32 %a0, i32 %a1) nounwind readnone { entry: +; ALL-LABEL: sdiv1: + +; ACC32: div $zero, $4, $5 +; ACC32-TRAP: teq $5, $zero, 7 + +; ACC64: div $zero, $4, $5 +; ACC64-TRAP: teq $5, $zero, 7 + +; GPR32: div $2, $4, $5 +; GPR32-TRAP: teq $5, $zero, 7 + +; GPR64: div $2, $4, $5 +; GPR64-TRAP: teq $5, $zero, 7 + +; NOCHECK-NOT: teq + +; ACC32: mflo $2 +; ACC64: mflo $2 + +; ALL: .end sdiv1 + %div = sdiv i32 %a0, %a1 ret i32 %div } -; TRAP-LABEL: srem1: -; TRAP: div $zero, ${{[0-9]+}}, $[[R0:[0-9]+]] -; TRAP: teq $[[R0]], $zero, 7 -; TRAP: mfhi - define i32 @srem1(i32 %a0, i32 %a1) nounwind readnone { entry: +; ALL-LABEL: srem1: + +; ACC32: div $zero, $4, $5 +; ACC32-TRAP: teq $5, $zero, 7 + +; ACC64: div $zero, $4, $5 +; ACC64-TRAP: teq $5, $zero, 7 + +; GPR32: mod $2, $4, $5 +; GPR32-TRAP: teq $5, $zero, 7 + +; GPR64: mod $2, $4, $5 +; GPR64-TRAP: teq $5, $zero, 7 + +; NOCHECK-NOT: teq + +; ACC32: mfhi $2 +; ACC64: mfhi $2 + +; ALL: .end srem1 + %rem = srem i32 %a0, %a1 ret i32 %rem } -; TRAP-LABEL: udiv1: -; TRAP: divu $zero, ${{[0-9]+}}, $[[R0:[0-9]+]] -; TRAP: teq $[[R0]], $zero, 7 -; TRAP: mflo - define i32 @udiv1(i32 %a0, i32 %a1) nounwind readnone { entry: +; ALL-LABEL: udiv1: + +; ACC32: divu $zero, $4, $5 +; ACC32-TRAP: teq $5, $zero, 7 + +; ACC64: divu $zero, $4, $5 +; ACC64-TRAP: teq $5, $zero, 7 + +; GPR32: divu $2, $4, $5 +; GPR32-TRAP: teq $5, $zero, 7 + +; GPR64: divu $2, $4, $5 +; GPR64-TRAP: teq $5, $zero, 7 + +; NOCHECK-NOT: teq + +; ACC32: mflo $2 +; ACC64: mflo $2 + +; ALL: .end udiv1 %div = udiv i32 %a0, %a1 ret i32 %div } -; TRAP-LABEL: urem1: -; TRAP: divu $zero, ${{[0-9]+}}, $[[R0:[0-9]+]] -; TRAP: teq $[[R0]], $zero, 7 -; TRAP: mfhi - define i32 @urem1(i32 %a0, i32 %a1) nounwind readnone { entry: +; ALL-LABEL: urem1: + +; ACC32: divu $zero, $4, $5 +; ACC32-TRAP: teq $5, $zero, 7 + +; ACC64: divu $zero, $4, $5 +; ACC64-TRAP: teq $5, $zero, 7 + +; GPR32: modu $2, $4, $5 +; GPR32-TRAP: teq $5, $zero, 7 + +; GPR64: modu $2, $4, $5 +; GPR64-TRAP: teq $5, $zero, 7 + +; NOCHECK-NOT: teq + +; ACC32: mfhi $2 +; ACC64: mfhi $2 + +; ALL: .end urem1 + %rem = urem i32 %a0, %a1 ret i32 %rem } -; TRAP: div $zero, define i32 @sdivrem1(i32 %a0, i32 %a1, i32* nocapture %r) nounwind { entry: +; ALL-LABEL: sdivrem1: + +; ACC32: div $zero, $4, $5 +; ACC32-TRAP: teq $5, $zero, 7 +; NOCHECK-NOT: teq +; ACC32: mflo $2 +; ACC32: mfhi $[[R0:[0-9]+]] +; ACC32: sw $[[R0]], 0(${{[0-9]+}}) + +; ACC64: div $zero, $4, $5 +; ACC64-TRAP: teq $5, $zero, 7 +; NOCHECK-NOT: teq +; ACC64: mflo $2 +; ACC64: mfhi $[[R0:[0-9]+]] +; ACC64: sw $[[R0]], 0(${{[0-9]+}}) + +; GPR32: mod $[[R0:[0-9]+]], $4, $5 +; GPR32-TRAP: teq $5, $zero, 7 +; NOCHECK-NOT: teq +; GPR32: sw $[[R0]], 0(${{[0-9]+}}) +; GPR32-DAG: div $2, $4, $5 +; GPR32-TRAP: teq $5, $zero, 7 + +; GPR64: mod $[[R0:[0-9]+]], $4, $5 +; GPR64-TRAP: teq $5, $zero, 7 +; NOCHECK-NOT: teq +; GPR64: sw $[[R0]], 0(${{[0-9]+}}) +; GPR64-DAG: div $2, $4, $5 +; GPR64-TRAP: teq $5, $zero, 7 +; NOCHECK-NOT: teq + +; ALL: .end sdivrem1 + %rem = srem i32 %a0, %a1 store i32 %rem, i32* %r, align 4 %div = sdiv i32 %a0, %a1 ret i32 %div } -; TRAP: divu $zero, define i32 @udivrem1(i32 %a0, i32 %a1, i32* nocapture %r) nounwind { entry: +; ALL-LABEL: udivrem1: + +; ACC32: divu $zero, $4, $5 +; ACC32-TRAP: teq $5, $zero, 7 +; NOCHECK-NOT: teq +; ACC32: mflo $2 +; ACC32: mfhi $[[R0:[0-9]+]] +; ACC32: sw $[[R0]], 0(${{[0-9]+}}) + +; ACC64: divu $zero, $4, $5 +; ACC64-TRAP: teq $5, $zero, 7 +; NOCHECK-NOT: teq +; ACC64: mflo $2 +; ACC64: mfhi $[[R0:[0-9]+]] +; ACC64: sw $[[R0]], 0(${{[0-9]+}}) + +; GPR32: modu $[[R0:[0-9]+]], $4, $5 +; GPR32-TRAP: teq $5, $zero, 7 +; NOCHECK-NOT: teq +; GPR32: sw $[[R0]], 0(${{[0-9]+}}) +; GPR32-DAG: divu $2, $4, $5 +; GPR32-TRAP: teq $5, $zero, 7 +; NOCHECK-NOT: teq + +; GPR64: modu $[[R0:[0-9]+]], $4, $5 +; GPR64-TRAP: teq $5, $zero, 7 +; NOCHECK-NOT: teq +; GPR64: sw $[[R0]], 0(${{[0-9]+}}) +; GPR64-DAG: divu $2, $4, $5 +; GPR64-TRAP: teq $5, $zero, 7 +; NOCHECK-NOT: teq + +; ALL: .end udivrem1 + %rem = urem i32 %a0, %a1 store i32 %rem, i32* %r, align 4 %div = udiv i32 %a0, %a1 ret i32 %div } +; FIXME: It's not clear what this is supposed to test. define i32 @killFlags() { entry: %0 = load i32* @g0, align 4 @@ -79,3 +225,164 @@ entry: %div = sdiv i32 %0, %1 ret i32 %div } + +define i64 @sdiv2(i64 %a0, i64 %a1) nounwind readnone { +entry: +; ALL-LABEL: sdiv2: + +; ACC32: lw $25, %call16(__divdi3)( +; ACC32: jalr $25 + +; ACC64: ddiv $zero, $4, $5 +; ACC64-TRAP: teq $5, $zero, 7 + +; GPR64: ddiv $2, $4, $5 +; GPR64-TRAP: teq $5, $zero, 7 + +; NOCHECK-NOT: teq + +; ACC64: mflo $2 + +; ALL: .end sdiv2 + + %div = sdiv i64 %a0, %a1 + ret i64 %div +} + +define i64 @srem2(i64 %a0, i64 %a1) nounwind readnone { +entry: +; ALL-LABEL: srem2: + +; ACC32: lw $25, %call16(__moddi3)( +; ACC32: jalr $25 + +; ACC64: div $zero, $4, $5 +; ACC64-TRAP: teq $5, $zero, 7 + +; GPR64: dmod $2, $4, $5 +; GPR64-TRAP: teq $5, $zero, 7 + +; NOCHECK-NOT: teq + +; ACC64: mfhi $2 + +; ALL: .end srem2 + + %rem = srem i64 %a0, %a1 + ret i64 %rem +} + +define i64 @udiv2(i64 %a0, i64 %a1) nounwind readnone { +entry: +; ALL-LABEL: udiv2: + +; ACC32: lw $25, %call16(__udivdi3)( +; ACC32: jalr $25 + +; ACC64: divu $zero, $4, $5 +; ACC64-TRAP: teq $5, $zero, 7 + +; GPR64: ddivu $2, $4, $5 +; GPR64-TRAP: teq $5, $zero, 7 + +; NOCHECK-NOT: teq + +; ACC64: mflo $2 + +; ALL: .end udiv2 + %div = udiv i64 %a0, %a1 + ret i64 %div +} + +define i64 @urem2(i64 %a0, i64 %a1) nounwind readnone { +entry: +; ALL-LABEL: urem2: + +; ACC32: lw $25, %call16(__umoddi3)( +; ACC32: jalr $25 + +; ACC64: divu $zero, $4, $5 +; ACC64-TRAP: teq $5, $zero, 7 + +; GPR64: dmodu $2, $4, $5 +; GPR64-TRAP: teq $5, $zero, 7 + +; NOCHECK-NOT: teq + +; ACC64: mfhi $2 + +; ALL: .end urem2 + + %rem = urem i64 %a0, %a1 + ret i64 %rem +} + +define i64 @sdivrem2(i64 %a0, i64 %a1, i64* nocapture %r) nounwind { +entry: +; ALL-LABEL: sdivrem2: + +; sdivrem2 is too complex to effectively check. We can at least check for the +; calls though. +; ACC32: lw $25, %call16(__moddi3)( +; ACC32: jalr $25 +; ACC32: lw $25, %call16(__divdi3)( +; ACC32: jalr $25 + +; ACC64: ddiv $zero, $4, $5 +; ACC64-TRAP: teq $5, $zero, 7 +; NOCHECK-NOT: teq +; ACC64: mflo $2 +; ACC64: mfhi $[[R0:[0-9]+]] +; ACC64: sd $[[R0]], 0(${{[0-9]+}}) + +; GPR64: dmod $[[R0:[0-9]+]], $4, $5 +; GPR64-TRAP: teq $5, $zero, 7 +; NOCHECK-NOT: teq +; GPR64: sd $[[R0]], 0(${{[0-9]+}}) + +; GPR64-DAG: ddiv $2, $4, $5 +; GPR64-TRAP: teq $5, $zero, 7 +; NOCHECK-NOT: teq + +; ALL: .end sdivrem2 + + %rem = srem i64 %a0, %a1 + store i64 %rem, i64* %r, align 8 + %div = sdiv i64 %a0, %a1 + ret i64 %div +} + +define i64 @udivrem2(i64 %a0, i64 %a1, i64* nocapture %r) nounwind { +entry: +; ALL-LABEL: udivrem2: + +; udivrem2 is too complex to effectively check. We can at least check for the +; calls though. +; ACC32: lw $25, %call16(__umoddi3)( +; ACC32: jalr $25 +; ACC32: lw $25, %call16(__udivdi3)( +; ACC32: jalr $25 + +; ACC64: ddivu $zero, $4, $5 +; ACC64-TRAP: teq $5, $zero, 7 +; NOCHECK-NOT: teq +; ACC64: mflo $2 +; ACC64: mfhi $[[R0:[0-9]+]] +; ACC64: sd $[[R0]], 0(${{[0-9]+}}) + +; GPR64: dmodu $[[R0:[0-9]+]], $4, $5 +; GPR64-TRAP: teq $5, $zero, 7 +; NOCHECK-NOT: teq +; GPR64: sd $[[R0]], 0(${{[0-9]+}}) + +; GPR64-DAG: ddivu $2, $4, $5 +; GPR64-TRAP: teq $5, $zero, 7 +; NOCHECK-NOT: teq + +; ALL: .end udivrem2 + + %rem = urem i64 %a0, %a1 + store i64 %rem, i64* %r, align 8 + %div = udiv i64 %a0, %a1 + ret i64 %div +} diff --git a/test/CodeGen/Mips/dsp-r1.ll b/test/CodeGen/Mips/dsp-r1.ll index acdd17d..fbd9703 100644 --- a/test/CodeGen/Mips/dsp-r1.ll +++ b/test/CodeGen/Mips/dsp-r1.ll @@ -1,4 +1,4 @@ -; RUN: llc -march=mipsel -mattr=+dsp < %s | FileCheck %s +; RUN: llc -march=mipsel -mcpu=mips32 -mattr=+dsp < %s | FileCheck %s define i32 @test__builtin_mips_extr_w1(i32 %i0, i32, i64 %a0) nounwind { entry: diff --git a/test/CodeGen/Mips/eh-return32.ll b/test/CodeGen/Mips/eh-return32.ll index c3003b3..748050c 100644 --- a/test/CodeGen/Mips/eh-return32.ll +++ b/test/CodeGen/Mips/eh-return32.ll @@ -1,4 +1,6 @@ -; RUN: llc -march=mipsel -mcpu=mips32 < %s | FileCheck %s +; RUN: llc -march=mipsel -mcpu=mips32 -asm-show-inst < %s | FileCheck %s -check-prefix=CHECK -check-prefix=NOT-R6 +; RUN: llc -march=mipsel -mcpu=mips32r2 -asm-show-inst < %s | FileCheck %s -check-prefix=CHECK -check-prefix=NOT-R6 +; RUN: llc -march=mipsel -mcpu=mips32r6 -asm-show-inst < %s | FileCheck %s -check-prefix=CHECK -check-prefix=R6 declare void @llvm.eh.return.i32(i32, i8*) declare void @foo(...) @@ -9,7 +11,7 @@ entry: call void @llvm.eh.return.i32(i32 %offset, i8* %handler) unreachable -; CHECK: f1 +; CHECK: f1: ; CHECK: addiu $sp, $sp, -[[spoffset:[0-9]+]] ; check that $a0-$a3 are saved on stack. @@ -41,7 +43,8 @@ entry: ; CHECK: addiu $sp, $sp, [[spoffset]] ; CHECK: move $25, $2 ; CHECK: move $ra, $2 -; CHECK: jr $ra +; NOT-R6: jr $ra # <MCInst #{{[0-9]+}} JR +; R6: jr $ra # <MCInst #{{[0-9]+}} JALR ; CHECK: addu $sp, $sp, $3 } @@ -50,7 +53,7 @@ entry: call void @llvm.eh.return.i32(i32 %offset, i8* %handler) unreachable -; CHECK: f2 +; CHECK: f2: ; CHECK: addiu $sp, $sp, -[[spoffset:[0-9]+]] ; check that $a0-$a3 are saved on stack. @@ -80,6 +83,7 @@ entry: ; CHECK: addiu $sp, $sp, [[spoffset]] ; CHECK: move $25, $2 ; CHECK: move $ra, $2 -; CHECK: jr $ra +; NOT-R6: jr $ra # <MCInst #{{[0-9]+}} JR +; R6: jr $ra # <MCInst #{{[0-9]+}} JALR ; CHECK: addu $sp, $sp, $3 } diff --git a/test/CodeGen/Mips/eh-return64.ll b/test/CodeGen/Mips/eh-return64.ll index 8c5af50..74a4323 100644 --- a/test/CodeGen/Mips/eh-return64.ll +++ b/test/CodeGen/Mips/eh-return64.ll @@ -1,5 +1,7 @@ -; RUN: llc -march=mips64el -mcpu=mips4 < %s | FileCheck %s -; RUN: llc -march=mips64el -mcpu=mips64 < %s | FileCheck %s +; RUN: llc -march=mips64el -mcpu=mips4 -asm-show-inst < %s | FileCheck %s -check-prefix=CHECK -check-prefix=NOT-R6 +; RUN: llc -march=mips64el -mcpu=mips64 -asm-show-inst < %s | FileCheck %s -check-prefix=CHECK -check-prefix=NOT-R6 +; RUN: llc -march=mips64el -mcpu=mips64r2 -asm-show-inst < %s | FileCheck %s -check-prefix=CHECK -check-prefix=NOT-R6 +; RUN: llc -march=mips64el -mcpu=mips64r6 -asm-show-inst < %s | FileCheck %s -check-prefix=CHECK -check-prefix=R6 declare void @llvm.eh.return.i64(i64, i8*) declare void @foo(...) @@ -10,7 +12,7 @@ entry: call void @llvm.eh.return.i64(i64 %offset, i8* %handler) unreachable -; CHECK: f1 +; CHECK: f1: ; CHECK: daddiu $sp, $sp, -[[spoffset:[0-9]+]] ; check that $a0-$a3 are saved on stack. @@ -42,9 +44,9 @@ entry: ; CHECK: daddiu $sp, $sp, [[spoffset]] ; CHECK: move $25, $2 ; CHECK: move $ra, $2 -; CHECK: jr $ra +; NOT-R6: jr $ra # <MCInst #{{[0-9]+}} JR +; R6: jr $ra # <MCInst #{{[0-9]+}} JALR ; CHECK: daddu $sp, $sp, $3 - } define void @f2(i64 %offset, i8* %handler) { @@ -52,7 +54,7 @@ entry: call void @llvm.eh.return.i64(i64 %offset, i8* %handler) unreachable -; CHECK: f2 +; CHECK: f2: ; CHECK: .cfi_startproc ; CHECK: daddiu $sp, $sp, -[[spoffset:[0-9]+]] ; CHECK: .cfi_def_cfa_offset [[spoffset]] @@ -84,7 +86,8 @@ entry: ; CHECK: daddiu $sp, $sp, [[spoffset]] ; CHECK: move $25, $2 ; CHECK: move $ra, $2 -; CHECK: jr $ra +; NOT-R6: jr $ra # <MCInst #{{[0-9]+}} JR +; R6: jr $ra # <MCInst #{{[0-9]+}} JALR ; CHECK: daddu $sp, $sp, $3 ; CHECK: .cfi_endproc } diff --git a/test/CodeGen/Mips/ehframe-indirect.ll b/test/CodeGen/Mips/ehframe-indirect.ll new file mode 100644 index 0000000..e78497a --- /dev/null +++ b/test/CodeGen/Mips/ehframe-indirect.ll @@ -0,0 +1,34 @@ +; RUN: llc -mtriple=mipsel-linux-gnu < %s | FileCheck %s +; RUN: llc -mtriple=mipsel-linux-android < %s | FileCheck %s + +define i32 @main() { +; CHECK: .cfi_startproc +; CHECK: .cfi_personality 128, DW.ref.__gxx_personality_v0 + +entry: + invoke void @foo() to label %cont unwind label %lpad +; CHECK: foo +; CHECK: jalr + +lpad: + %0 = landingpad { i8*, i32 } personality i8* + bitcast (i32 (...)* @__gxx_personality_v0 to i8*) catch i8* null + ret i32 0 + +cont: + ret i32 0 +} +; CHECK: .cfi_endproc + +declare i32 @__gxx_personality_v0(...) + +declare void @foo() + +; CHECK: .hidden DW.ref.__gxx_personality_v0 +; CHECK: .weak DW.ref.__gxx_personality_v0 +; CHECK: .section .data.DW.ref.__gxx_personality_v0,"aGw",@progbits,DW.ref.__gxx_personality_v0,comdat +; CHECK: .align 2 +; CHECK: .type DW.ref.__gxx_personality_v0,@object +; CHECK: .size DW.ref.__gxx_personality_v0, 4 +; CHECK: DW.ref.__gxx_personality_v0: +; CHECK: .4byte __gxx_personality_v0 diff --git a/test/CodeGen/Mips/fcmp.ll b/test/CodeGen/Mips/fcmp.ll new file mode 100644 index 0000000..b775983 --- /dev/null +++ b/test/CodeGen/Mips/fcmp.ll @@ -0,0 +1,783 @@ +; RUN: llc < %s -march=mipsel -mcpu=mips32 | FileCheck %s -check-prefix=ALL -check-prefix=32-C +; RUN: llc < %s -march=mipsel -mcpu=mips32r2 | FileCheck %s -check-prefix=ALL -check-prefix=32-C +; RUN: llc < %s -march=mipsel -mcpu=mips32r6 | FileCheck %s -check-prefix=ALL -check-prefix=32-CMP +; RUN: llc < %s -march=mips64el -mcpu=mips4 | FileCheck %s -check-prefix=ALL -check-prefix=64-C +; RUN: llc < %s -march=mips64el -mcpu=mips64 | FileCheck %s -check-prefix=ALL -check-prefix=64-C +; RUN: llc < %s -march=mips64el -mcpu=mips64r2 | FileCheck %s -check-prefix=ALL -check-prefix=64-C +; RUN: llc < %s -march=mips64el -mcpu=mips64r6 | FileCheck %s -check-prefix=ALL -check-prefix=64-CMP + +define i32 @false_f32(float %a, float %b) nounwind { +; ALL-LABEL: false_f32: +; ALL: addiu $2, $zero, 0 + + %1 = fcmp false float %a, %b + %2 = zext i1 %1 to i32 + ret i32 %2 +} + +define i32 @oeq_f32(float %a, float %b) nounwind { +; ALL-LABEL: oeq_f32: + +; 32-C-DAG: addiu $[[T0:2]], $zero, 0 +; 32-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 32-C-DAG: c.eq.s $f12, $f14 +; 32-C-DAG: movt $[[T0]], $1, $fcc0 + +; 64-C-DAG: addiu $[[T0:2]], $zero, 0 +; 64-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 64-C-DAG: c.eq.s $f12, $f13 +; 64-C-DAG: movt $[[T0]], $1, $fcc0 + +; 32-CMP-DAG: cmp.eq.s $[[T0:f[0-9]+]], $f12, $f14 +; 32-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 32-CMP-DAG: andi $2, $[[T1]], 1 + +; 64-CMP-DAG: cmp.eq.s $[[T0:f[0-9]+]], $f12, $f13 +; 64-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 64-CMP-DAG: andi $2, $[[T1]], 1 + + %1 = fcmp oeq float %a, %b + %2 = zext i1 %1 to i32 + ret i32 %2 +} + +define i32 @ogt_f32(float %a, float %b) nounwind { +; ALL-LABEL: ogt_f32: + +; 32-C-DAG: addiu $[[T0:2]], $zero, 0 +; 32-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 32-C-DAG: c.ule.s $f12, $f14 +; 32-C-DAG: movf $[[T0]], $1, $fcc0 + +; 64-C-DAG: addiu $[[T0:2]], $zero, 0 +; 64-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 64-C-DAG: c.ule.s $f12, $f13 +; 64-C-DAG: movf $[[T0]], $1, $fcc0 + +; 32-CMP-DAG: cmp.lt.s $[[T0:f[0-9]+]], $f14, $f12 +; 32-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 32-CMP-DAG: andi $2, $[[T1]], 1 + +; 64-CMP-DAG: cmp.lt.s $[[T0:f[0-9]+]], $f13, $f12 +; 64-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 64-CMP-DAG: andi $2, $[[T1]], 1 + + %1 = fcmp ogt float %a, %b + %2 = zext i1 %1 to i32 + ret i32 %2 +} + +define i32 @oge_f32(float %a, float %b) nounwind { +; ALL-LABEL: oge_f32: + +; 32-C-DAG: addiu $[[T0:2]], $zero, 0 +; 32-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 32-C-DAG: c.ult.s $f12, $f14 +; 32-C-DAG: movf $[[T0]], $1, $fcc0 + +; 64-C-DAG: addiu $[[T0:2]], $zero, 0 +; 64-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 64-C-DAG: c.ult.s $f12, $f13 +; 64-C-DAG: movf $[[T0]], $1, $fcc0 + +; 32-CMP-DAG: cmp.le.s $[[T0:f[0-9]+]], $f14, $f12 +; 32-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 32-CMP-DAG: andi $2, $[[T1]], 1 + +; 64-CMP-DAG: cmp.le.s $[[T0:f[0-9]+]], $f13, $f12 +; 64-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 64-CMP-DAG: andi $2, $[[T1]], 1 + + %1 = fcmp oge float %a, %b + %2 = zext i1 %1 to i32 + ret i32 %2 +} + +define i32 @olt_f32(float %a, float %b) nounwind { +; ALL-LABEL: olt_f32: + +; 32-C-DAG: addiu $[[T0:2]], $zero, 0 +; 32-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 32-C-DAG: c.olt.s $f12, $f14 +; 32-C-DAG: movt $[[T0]], $1, $fcc0 + +; 64-C-DAG: addiu $[[T0:2]], $zero, 0 +; 64-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 64-C-DAG: c.olt.s $f12, $f13 +; 64-C-DAG: movt $[[T0]], $1, $fcc0 + +; 32-CMP-DAG: cmp.lt.s $[[T0:f[0-9]+]], $f12, $f14 +; 32-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 32-CMP-DAG: andi $2, $[[T1]], 1 + +; 64-CMP-DAG: cmp.lt.s $[[T0:f[0-9]+]], $f12, $f13 +; 64-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 64-CMP-DAG: andi $2, $[[T1]], 1 + + %1 = fcmp olt float %a, %b + %2 = zext i1 %1 to i32 + ret i32 %2 +} + +define i32 @ole_f32(float %a, float %b) nounwind { +; ALL-LABEL: ole_f32: + +; 32-C-DAG: addiu $[[T0:2]], $zero, 0 +; 32-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 32-C-DAG: c.ole.s $f12, $f14 +; 32-C-DAG: movt $[[T0]], $1, $fcc0 + +; 64-C-DAG: addiu $[[T0:2]], $zero, 0 +; 64-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 64-C-DAG: c.ole.s $f12, $f13 +; 64-C-DAG: movt $[[T0]], $1, $fcc0 + +; 32-CMP-DAG: cmp.le.s $[[T0:f[0-9]+]], $f12, $f14 +; 32-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 32-CMP-DAG: andi $2, $[[T1]], 1 + +; 64-CMP-DAG: cmp.le.s $[[T0:f[0-9]+]], $f12, $f13 +; 64-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 64-CMP-DAG: andi $2, $[[T1]], 1 + + %1 = fcmp ole float %a, %b + %2 = zext i1 %1 to i32 + ret i32 %2 +} + +define i32 @one_f32(float %a, float %b) nounwind { +; ALL-LABEL: one_f32: + +; 32-C-DAG: addiu $[[T0:2]], $zero, 0 +; 32-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 32-C-DAG: c.ueq.s $f12, $f14 +; 32-C-DAG: movf $[[T0]], $1, $fcc0 + +; 64-C-DAG: addiu $[[T0:2]], $zero, 0 +; 64-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 64-C-DAG: c.ueq.s $f12, $f13 +; 64-C-DAG: movf $[[T0]], $1, $fcc0 + +; 32-CMP-DAG: cmp.ueq.s $[[T0:f[0-9]+]], $f12, $f14 +; 32-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 32-CMP-DAG: not $[[T2:[0-9]+]], $[[T1]] +; 32-CMP-DAG: andi $2, $[[T2]], 1 + +; 64-CMP-DAG: cmp.ueq.s $[[T0:f[0-9]+]], $f12, $f13 +; 64-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 64-CMP-DAG: not $[[T2:[0-9]+]], $[[T1]] +; 64-CMP-DAG: andi $2, $[[T2]], 1 + + %1 = fcmp one float %a, %b + %2 = zext i1 %1 to i32 + ret i32 %2 +} + +define i32 @ord_f32(float %a, float %b) nounwind { +; ALL-LABEL: ord_f32: + +; 32-C-DAG: addiu $[[T0:2]], $zero, 0 +; 32-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 32-C-DAG: c.un.s $f12, $f14 +; 32-C-DAG: movf $[[T0]], $1, $fcc0 + +; 64-C-DAG: addiu $[[T0:2]], $zero, 0 +; 64-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 64-C-DAG: c.un.s $f12, $f13 +; 64-C-DAG: movf $[[T0]], $1, $fcc0 + +; 32-CMP-DAG: cmp.un.s $[[T0:f[0-9]+]], $f12, $f14 +; 32-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 32-CMP-DAG: not $[[T2:[0-9]+]], $[[T1]] +; 32-CMP-DAG: andi $2, $[[T2]], 1 + +; 64-CMP-DAG: cmp.un.s $[[T0:f[0-9]+]], $f12, $f13 +; 64-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 64-CMP-DAG: not $[[T2:[0-9]+]], $[[T1]] +; 64-CMP-DAG: andi $2, $[[T2]], 1 + + %1 = fcmp ord float %a, %b + %2 = zext i1 %1 to i32 + ret i32 %2 +} + +define i32 @ueq_f32(float %a, float %b) nounwind { +; ALL-LABEL: ueq_f32: + +; 32-C-DAG: addiu $[[T0:2]], $zero, 0 +; 32-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 32-C-DAG: c.ueq.s $f12, $f14 +; 32-C-DAG: movt $[[T0]], $1, $fcc0 + +; 64-C-DAG: addiu $[[T0:2]], $zero, 0 +; 64-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 64-C-DAG: c.ueq.s $f12, $f13 +; 64-C-DAG: movt $[[T0]], $1, $fcc0 + +; 32-CMP-DAG: cmp.ueq.s $[[T0:f[0-9]+]], $f12, $f14 +; 32-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 32-CMP-DAG: andi $2, $[[T1]], 1 + +; 64-CMP-DAG: cmp.ueq.s $[[T0:f[0-9]+]], $f12, $f13 +; 64-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 64-CMP-DAG: andi $2, $[[T1]], 1 + + %1 = fcmp ueq float %a, %b + %2 = zext i1 %1 to i32 + ret i32 %2 +} + +define i32 @ugt_f32(float %a, float %b) nounwind { +; ALL-LABEL: ugt_f32: + +; 32-C-DAG: addiu $[[T0:2]], $zero, 0 +; 32-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 32-C-DAG: c.ole.s $f12, $f14 +; 32-C-DAG: movf $[[T0]], $1, $fcc0 + +; 64-C-DAG: addiu $[[T0:2]], $zero, 0 +; 64-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 64-C-DAG: c.ole.s $f12, $f13 +; 64-C-DAG: movf $[[T0]], $1, $fcc0 + +; 32-CMP-DAG: cmp.ult.s $[[T0:f[0-9]+]], $f14, $f12 +; 32-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 32-CMP-DAG: andi $2, $[[T1]], 1 + +; 64-CMP-DAG: cmp.ult.s $[[T0:f[0-9]+]], $f13, $f12 +; 64-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 64-CMP-DAG: andi $2, $[[T1]], 1 + + %1 = fcmp ugt float %a, %b + %2 = zext i1 %1 to i32 + ret i32 %2 +} + +define i32 @uge_f32(float %a, float %b) nounwind { +; ALL-LABEL: uge_f32: + +; 32-C-DAG: addiu $[[T0:2]], $zero, 0 +; 32-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 32-C-DAG: c.olt.s $f12, $f14 +; 32-C-DAG: movf $[[T0]], $1, $fcc0 + +; 64-C-DAG: addiu $[[T0:2]], $zero, 0 +; 64-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 64-C-DAG: c.olt.s $f12, $f13 +; 64-C-DAG: movf $[[T0]], $1, $fcc0 + +; 32-CMP-DAG: cmp.ule.s $[[T0:f[0-9]+]], $f14, $f12 +; 32-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 32-CMP-DAG: andi $2, $[[T1]], 1 + +; 64-CMP-DAG: cmp.ule.s $[[T0:f[0-9]+]], $f13, $f12 +; 64-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 64-CMP-DAG: andi $2, $[[T1]], 1 + + %1 = fcmp uge float %a, %b + %2 = zext i1 %1 to i32 + ret i32 %2 +} + +define i32 @ult_f32(float %a, float %b) nounwind { +; ALL-LABEL: ult_f32: + +; 32-C-DAG: addiu $[[T0:2]], $zero, 0 +; 32-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 32-C-DAG: c.ult.s $f12, $f14 +; 32-C-DAG: movt $[[T0]], $1, $fcc0 + +; 64-C-DAG: addiu $[[T0:2]], $zero, 0 +; 64-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 64-C-DAG: c.ult.s $f12, $f13 +; 64-C-DAG: movt $[[T0]], $1, $fcc0 + +; 32-CMP-DAG: cmp.ult.s $[[T0:f[0-9]+]], $f12, $f14 +; 32-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 32-CMP-DAG: andi $2, $[[T1]], 1 + +; 64-CMP-DAG: cmp.ult.s $[[T0:f[0-9]+]], $f12, $f13 +; 64-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 64-CMP-DAG: andi $2, $[[T1]], 1 + + %1 = fcmp ult float %a, %b + %2 = zext i1 %1 to i32 + ret i32 %2 +} + +define i32 @ule_f32(float %a, float %b) nounwind { +; ALL-LABEL: ule_f32: + +; 32-C-DAG: addiu $[[T0:2]], $zero, 0 +; 32-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 32-C-DAG: c.ule.s $f12, $f14 +; 32-C-DAG: movt $[[T0]], $1, $fcc0 + +; 64-C-DAG: addiu $[[T0:2]], $zero, 0 +; 64-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 64-C-DAG: c.ule.s $f12, $f13 +; 64-C-DAG: movt $[[T0]], $1, $fcc0 + +; 32-CMP-DAG: cmp.ule.s $[[T0:f[0-9]+]], $f12, $f14 +; 32-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 32-CMP-DAG: andi $2, $[[T1]], 1 + +; 64-CMP-DAG: cmp.ule.s $[[T0:f[0-9]+]], $f12, $f13 +; 64-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 64-CMP-DAG: andi $2, $[[T1]], 1 + + %1 = fcmp ule float %a, %b + %2 = zext i1 %1 to i32 + ret i32 %2 +} + +define i32 @une_f32(float %a, float %b) nounwind { +; ALL-LABEL: une_f32: + +; 32-C-DAG: addiu $[[T0:2]], $zero, 0 +; 32-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 32-C-DAG: c.eq.s $f12, $f14 +; 32-C-DAG: movf $[[T0]], $1, $fcc0 + +; 64-C-DAG: addiu $[[T0:2]], $zero, 0 +; 64-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 64-C-DAG: c.eq.s $f12, $f13 +; 64-C-DAG: movf $[[T0]], $1, $fcc0 + +; 32-CMP-DAG: cmp.eq.s $[[T0:f[0-9]+]], $f12, $f14 +; 32-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 32-CMP-DAG: not $[[T2:[0-9]+]], $[[T1]] +; 32-CMP-DAG: andi $2, $[[T2]], 1 + +; 64-CMP-DAG: cmp.eq.s $[[T0:f[0-9]+]], $f12, $f13 +; 64-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 64-CMP-DAG: not $[[T2:[0-9]+]], $[[T1]] +; 64-CMP-DAG: andi $2, $[[T2]], 1 + + %1 = fcmp une float %a, %b + %2 = zext i1 %1 to i32 + ret i32 %2 +} + +define i32 @uno_f32(float %a, float %b) nounwind { +; ALL-LABEL: uno_f32: + +; 32-C-DAG: addiu $[[T0:2]], $zero, 0 +; 32-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 32-C-DAG: c.un.s $f12, $f14 +; 32-C-DAG: movt $[[T0]], $1, $fcc0 + +; 64-C-DAG: addiu $[[T0:2]], $zero, 0 +; 64-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 64-C-DAG: c.un.s $f12, $f13 +; 64-C-DAG: movt $[[T0]], $1, $fcc0 + +; 32-CMP-DAG: cmp.un.s $[[T0:f[0-9]+]], $f12, $f14 +; 32-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 32-CMP-DAG: andi $2, $[[T1]], 1 + +; 64-CMP-DAG: cmp.un.s $[[T0:f[0-9]+]], $f12, $f13 +; 64-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 64-CMP-DAG: andi $2, $[[T1]], 1 + + %1 = fcmp uno float %a, %b + %2 = zext i1 %1 to i32 + ret i32 %2 +} + +define i32 @true_f32(float %a, float %b) nounwind { +; ALL-LABEL: true_f32: +; ALL: addiu $2, $zero, 1 + + %1 = fcmp true float %a, %b + %2 = zext i1 %1 to i32 + ret i32 %2 +} + +define i32 @false_f64(double %a, double %b) nounwind { +; ALL-LABEL: false_f64: +; ALL: addiu $2, $zero, 0 + + %1 = fcmp false double %a, %b + %2 = zext i1 %1 to i32 + ret i32 %2 +} + +define i32 @oeq_f64(double %a, double %b) nounwind { +; ALL-LABEL: oeq_f64: + +; 32-C-DAG: addiu $[[T0:2]], $zero, 0 +; 32-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 32-C-DAG: c.eq.d $f12, $f14 +; 32-C-DAG: movt $[[T0]], $1, $fcc0 + +; 64-C-DAG: addiu $[[T0:2]], $zero, 0 +; 64-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 64-C-DAG: c.eq.d $f12, $f13 +; 64-C-DAG: movt $[[T0]], $1, $fcc0 + +; 32-CMP-DAG: cmp.eq.d $[[T0:f[0-9]+]], $f12, $f14 +; 32-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 32-CMP-DAG: andi $2, $[[T1]], 1 + +; 64-CMP-DAG: cmp.eq.d $[[T0:f[0-9]+]], $f12, $f13 +; 64-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 64-CMP-DAG: andi $2, $[[T1]], 1 + + %1 = fcmp oeq double %a, %b + %2 = zext i1 %1 to i32 + ret i32 %2 +} + +define i32 @ogt_f64(double %a, double %b) nounwind { +; ALL-LABEL: ogt_f64: + +; 32-C-DAG: addiu $[[T0:2]], $zero, 0 +; 32-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 32-C-DAG: c.ule.d $f12, $f14 +; 32-C-DAG: movf $[[T0]], $1, $fcc0 + +; 64-C-DAG: addiu $[[T0:2]], $zero, 0 +; 64-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 64-C-DAG: c.ule.d $f12, $f13 +; 64-C-DAG: movf $[[T0]], $1, $fcc0 + +; 32-CMP-DAG: cmp.lt.d $[[T0:f[0-9]+]], $f14, $f12 +; 32-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 32-CMP-DAG: andi $2, $[[T1]], 1 + +; 64-CMP-DAG: cmp.lt.d $[[T0:f[0-9]+]], $f13, $f12 +; 64-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 64-CMP-DAG: andi $2, $[[T1]], 1 + + %1 = fcmp ogt double %a, %b + %2 = zext i1 %1 to i32 + ret i32 %2 +} + +define i32 @oge_f64(double %a, double %b) nounwind { +; ALL-LABEL: oge_f64: + +; 32-C-DAG: addiu $[[T0:2]], $zero, 0 +; 32-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 32-C-DAG: c.ult.d $f12, $f14 +; 32-C-DAG: movf $[[T0]], $1, $fcc0 + +; 64-C-DAG: addiu $[[T0:2]], $zero, 0 +; 64-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 64-C-DAG: c.ult.d $f12, $f13 +; 64-C-DAG: movf $[[T0]], $1, $fcc0 + +; 32-CMP-DAG: cmp.le.d $[[T0:f[0-9]+]], $f14, $f12 +; 32-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 32-CMP-DAG: andi $2, $[[T1]], 1 + +; 64-CMP-DAG: cmp.le.d $[[T0:f[0-9]+]], $f13, $f12 +; 64-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 64-CMP-DAG: andi $2, $[[T1]], 1 + + %1 = fcmp oge double %a, %b + %2 = zext i1 %1 to i32 + ret i32 %2 +} + +define i32 @olt_f64(double %a, double %b) nounwind { +; ALL-LABEL: olt_f64: + +; 32-C-DAG: addiu $[[T0:2]], $zero, 0 +; 32-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 32-C-DAG: c.olt.d $f12, $f14 +; 32-C-DAG: movt $[[T0]], $1, $fcc0 + +; 64-C-DAG: addiu $[[T0:2]], $zero, 0 +; 64-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 64-C-DAG: c.olt.d $f12, $f13 +; 64-C-DAG: movt $[[T0]], $1, $fcc0 + +; 32-CMP-DAG: cmp.lt.d $[[T0:f[0-9]+]], $f12, $f14 +; 32-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 32-CMP-DAG: andi $2, $[[T1]], 1 + +; 64-CMP-DAG: cmp.lt.d $[[T0:f[0-9]+]], $f12, $f13 +; 64-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 64-CMP-DAG: andi $2, $[[T1]], 1 + + %1 = fcmp olt double %a, %b + %2 = zext i1 %1 to i32 + ret i32 %2 +} + +define i32 @ole_f64(double %a, double %b) nounwind { +; ALL-LABEL: ole_f64: + +; 32-C-DAG: addiu $[[T0:2]], $zero, 0 +; 32-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 32-C-DAG: c.ole.d $f12, $f14 +; 32-C-DAG: movt $[[T0]], $1, $fcc0 + +; 64-C-DAG: addiu $[[T0:2]], $zero, 0 +; 64-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 64-C-DAG: c.ole.d $f12, $f13 +; 64-C-DAG: movt $[[T0]], $1, $fcc0 + +; 32-CMP-DAG: cmp.le.d $[[T0:f[0-9]+]], $f12, $f14 +; 32-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 32-CMP-DAG: andi $2, $[[T1]], 1 + +; 64-CMP-DAG: cmp.le.d $[[T0:f[0-9]+]], $f12, $f13 +; 64-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 64-CMP-DAG: andi $2, $[[T1]], 1 + + %1 = fcmp ole double %a, %b + %2 = zext i1 %1 to i32 + ret i32 %2 +} + +define i32 @one_f64(double %a, double %b) nounwind { +; ALL-LABEL: one_f64: + +; 32-C-DAG: addiu $[[T0:2]], $zero, 0 +; 32-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 32-C-DAG: c.ueq.d $f12, $f14 +; 32-C-DAG: movf $[[T0]], $1, $fcc0 + +; 64-C-DAG: addiu $[[T0:2]], $zero, 0 +; 64-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 64-C-DAG: c.ueq.d $f12, $f13 +; 64-C-DAG: movf $[[T0]], $1, $fcc0 + +; 32-CMP-DAG: cmp.ueq.d $[[T0:f[0-9]+]], $f12, $f14 +; 32-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 32-CMP-DAG: not $[[T2:[0-9]+]], $[[T1]] +; 32-CMP-DAG: andi $2, $[[T2]], 1 + +; 64-CMP-DAG: cmp.ueq.d $[[T0:f[0-9]+]], $f12, $f13 +; 64-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 64-CMP-DAG: not $[[T2:[0-9]+]], $[[T1]] +; 64-CMP-DAG: andi $2, $[[T2]], 1 + + %1 = fcmp one double %a, %b + %2 = zext i1 %1 to i32 + ret i32 %2 +} + +define i32 @ord_f64(double %a, double %b) nounwind { +; ALL-LABEL: ord_f64: + +; 32-C-DAG: addiu $[[T0:2]], $zero, 0 +; 32-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 32-C-DAG: c.un.d $f12, $f14 +; 32-C-DAG: movf $[[T0]], $1, $fcc0 + +; 64-C-DAG: addiu $[[T0:2]], $zero, 0 +; 64-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 64-C-DAG: c.un.d $f12, $f13 +; 64-C-DAG: movf $[[T0]], $1, $fcc0 + +; 32-CMP-DAG: cmp.un.d $[[T0:f[0-9]+]], $f12, $f14 +; 32-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 32-CMP-DAG: not $[[T2:[0-9]+]], $[[T1]] +; 32-CMP-DAG: andi $2, $[[T2]], 1 + +; 64-CMP-DAG: cmp.un.d $[[T0:f[0-9]+]], $f12, $f13 +; 64-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 64-CMP-DAG: not $[[T2:[0-9]+]], $[[T1]] +; 64-CMP-DAG: andi $2, $[[T2]], 1 + + %1 = fcmp ord double %a, %b + %2 = zext i1 %1 to i32 + ret i32 %2 +} + +define i32 @ueq_f64(double %a, double %b) nounwind { +; ALL-LABEL: ueq_f64: + +; 32-C-DAG: addiu $[[T0:2]], $zero, 0 +; 32-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 32-C-DAG: c.ueq.d $f12, $f14 +; 32-C-DAG: movt $[[T0]], $1, $fcc0 + +; 64-C-DAG: addiu $[[T0:2]], $zero, 0 +; 64-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 64-C-DAG: c.ueq.d $f12, $f13 +; 64-C-DAG: movt $[[T0]], $1, $fcc0 + +; 32-CMP-DAG: cmp.ueq.d $[[T0:f[0-9]+]], $f12, $f14 +; 32-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 32-CMP-DAG: andi $2, $[[T1]], 1 + +; 64-CMP-DAG: cmp.ueq.d $[[T0:f[0-9]+]], $f12, $f13 +; 64-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 64-CMP-DAG: andi $2, $[[T1]], 1 + + %1 = fcmp ueq double %a, %b + %2 = zext i1 %1 to i32 + ret i32 %2 +} + +define i32 @ugt_f64(double %a, double %b) nounwind { +; ALL-LABEL: ugt_f64: + +; 32-C-DAG: addiu $[[T0:2]], $zero, 0 +; 32-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 32-C-DAG: c.ole.d $f12, $f14 +; 32-C-DAG: movf $[[T0]], $1, $fcc0 + +; 64-C-DAG: addiu $[[T0:2]], $zero, 0 +; 64-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 64-C-DAG: c.ole.d $f12, $f13 +; 64-C-DAG: movf $[[T0]], $1, $fcc0 + +; 32-CMP-DAG: cmp.ult.d $[[T0:f[0-9]+]], $f14, $f12 +; 32-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 32-CMP-DAG: andi $2, $[[T1]], 1 + +; 64-CMP-DAG: cmp.ult.d $[[T0:f[0-9]+]], $f13, $f12 +; 64-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 64-CMP-DAG: andi $2, $[[T1]], 1 + + %1 = fcmp ugt double %a, %b + %2 = zext i1 %1 to i32 + ret i32 %2 +} + +define i32 @uge_f64(double %a, double %b) nounwind { +; ALL-LABEL: uge_f64: + +; 32-C-DAG: addiu $[[T0:2]], $zero, 0 +; 32-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 32-C-DAG: c.olt.d $f12, $f14 +; 32-C-DAG: movf $[[T0]], $1, $fcc0 + +; 64-C-DAG: addiu $[[T0:2]], $zero, 0 +; 64-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 64-C-DAG: c.olt.d $f12, $f13 +; 64-C-DAG: movf $[[T0]], $1, $fcc0 + +; 32-CMP-DAG: cmp.ule.d $[[T0:f[0-9]+]], $f14, $f12 +; 32-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 32-CMP-DAG: andi $2, $[[T1]], 1 + +; 64-CMP-DAG: cmp.ule.d $[[T0:f[0-9]+]], $f13, $f12 +; 64-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 64-CMP-DAG: andi $2, $[[T1]], 1 + + %1 = fcmp uge double %a, %b + %2 = zext i1 %1 to i32 + ret i32 %2 +} + +define i32 @ult_f64(double %a, double %b) nounwind { +; ALL-LABEL: ult_f64: + +; 32-C-DAG: addiu $[[T0:2]], $zero, 0 +; 32-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 32-C-DAG: c.ult.d $f12, $f14 +; 32-C-DAG: movt $[[T0]], $1, $fcc0 + +; 64-C-DAG: addiu $[[T0:2]], $zero, 0 +; 64-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 64-C-DAG: c.ult.d $f12, $f13 +; 64-C-DAG: movt $[[T0]], $1, $fcc0 + +; 32-CMP-DAG: cmp.ult.d $[[T0:f[0-9]+]], $f12, $f14 +; 32-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 32-CMP-DAG: andi $2, $[[T1]], 1 + +; 64-CMP-DAG: cmp.ult.d $[[T0:f[0-9]+]], $f12, $f13 +; 64-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 64-CMP-DAG: andi $2, $[[T1]], 1 + + %1 = fcmp ult double %a, %b + %2 = zext i1 %1 to i32 + ret i32 %2 +} + +define i32 @ule_f64(double %a, double %b) nounwind { +; ALL-LABEL: ule_f64: + +; 32-C-DAG: addiu $[[T0:2]], $zero, 0 +; 32-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 32-C-DAG: c.ule.d $f12, $f14 +; 32-C-DAG: movt $[[T0]], $1, $fcc0 + +; 64-C-DAG: addiu $[[T0:2]], $zero, 0 +; 64-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 64-C-DAG: c.ule.d $f12, $f13 +; 64-C-DAG: movt $[[T0]], $1, $fcc0 + +; 32-CMP-DAG: cmp.ule.d $[[T0:f[0-9]+]], $f12, $f14 +; 32-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 32-CMP-DAG: andi $2, $[[T1]], 1 + +; 64-CMP-DAG: cmp.ule.d $[[T0:f[0-9]+]], $f12, $f13 +; 64-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 64-CMP-DAG: andi $2, $[[T1]], 1 + + %1 = fcmp ule double %a, %b + %2 = zext i1 %1 to i32 + ret i32 %2 +} + +define i32 @une_f64(double %a, double %b) nounwind { +; ALL-LABEL: une_f64: + +; 32-C-DAG: addiu $[[T0:2]], $zero, 0 +; 32-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 32-C-DAG: c.eq.d $f12, $f14 +; 32-C-DAG: movf $[[T0]], $1, $fcc0 + +; 64-C-DAG: addiu $[[T0:2]], $zero, 0 +; 64-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 64-C-DAG: c.eq.d $f12, $f13 +; 64-C-DAG: movf $[[T0]], $1, $fcc0 + +; 32-CMP-DAG: cmp.eq.d $[[T0:f[0-9]+]], $f12, $f14 +; 32-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 32-CMP-DAG: not $[[T2:[0-9]+]], $[[T1]] +; 32-CMP-DAG: andi $2, $[[T2]], 1 + +; 64-CMP-DAG: cmp.eq.d $[[T0:f[0-9]+]], $f12, $f13 +; 64-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 64-CMP-DAG: not $[[T2:[0-9]+]], $[[T1]] +; 64-CMP-DAG: andi $2, $[[T2]], 1 + + %1 = fcmp une double %a, %b + %2 = zext i1 %1 to i32 + ret i32 %2 +} + +define i32 @uno_f64(double %a, double %b) nounwind { +; ALL-LABEL: uno_f64: + +; 32-C-DAG: addiu $[[T0:2]], $zero, 0 +; 32-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 32-C-DAG: c.un.d $f12, $f14 +; 32-C-DAG: movt $[[T0]], $1, $fcc0 + +; 64-C-DAG: addiu $[[T0:2]], $zero, 0 +; 64-C-DAG: addiu $[[T1:[0-9]+]], $zero, 1 +; 64-C-DAG: c.un.d $f12, $f13 +; 64-C-DAG: movt $[[T0]], $1, $fcc0 + +; 32-CMP-DAG: cmp.un.d $[[T0:f[0-9]+]], $f12, $f14 +; 32-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 32-CMP-DAG: andi $2, $[[T1]], 1 + +; 64-CMP-DAG: cmp.un.d $[[T0:f[0-9]+]], $f12, $f13 +; 64-CMP-DAG: mfc1 $[[T1:[0-9]+]], $[[T0]] +; 64-CMP-DAG: andi $2, $[[T1]], 1 + + %1 = fcmp uno double %a, %b + %2 = zext i1 %1 to i32 + ret i32 %2 +} + +define i32 @true_f64(double %a, double %b) nounwind { +; ALL-LABEL: true_f64: +; ALL: addiu $2, $zero, 1 + + %1 = fcmp true double %a, %b + %2 = zext i1 %1 to i32 + ret i32 %2 +} diff --git a/test/CodeGen/Mips/fcopysign.ll b/test/CodeGen/Mips/fcopysign.ll index 44c4117..3a9d9c7 100644 --- a/test/CodeGen/Mips/fcopysign.ll +++ b/test/CodeGen/Mips/fcopysign.ll @@ -17,7 +17,7 @@ entry: ; 32R2: ext $[[EXT:[0-9]+]], ${{[0-9]+}}, 31, 1 ; 32R2: ins $[[INS:[0-9]+]], $[[EXT]], 31, 1 -; 32R2: mtc1 $[[INS]], $f1 +; 32R2: mthc1 $[[INS]], $f0 ; 64: daddiu $[[T0:[0-9]+]], $zero, 1 ; 64: dsll $[[MSK1:[0-9]+]], $[[T0]], 63 diff --git a/test/CodeGen/Mips/fmadd1.ll b/test/CodeGen/Mips/fmadd1.ll index a9a8e21..271631e 100644 --- a/test/CodeGen/Mips/fmadd1.ll +++ b/test/CodeGen/Mips/fmadd1.ll @@ -5,15 +5,54 @@ ; IEEE 754 (1985) and IEEE 754 (2008). These instructions are therefore only ; available when -enable-no-nans-fp-math is given. -; RUN: llc < %s -march=mipsel -mcpu=mips32r2 -enable-no-nans-fp-math | FileCheck %s -check-prefix=32R2 -check-prefix=CHECK -; RUN: llc < %s -march=mips64el -mcpu=mips64r2 -mattr=n64 -enable-no-nans-fp-math | FileCheck %s -check-prefix=64R2 -check-prefix=CHECK -; RUN: llc < %s -march=mipsel -mcpu=mips32r2 | FileCheck %s -check-prefix=32R2NAN -check-prefix=CHECK -; RUN: llc < %s -march=mips64el -mcpu=mips64r2 -mattr=n64 | FileCheck %s -check-prefix=64R2NAN -check-prefix=CHECK +; RUN: llc < %s -march=mipsel -mcpu=mips32 -enable-no-nans-fp-math | FileCheck %s -check-prefix=ALL -check-prefix=32 -check-prefix=32-NONAN +; RUN: llc < %s -march=mipsel -mcpu=mips32r2 -enable-no-nans-fp-math | FileCheck %s -check-prefix=ALL -check-prefix=32R2 -check-prefix=32R2-NONAN +; RUN: llc < %s -march=mipsel -mcpu=mips32r6 -enable-no-nans-fp-math | FileCheck %s -check-prefix=ALL -check-prefix=32R6 -check-prefix=32R6-NONAN +; RUN: llc < %s -march=mips64el -mcpu=mips64 -mattr=n64 -enable-no-nans-fp-math | FileCheck %s -check-prefix=ALL -check-prefix=64 -check-prefix=64-NONAN +; RUN: llc < %s -march=mips64el -mcpu=mips64r2 -mattr=n64 -enable-no-nans-fp-math | FileCheck %s -check-prefix=ALL -check-prefix=64R2 -check-prefix=64R2-NONAN +; RUN: llc < %s -march=mips64el -mcpu=mips64r6 -mattr=n64 -enable-no-nans-fp-math | FileCheck %s -check-prefix=ALL -check-prefix=64R6 -check-prefix=64R6-NONAN +; RUN: llc < %s -march=mipsel -mcpu=mips32 | FileCheck %s -check-prefix=ALL -check-prefix=32 -check-prefix=32-NAN +; RUN: llc < %s -march=mipsel -mcpu=mips32r2 | FileCheck %s -check-prefix=ALL -check-prefix=32R2 -check-prefix=32R2-NAN +; RUN: llc < %s -march=mipsel -mcpu=mips32r6 | FileCheck %s -check-prefix=ALL -check-prefix=32R6 -check-prefix=32R6-NAN +; RUN: llc < %s -march=mips64el -mcpu=mips64 -mattr=n64 | FileCheck %s -check-prefix=ALL -check-prefix=64 -check-prefix=64-NAN +; RUN: llc < %s -march=mips64el -mcpu=mips64r2 -mattr=n64 | FileCheck %s -check-prefix=ALL -check-prefix=64R2 -check-prefix=64R2-NAN +; RUN: llc < %s -march=mips64el -mcpu=mips64r6 -mattr=n64 | FileCheck %s -check-prefix=ALL -check-prefix=64R6 -check-prefix=64R6-NAN define float @FOO0float(float %a, float %b, float %c) nounwind readnone { entry: -; CHECK-LABEL: FOO0float: -; CHECK: madd.s +; ALL-LABEL: FOO0float: + +; 32-DAG: mtc1 $6, $[[T0:f[0-9]+]] +; 32-DAG: mul.s $[[T1:f[0-9]+]], $f12, $f14 +; 32-DAG: add.s $[[T2:f[0-9]+]], $[[T1]], $[[T0]] +; 32-DAG: mtc1 $zero, $[[T2:f[0-9]+]] +; 32-DAG: add.s $f0, $[[T1]], $[[T2]] + +; 32R2: mtc1 $6, $[[T0:f[0-9]+]] +; 32R2: madd.s $[[T1:f[0-9]+]], $[[T0]], $f12, $f14 +; 32R2: mtc1 $zero, $[[T2:f[0-9]+]] +; 32R2: add.s $f0, $[[T1]], $[[T2]] + +; 32R6-DAG: mtc1 $6, $[[T0:f[0-9]+]] +; 32R6-DAG: mul.s $[[T1:f[0-9]+]], $f12, $f14 +; 32R6-DAG: add.s $[[T2:f[0-9]+]], $[[T1]], $[[T0]] +; 32R6-DAG: mtc1 $zero, $[[T2:f[0-9]+]] +; 32R6-DAG: add.s $f0, $[[T1]], $[[T2]] + +; 64-DAG: mul.s $[[T1:f[0-9]+]], $f12, $f13 +; 64-DAG: add.s $[[T2:f[0-9]+]], $[[T1]], $f14 +; 64-DAG: mtc1 $zero, $[[T2:f[0-9]+]] +; 64-DAG: add.s $f0, $[[T1]], $[[T2]] + +; 64R2: madd.s $[[T0:f[0-9]+]], $f14, $f12, $f13 +; 64R2: mtc1 $zero, $[[T1:f[0-9]+]] +; 64R2: add.s $f0, $[[T0]], $[[T1]] + +; 64R6-DAG: mul.s $[[T0:f[0-9]+]], $f12, $f13 +; 64R6-DAG: add.s $[[T1:f[0-9]+]], $[[T0]], $f14 +; 64R6-DAG: mtc1 $zero, $[[T2:f[0-9]+]] +; 64R6-DAG: add.s $f0, $[[T1]], $[[T2]] + %mul = fmul float %a, %b %add = fadd float %mul, %c %add1 = fadd float %add, 0.000000e+00 @@ -22,8 +61,39 @@ entry: define float @FOO1float(float %a, float %b, float %c) nounwind readnone { entry: -; CHECK-LABEL: FOO1float: -; CHECK: msub.s +; ALL-LABEL: FOO1float: + +; 32-DAG: mtc1 $6, $[[T0:f[0-9]+]] +; 32-DAG: mul.s $[[T1:f[0-9]+]], $f12, $f14 +; 32-DAG: sub.s $[[T2:f[0-9]+]], $[[T1]], $[[T0]] +; 32-DAG: mtc1 $zero, $[[T2:f[0-9]+]] +; 32-DAG: add.s $f0, $[[T1]], $[[T2]] + +; 32R2: mtc1 $6, $[[T0:f[0-9]+]] +; 32R2: msub.s $[[T1:f[0-9]+]], $[[T0]], $f12, $f14 +; 32R2: mtc1 $zero, $[[T2:f[0-9]+]] +; 32R2: add.s $f0, $[[T1]], $[[T2]] + +; 32R6-DAG: mtc1 $6, $[[T0:f[0-9]+]] +; 32R6-DAG: mul.s $[[T1:f[0-9]+]], $f12, $f14 +; 32R6-DAG: sub.s $[[T2:f[0-9]+]], $[[T1]], $[[T0]] +; 32R6-DAG: mtc1 $zero, $[[T2:f[0-9]+]] +; 32R6-DAG: add.s $f0, $[[T1]], $[[T2]] + +; 64-DAG: mul.s $[[T1:f[0-9]+]], $f12, $f13 +; 64-DAG: sub.s $[[T2:f[0-9]+]], $[[T1]], $f14 +; 64-DAG: mtc1 $zero, $[[T2:f[0-9]+]] +; 64-DAG: add.s $f0, $[[T1]], $[[T2]] + +; 64R2: msub.s $[[T0:f[0-9]+]], $f14, $f12, $f13 +; 64R2: mtc1 $zero, $[[T1:f[0-9]+]] +; 64R2: add.s $f0, $[[T0]], $[[T1]] + +; 64R6-DAG: mul.s $[[T0:f[0-9]+]], $f12, $f13 +; 64R6-DAG: sub.s $[[T1:f[0-9]+]], $[[T0]], $f14 +; 64R6-DAG: mtc1 $zero, $[[T2:f[0-9]+]] +; 64R6-DAG: add.s $f0, $[[T1]], $[[T2]] + %mul = fmul float %a, %b %sub = fsub float %mul, %c %add = fadd float %sub, 0.000000e+00 @@ -32,11 +102,44 @@ entry: define float @FOO2float(float %a, float %b, float %c) nounwind readnone { entry: -; CHECK-LABEL: FOO2float: -; 32R2: nmadd.s -; 64R2: nmadd.s -; 32R2NAN: madd.s -; 64R2NAN: madd.s +; ALL-LABEL: FOO2float: + +; 32-DAG: mtc1 $6, $[[T0:f[0-9]+]] +; 32-DAG: mul.s $[[T1:f[0-9]+]], $f12, $f14 +; 32-DAG: add.s $[[T2:f[0-9]+]], $[[T1]], $[[T0]] +; 32-DAG: mtc1 $zero, $[[T2:f[0-9]+]] +; 32-DAG: sub.s $f0, $[[T2]], $[[T1]] + +; 32R2-NONAN: mtc1 $6, $[[T0:f[0-9]+]] +; 32R2-NONAN: nmadd.s $f0, $[[T0]], $f12, $f14 + +; 32R2-NAN: mtc1 $6, $[[T0:f[0-9]+]] +; 32R2-NAN: madd.s $[[T1:f[0-9]+]], $[[T0]], $f12, $f14 +; 32R2-NAN: mtc1 $zero, $[[T2:f[0-9]+]] +; 32R2-NAN: sub.s $f0, $[[T2]], $[[T1]] + +; 32R6-DAG: mtc1 $6, $[[T0:f[0-9]+]] +; 32R6-DAG: mul.s $[[T1:f[0-9]+]], $f12, $f14 +; 32R6-DAG: add.s $[[T2:f[0-9]+]], $[[T1]], $[[T0]] +; 32R6-DAG: mtc1 $zero, $[[T2:f[0-9]+]] +; 32R6-DAG: sub.s $f0, $[[T2]], $[[T1]] + +; 64-DAG: mul.s $[[T1:f[0-9]+]], $f12, $f13 +; 64-DAG: add.s $[[T2:f[0-9]+]], $[[T1]], $f14 +; 64-DAG: mtc1 $zero, $[[T2:f[0-9]+]] +; 64-DAG: sub.s $f0, $[[T2]], $[[T1]] + +; 64R2-NONAN: nmadd.s $f0, $f14, $f12, $f13 + +; 64R2-NAN: madd.s $[[T0:f[0-9]+]], $f14, $f12, $f13 +; 64R2-NAN: mtc1 $zero, $[[T1:f[0-9]+]] +; 64R2-NAN: sub.s $f0, $[[T1]], $[[T0]] + +; 64R6-DAG: mul.s $[[T1:f[0-9]+]], $f12, $f13 +; 64R6-DAG: add.s $[[T2:f[0-9]+]], $[[T1]], $f14 +; 64R6-DAG: mtc1 $zero, $[[T2:f[0-9]+]] +; 64R6-DAG: sub.s $f0, $[[T2]], $[[T1]] + %mul = fmul float %a, %b %add = fadd float %mul, %c %sub = fsub float 0.000000e+00, %add @@ -45,11 +148,36 @@ entry: define float @FOO3float(float %a, float %b, float %c) nounwind readnone { entry: -; CHECK-LABEL: FOO3float: -; 32R2: nmsub.s -; 64R2: nmsub.s -; 32R2NAN: msub.s -; 64R2NAN: msub.s +; ALL-LABEL: FOO3float: + +; 32-DAG: mtc1 $6, $[[T0:f[0-9]+]] +; 32-DAG: mul.s $[[T1:f[0-9]+]], $f12, $f14 +; 32-DAG: sub.s $[[T2:f[0-9]+]], $[[T1]], $[[T0]] +; 32-DAG: mtc1 $zero, $[[T2:f[0-9]+]] +; 32-DAG: sub.s $f0, $[[T2]], $[[T1]] + +; 32R2-NONAN: mtc1 $6, $[[T0:f[0-9]+]] +; 32R2-NONAN: nmsub.s $f0, $[[T0]], $f12, $f14 + +; 32R2-NAN: mtc1 $6, $[[T0:f[0-9]+]] +; 32R2-NAN: msub.s $[[T1:f[0-9]+]], $[[T0]], $f12, $f14 +; 32R2-NAN: mtc1 $zero, $[[T2:f[0-9]+]] +; 32R2-NAN: sub.s $f0, $[[T2]], $[[T1]] + +; 64-DAG: mul.s $[[T1:f[0-9]+]], $f12, $f13 +; 64-DAG: sub.s $[[T2:f[0-9]+]], $[[T1]], $f14 +; 64-DAG: mtc1 $zero, $[[T2:f[0-9]+]] +; 64-DAG: sub.s $f0, $[[T2]], $[[T1]] + +; 64R2-NAN: msub.s $[[T0:f[0-9]+]], $f14, $f12, $f13 +; 64R2-NAN: mtc1 $zero, $[[T1:f[0-9]+]] +; 64R2-NAN: sub.s $f0, $[[T1]], $[[T0]] + +; 64R6-DAG: mul.s $[[T1:f[0-9]+]], $f12, $f13 +; 64R6-DAG: sub.s $[[T2:f[0-9]+]], $[[T1]], $f14 +; 64R6-DAG: mtc1 $zero, $[[T2:f[0-9]+]] +; 64R6-DAG: sub.s $f0, $[[T2]], $[[T1]] + %mul = fmul float %a, %b %sub = fsub float %mul, %c %sub1 = fsub float 0.000000e+00, %sub @@ -58,8 +186,40 @@ entry: define double @FOO10double(double %a, double %b, double %c) nounwind readnone { entry: -; CHECK-LABEL: FOO10double: -; CHECK: madd.d +; ALL-LABEL: FOO10double: + +; 32-DAG: ldc1 $[[T0:f[0-9]+]], 16($sp) +; 32-DAG: mul.d $[[T1:f[0-9]+]], $f12, $f14 +; 32-DAG: add.d $[[T2:f[0-9]+]], $[[T1]], $[[T0]] +; 32-DAG: mtc1 $zero, $[[T2:f[0-9]+]] +; 32-DAG: add.d $f0, $[[T1]], $[[T2]] + +; 32R2: ldc1 $[[T0:f[0-9]+]], 16($sp) +; 32R2: madd.d $[[T1:f[0-9]+]], $[[T0]], $f12, $f14 +; 32R2: mtc1 $zero, $[[T2:f[0-9]+]] +; 32R2: mthc1 $zero, $[[T2]] +; 32R2: add.d $f0, $[[T1]], $[[T2]] + +; 32R6-DAG: ldc1 $[[T0:f[0-9]+]], 16($sp) +; 32R6-DAG: mul.d $[[T1:f[0-9]+]], $f12, $f14 +; 32R6-DAG: add.d $[[T2:f[0-9]+]], $[[T1]], $[[T0]] +; 32R6-DAG: mtc1 $zero, $[[T2:f[0-9]+]] +; 32R6-DAG: add.d $f0, $[[T1]], $[[T2]] + +; 64-DAG: mul.d $[[T1:f[0-9]+]], $f12, $f13 +; 64-DAG: add.d $[[T2:f[0-9]+]], $[[T1]], $f14 +; 64-DAG: dmtc1 $zero, $[[T2:f[0-9]+]] +; 64-DAG: add.d $f0, $[[T1]], $[[T2]] + +; 64R2: madd.d $[[T0:f[0-9]+]], $f14, $f12, $f13 +; 64R2: mtc1 $zero, $[[T1:f[0-9]+]] +; 64R2: add.d $f0, $[[T0]], $[[T1]] + +; 64R6-DAG: mul.d $[[T1:f[0-9]+]], $f12, $f13 +; 64R6-DAG: add.d $[[T2:f[0-9]+]], $[[T1]], $f14 +; 64R6-DAG: dmtc1 $zero, $[[T2:f[0-9]+]] +; 64R6-DAG: add.d $f0, $[[T1]], $[[T2]] + %mul = fmul double %a, %b %add = fadd double %mul, %c %add1 = fadd double %add, 0.000000e+00 @@ -68,8 +228,40 @@ entry: define double @FOO11double(double %a, double %b, double %c) nounwind readnone { entry: -; CHECK-LABEL: FOO11double: -; CHECK: msub.d +; ALL-LABEL: FOO11double: + +; 32-DAG: ldc1 $[[T0:f[0-9]+]], 16($sp) +; 32-DAG: mul.d $[[T1:f[0-9]+]], $f12, $f14 +; 32-DAG: sub.d $[[T2:f[0-9]+]], $[[T1]], $[[T0]] +; 32-DAG: mtc1 $zero, $[[T2:f[0-9]+]] +; 32-DAG: add.d $f0, $[[T1]], $[[T2]] + +; 32R2: ldc1 $[[T0:f[0-9]+]], 16($sp) +; 32R2: msub.d $[[T1:f[0-9]+]], $[[T0]], $f12, $f14 +; 32R2: mtc1 $zero, $[[T2:f[0-9]+]] +; 32R2: mthc1 $zero, $[[T2]] +; 32R2: add.d $f0, $[[T1]], $[[T2]] + +; 32R6-DAG: ldc1 $[[T0:f[0-9]+]], 16($sp) +; 32R6-DAG: mul.d $[[T1:f[0-9]+]], $f12, $f14 +; 32R6-DAG: sub.d $[[T2:f[0-9]+]], $[[T1]], $[[T0]] +; 32R6-DAG: mtc1 $zero, $[[T2:f[0-9]+]] +; 32R6-DAG: add.d $f0, $[[T1]], $[[T2]] + +; 64-DAG: mul.d $[[T1:f[0-9]+]], $f12, $f13 +; 64-DAG: sub.d $[[T2:f[0-9]+]], $[[T1]], $f14 +; 64-DAG: dmtc1 $zero, $[[T2:f[0-9]+]] +; 64-DAG: add.d $f0, $[[T1]], $[[T2]] + +; 64R2: msub.d $[[T0:f[0-9]+]], $f14, $f12, $f13 +; 64R2: mtc1 $zero, $[[T1:f[0-9]+]] +; 64R2: add.d $f0, $[[T0]], $[[T1]] + +; 64R6-DAG: mul.d $[[T1:f[0-9]+]], $f12, $f13 +; 64R6-DAG: sub.d $[[T2:f[0-9]+]], $[[T1]], $f14 +; 64R6-DAG: dmtc1 $zero, $[[T2:f[0-9]+]] +; 64R6-DAG: add.d $f0, $[[T1]], $[[T2]] + %mul = fmul double %a, %b %sub = fsub double %mul, %c %add = fadd double %sub, 0.000000e+00 @@ -78,11 +270,45 @@ entry: define double @FOO12double(double %a, double %b, double %c) nounwind readnone { entry: -; CHECK-LABEL: FOO12double: -; 32R2: nmadd.d -; 64R2: nmadd.d -; 32R2NAN: madd.d -; 64R2NAN: madd.d +; ALL-LABEL: FOO12double: + +; 32-DAG: ldc1 $[[T0:f[0-9]+]], 16($sp) +; 32-DAG: mul.d $[[T1:f[0-9]+]], $f12, $f14 +; 32-DAG: add.d $[[T2:f[0-9]+]], $[[T1]], $[[T0]] +; 32-DAG: mtc1 $zero, $[[T2:f[0-9]+]] +; 32-DAG: sub.d $f0, $[[T2]], $[[T1]] + +; 32R2-NONAN: ldc1 $[[T0:f[0-9]+]], 16($sp) +; 32R2-NONAN: nmadd.d $f0, $[[T0]], $f12, $f14 + +; 32R2-NAN: ldc1 $[[T0:f[0-9]+]], 16($sp) +; 32R2-NAN: madd.d $[[T1:f[0-9]+]], $[[T0]], $f12, $f14 +; 32R2-NAN: mtc1 $zero, $[[T2:f[0-9]+]] +; 32R2-NAN: mthc1 $zero, $[[T2]] +; 32R2-NAN: sub.d $f0, $[[T2]], $[[T1]] + +; 32R6-DAG: ldc1 $[[T0:f[0-9]+]], 16($sp) +; 32R6-DAG: mul.d $[[T1:f[0-9]+]], $f12, $f14 +; 32R6-DAG: add.d $[[T2:f[0-9]+]], $[[T1]], $[[T0]] +; 32R6-DAG: mtc1 $zero, $[[T2:f[0-9]+]] +; 32R6-DAG: sub.d $f0, $[[T2]], $[[T1]] + +; 64-DAG: mul.d $[[T1:f[0-9]+]], $f12, $f13 +; 64-DAG: add.d $[[T2:f[0-9]+]], $[[T1]], $f14 +; 64-DAG: dmtc1 $zero, $[[T2:f[0-9]+]] +; 64-DAG: sub.d $f0, $[[T2]], $[[T1]] + +; 64R2-NONAN: nmadd.d $f0, $f14, $f12, $f13 + +; 64R2-NAN: madd.d $[[T0:f[0-9]+]], $f14, $f12, $f13 +; 64R2-NAN: mtc1 $zero, $[[T1:f[0-9]+]] +; 64R2-NAN: sub.d $f0, $[[T1]], $[[T0]] + +; 64R6-DAG: mul.d $[[T1:f[0-9]+]], $f12, $f13 +; 64R6-DAG: add.d $[[T2:f[0-9]+]], $[[T1]], $f14 +; 64R6-DAG: dmtc1 $zero, $[[T2:f[0-9]+]] +; 64R6-DAG: sub.d $f0, $[[T2]], $[[T1]] + %mul = fmul double %a, %b %add = fadd double %mul, %c %sub = fsub double 0.000000e+00, %add @@ -91,11 +317,45 @@ entry: define double @FOO13double(double %a, double %b, double %c) nounwind readnone { entry: -; CHECK-LABEL: FOO13double: -; 32R2: nmsub.d -; 64R2: nmsub.d -; 32R2NAN: msub.d -; 64R2NAN: msub.d +; ALL-LABEL: FOO13double: + +; 32-DAG: ldc1 $[[T0:f[0-9]+]], 16($sp) +; 32-DAG: mul.d $[[T1:f[0-9]+]], $f12, $f14 +; 32-DAG: sub.d $[[T2:f[0-9]+]], $[[T1]], $[[T0]] +; 32-DAG: mtc1 $zero, $[[T2:f[0-9]+]] +; 32-DAG: sub.d $f0, $[[T2]], $[[T1]] + +; 32R2-NONAN: ldc1 $[[T0:f[0-9]+]], 16($sp) +; 32R2-NONAN: nmsub.d $f0, $[[T0]], $f12, $f14 + +; 32R2-NAN: ldc1 $[[T0:f[0-9]+]], 16($sp) +; 32R2-NAN: msub.d $[[T1:f[0-9]+]], $[[T0]], $f12, $f14 +; 32R2-NAN: mtc1 $zero, $[[T2:f[0-9]+]] +; 32R2-NAN: mthc1 $zero, $[[T2]] +; 32R2-NAN: sub.d $f0, $[[T2]], $[[T1]] + +; 32R6-DAG: ldc1 $[[T0:f[0-9]+]], 16($sp) +; 32R6-DAG: mul.d $[[T1:f[0-9]+]], $f12, $f14 +; 32R6-DAG: sub.d $[[T2:f[0-9]+]], $[[T1]], $[[T0]] +; 32R6-DAG: mtc1 $zero, $[[T2:f[0-9]+]] +; 32R6-DAG: sub.d $f0, $[[T2]], $[[T1]] + +; 64-DAG: mul.d $[[T1:f[0-9]+]], $f12, $f13 +; 64-DAG: sub.d $[[T2:f[0-9]+]], $[[T1]], $f14 +; 64-DAG: dmtc1 $zero, $[[T2:f[0-9]+]] +; 64-DAG: sub.d $f0, $[[T2]], $[[T1]] + +; 64R2-NONAN: nmsub.d $f0, $f14, $f12, $f13 + +; 64R2-NAN: msub.d $[[T0:f[0-9]+]], $f14, $f12, $f13 +; 64R2-NAN: mtc1 $zero, $[[T1:f[0-9]+]] +; 64R2-NAN: sub.d $f0, $[[T1]], $[[T0]] + +; 64R6-DAG: mul.d $[[T1:f[0-9]+]], $f12, $f13 +; 64R6-DAG: sub.d $[[T2:f[0-9]+]], $[[T1]], $f14 +; 64R6-DAG: dmtc1 $zero, $[[T2:f[0-9]+]] +; 64R6-DAG: sub.d $f0, $[[T2]], $[[T1]] + %mul = fmul double %a, %b %sub = fsub double %mul, %c %sub1 = fsub double 0.000000e+00, %sub diff --git a/test/CodeGen/Mips/fp-indexed-ls.ll b/test/CodeGen/Mips/fp-indexed-ls.ll index d8c37e7..787e131 100644 --- a/test/CodeGen/Mips/fp-indexed-ls.ll +++ b/test/CodeGen/Mips/fp-indexed-ls.ll @@ -1,6 +1,13 @@ -; RUN: llc -march=mipsel -mcpu=mips32r2 < %s | FileCheck %s -; RUN: llc -mtriple=mipsel-none-nacl-gnu -mcpu=mips32r2 < %s \ -; RUN: | FileCheck %s -check-prefix=CHECK-NACL +; RUN: llc -march=mipsel -mcpu=mips32 < %s | FileCheck %s -check-prefix=ALL -check-prefix=MIPS32R1 +; RUN: llc -march=mipsel -mcpu=mips32r2 < %s | FileCheck %s -check-prefix=ALL -check-prefix=MIPS32R2 +; RUN: llc -march=mipsel -mcpu=mips32r6 < %s | FileCheck %s -check-prefix=ALL -check-prefix=MIPS32R6 +; RUN: llc -march=mips64el -mcpu=mips4 -mattr=n64 < %s | FileCheck %s -check-prefix=ALL -check-prefix=MIPS4 +; RUN: llc -march=mips64el -mcpu=mips64 -mattr=n64 < %s | FileCheck %s -check-prefix=ALL -check-prefix=MIPS4 +; RUN: llc -march=mips64el -mcpu=mips64r2 -mattr=n64 < %s | FileCheck %s -check-prefix=ALL -check-prefix=MIPS4 +; RUN: llc -march=mips64el -mcpu=mips64r6 -mattr=n64 < %s | FileCheck %s -check-prefix=ALL -check-prefix=MIPS64R6 + +; Check that [ls][dwu]xc1 are not emitted for nacl. +; RUN: llc -mtriple=mipsel-none-nacl-gnu -mcpu=mips32r2 < %s | FileCheck %s -check-prefix=CHECK-NACL %struct.S = type <{ [4 x float] }> %struct.S2 = type <{ [4 x double] }> @@ -14,8 +21,30 @@ define float @foo0(float* nocapture %b, i32 %o) nounwind readonly { entry: -; CHECK: lwxc1 +; ALL-LABEL: foo0: + +; MIPS32R1: sll $[[T1:[0-9]+]], $5, 2 +; MIPS32R1: addu $[[T3:[0-9]+]], $4, $[[T1]] +; MIPS32R1: lwc1 $f0, 0($[[T3]]) + +; MIPS32R2: sll $[[T1:[0-9]+]], $5, 2 +; MIPS32R2: lwxc1 $f0, $[[T1]]($4) + +; MIPS32R6: sll $[[T1:[0-9]+]], $5, 2 +; MIPS32R6: addu $[[T3:[0-9]+]], $4, $[[T1]] +; MIPS32R6: lwc1 $f0, 0($[[T3]]) + +; MIPS4: sll $[[T0:[0-9]+]], $5, 0 +; MIPS4: dsll $[[T1:[0-9]+]], $[[T0]], 2 +; MIPS4: lwxc1 $f0, $[[T1]]($4) + +; MIPS64R6: sll $[[T0:[0-9]+]], $5, 0 +; MIPS64R6: dsll $[[T1:[0-9]+]], $[[T0]], 2 +; MIPS64R6: daddu $[[T3:[0-9]+]], $4, $[[T1]] +; MIPS64R6: lwc1 $f0, 0($[[T3]]) + ; CHECK-NACL-NOT: lwxc1 + %arrayidx = getelementptr inbounds float* %b, i32 %o %0 = load float* %arrayidx, align 4 ret float %0 @@ -23,8 +52,30 @@ entry: define double @foo1(double* nocapture %b, i32 %o) nounwind readonly { entry: -; CHECK: ldxc1 +; ALL-LABEL: foo1: + +; MIPS32R1: sll $[[T1:[0-9]+]], $5, 3 +; MIPS32R1: addu $[[T3:[0-9]+]], $4, $[[T1]] +; MIPS32R1: ldc1 $f0, 0($[[T3]]) + +; MIPS32R2: sll $[[T1:[0-9]+]], $5, 3 +; MIPS32R2: ldxc1 $f0, $[[T1]]($4) + +; MIPS32R6: sll $[[T1:[0-9]+]], $5, 3 +; MIPS32R6: addu $[[T3:[0-9]+]], $4, $[[T1]] +; MIPS32R6: ldc1 $f0, 0($[[T3]]) + +; MIPS4: sll $[[T0:[0-9]+]], $5, 0 +; MIPS4: dsll $[[T1:[0-9]+]], $[[T0]], 3 +; MIPS4: ldxc1 $f0, $[[T1]]($4) + +; MIPS64R6: sll $[[T0:[0-9]+]], $5, 0 +; MIPS64R6: dsll $[[T1:[0-9]+]], $[[T0]], 3 +; MIPS64R6: daddu $[[T3:[0-9]+]], $4, $[[T1]] +; MIPS64R6: ldc1 $f0, 0($[[T3]]) + ; CHECK-NACL-NOT: ldxc1 + %arrayidx = getelementptr inbounds double* %b, i32 %o %0 = load double* %arrayidx, align 8 ret double %0 @@ -32,7 +83,23 @@ entry: define float @foo2(i32 %b, i32 %c) nounwind readonly { entry: -; CHECK-NOT: luxc1 +; ALL-LABEL: foo2: + +; luxc1 did not exist in MIPS32r1 +; MIPS32R1-NOT: luxc1 + +; luxc1 is a misnomer since it aligns the given pointer downwards and performs +; an aligned load. We mustn't use it to handle unaligned loads. +; MIPS32R2-NOT: luxc1 + +; luxc1 was removed in MIPS32r6 +; MIPS32R6-NOT: luxc1 + +; MIPS4-NOT: luxc1 + +; luxc1 was removed in MIPS64r6 +; MIPS64R6-NOT: luxc1 + %arrayidx1 = getelementptr inbounds [4 x %struct.S]* @s, i32 0, i32 %b, i32 0, i32 %c %0 = load float* %arrayidx1, align 1 ret float %0 @@ -40,8 +107,28 @@ entry: define void @foo3(float* nocapture %b, i32 %o) nounwind { entry: -; CHECK: swxc1 +; ALL-LABEL: foo3: + +; MIPS32R1-DAG: lwc1 $[[T0:f0]], 0(${{[0-9]+}}) +; MIPS32R1-DAG: addu $[[T1:[0-9]+]], $4, ${{[0-9]+}} +; MIPS32R1-DAG: swc1 $[[T0]], 0($[[T1]]) + +; MIPS32R2: lwc1 $[[T0:f0]], 0(${{[0-9]+}}) +; MIPS32R2: swxc1 $[[T0]], ${{[0-9]+}}($4) + +; MIPS32R6-DAG: lwc1 $[[T0:f0]], 0(${{[0-9]+}}) +; MIPS32R6-DAG: addu $[[T1:[0-9]+]], $4, ${{[0-9]+}} +; MIPS32R6-DAG: swc1 $[[T0]], 0($[[T1]]) + +; MIPS4: lwc1 $[[T0:f0]], 0(${{[0-9]+}}) +; MIPS4: swxc1 $[[T0]], ${{[0-9]+}}($4) + +; MIPS64R6-DAG: lwc1 $[[T0:f0]], 0(${{[0-9]+}}) +; MIPS64R6-DAG: daddu $[[T1:[0-9]+]], $4, ${{[0-9]+}} +; MIPS64R6-DAG: swc1 $[[T0]], 0($[[T1]]) + ; CHECK-NACL-NOT: swxc1 + %0 = load float* @gf, align 4 %arrayidx = getelementptr inbounds float* %b, i32 %o store float %0, float* %arrayidx, align 4 @@ -50,8 +137,28 @@ entry: define void @foo4(double* nocapture %b, i32 %o) nounwind { entry: -; CHECK: sdxc1 +; ALL-LABEL: foo4: + +; MIPS32R1-DAG: ldc1 $[[T0:f0]], 0(${{[0-9]+}}) +; MIPS32R1-DAG: addu $[[T1:[0-9]+]], $4, ${{[0-9]+}} +; MIPS32R1-DAG: sdc1 $[[T0]], 0($[[T1]]) + +; MIPS32R2: ldc1 $[[T0:f0]], 0(${{[0-9]+}}) +; MIPS32R2: sdxc1 $[[T0]], ${{[0-9]+}}($4) + +; MIPS32R6-DAG: ldc1 $[[T0:f0]], 0(${{[0-9]+}}) +; MIPS32R6-DAG: addu $[[T1:[0-9]+]], $4, ${{[0-9]+}} +; MIPS32R6-DAG: sdc1 $[[T0]], 0($[[T1]]) + +; MIPS4: ldc1 $[[T0:f0]], 0(${{[0-9]+}}) +; MIPS4: sdxc1 $[[T0]], ${{[0-9]+}}($4) + +; MIPS64R6-DAG: ldc1 $[[T0:f0]], 0(${{[0-9]+}}) +; MIPS64R6-DAG: daddu $[[T1:[0-9]+]], $4, ${{[0-9]+}} +; MIPS64R6-DAG: sdc1 $[[T0]], 0($[[T1]]) + ; CHECK-NACL-NOT: sdxc1 + %0 = load double* @gd, align 8 %arrayidx = getelementptr inbounds double* %b, i32 %o store double %0, double* %arrayidx, align 8 @@ -60,7 +167,18 @@ entry: define void @foo5(i32 %b, i32 %c) nounwind { entry: -; CHECK-NOT: suxc1 +; ALL-LABEL: foo5: + +; MIPS32R1-NOT: suxc1 + +; MIPS32R2-NOT: suxc1 + +; MIPS32R6-NOT: suxc1 + +; MIPS4-NOT: suxc1 + +; MIPS64R6-NOT: suxc1 + %0 = load float* @gf, align 4 %arrayidx1 = getelementptr inbounds [4 x %struct.S]* @s, i32 0, i32 %b, i32 0, i32 %c store float %0, float* %arrayidx1, align 1 @@ -69,8 +187,18 @@ entry: define double @foo6(i32 %b, i32 %c) nounwind readonly { entry: -; CHECK: foo6 -; CHECK-NOT: luxc1 +; ALL-LABEL: foo6: + +; MIPS32R1-NOT: luxc1 + +; MIPS32R2-NOT: luxc1 + +; MIPS32R6-NOT: luxc1 + +; MIPS4-NOT: luxc1 + +; MIPS64R6-NOT: luxc1 + %arrayidx1 = getelementptr inbounds [4 x %struct.S2]* @s2, i32 0, i32 %b, i32 0, i32 %c %0 = load double* %arrayidx1, align 1 ret double %0 @@ -78,8 +206,18 @@ entry: define void @foo7(i32 %b, i32 %c) nounwind { entry: -; CHECK: foo7 -; CHECK-NOT: suxc1 +; ALL-LABEL: foo7: + +; MIPS32R1-NOT: suxc1 + +; MIPS32R2-NOT: suxc1 + +; MIPS32R6-NOT: suxc1 + +; MIPS4-NOT: suxc1 + +; MIPS64R6-NOT: suxc1 + %0 = load double* @gd, align 8 %arrayidx1 = getelementptr inbounds [4 x %struct.S2]* @s2, i32 0, i32 %b, i32 0, i32 %c store double %0, double* %arrayidx1, align 1 @@ -88,16 +226,36 @@ entry: define float @foo8() nounwind readonly { entry: -; CHECK: foo8 -; CHECK-NOT: luxc1 +; ALL-LABEL: foo8: + +; MIPS32R1-NOT: luxc1 + +; MIPS32R2-NOT: luxc1 + +; MIPS32R6-NOT: luxc1 + +; MIPS4-NOT: luxc1 + +; MIPS64R6-NOT: luxc1 + %0 = load float* getelementptr inbounds (%struct.S3* @s3, i32 0, i32 1), align 1 ret float %0 } define void @foo9(float %f) nounwind { entry: -; CHECK: foo9 -; CHECK-NOT: suxc1 +; ALL-LABEL: foo9: + +; MIPS32R1-NOT: suxc1 + +; MIPS32R2-NOT: suxc1 + +; MIPS32R6-NOT: suxc1 + +; MIPS4-NOT: suxc1 + +; MIPS64R6-NOT: suxc1 + store float %f, float* getelementptr inbounds (%struct.S3* @s3, i32 0, i32 1), align 1 ret void } diff --git a/test/CodeGen/Mips/fpbr.ll b/test/CodeGen/Mips/fpbr.ll index a136557..311b830 100644 --- a/test/CodeGen/Mips/fpbr.ll +++ b/test/CodeGen/Mips/fpbr.ll @@ -1,9 +1,25 @@ -; RUN: llc < %s -march=mipsel | FileCheck %s +; RUN: llc < %s -march=mipsel -mcpu=mips32 | FileCheck %s -check-prefix=ALL -check-prefix=FCC -check-prefix=32-FCC +; RUN: llc < %s -march=mipsel -mcpu=mips32r2 | FileCheck %s -check-prefix=ALL -check-prefix=FCC -check-prefix=32-FCC +; RUN: llc < %s -march=mipsel -mcpu=mips32r6 | FileCheck %s -check-prefix=ALL -check-prefix=GPR -check-prefix=32-GPR +; RUN: llc < %s -march=mips64el -mcpu=mips64 | FileCheck %s -check-prefix=ALL -check-prefix=FCC -check-prefix=64-FCC +; RUN: llc < %s -march=mips64el -mcpu=mips64r2 | FileCheck %s -check-prefix=ALL -check-prefix=FCC -check-prefix=64-FCC +; RUN: llc < %s -march=mips64el -mcpu=mips64r6 | FileCheck %s -check-prefix=ALL -check-prefix=GPR -check-prefix=64-GPR define void @func0(float %f2, float %f3) nounwind { entry: -; CHECK: c.eq.s -; CHECK: bc1f +; ALL-LABEL: func0: + +; 32-FCC: c.eq.s $f12, $f14 +; 64-FCC: c.eq.s $f12, $f13 +; FCC: bc1f $BB0_2 + +; 32-GPR: cmp.eq.s $[[FGRCC:f[0-9]+]], $f12, $f14 +; 64-GPR: cmp.eq.s $[[FGRCC:f[0-9]+]], $f12, $f13 +; GPR: mfc1 $[[GPRCC:[0-9]+]], $[[FGRCC:f[0-9]+]] +; FIXME: We ought to be able to transform not+bnez -> beqz +; GPR: not $[[GPRCC]], $[[GPRCC]] +; GPR: bnez $[[GPRCC]], $BB0_2 + %cmp = fcmp oeq float %f2, %f3 br i1 %cmp, label %if.then, label %if.else @@ -25,8 +41,18 @@ declare void @g1(...) define void @func1(float %f2, float %f3) nounwind { entry: -; CHECK: c.olt.s -; CHECK: bc1f +; ALL-LABEL: func1: + +; 32-FCC: c.olt.s $f12, $f14 +; 64-FCC: c.olt.s $f12, $f13 +; FCC: bc1f $BB1_2 + +; 32-GPR: cmp.ule.s $[[FGRCC:f[0-9]+]], $f14, $f12 +; 64-GPR: cmp.ule.s $[[FGRCC:f[0-9]+]], $f13, $f12 +; GPR: mfc1 $[[GPRCC:[0-9]+]], $[[FGRCC:f[0-9]+]] +; GPR-NOT: not $[[GPRCC]], $[[GPRCC]] +; GPR: bnez $[[GPRCC]], $BB1_2 + %cmp = fcmp olt float %f2, %f3 br i1 %cmp, label %if.then, label %if.else @@ -44,8 +70,18 @@ if.end: ; preds = %if.else, %if.then define void @func2(float %f2, float %f3) nounwind { entry: -; CHECK: c.ole.s -; CHECK: bc1t +; ALL-LABEL: func2: + +; 32-FCC: c.ole.s $f12, $f14 +; 64-FCC: c.ole.s $f12, $f13 +; FCC: bc1t $BB2_2 + +; 32-GPR: cmp.ult.s $[[FGRCC:f[0-9]+]], $f14, $f12 +; 64-GPR: cmp.ult.s $[[FGRCC:f[0-9]+]], $f13, $f12 +; GPR: mfc1 $[[GPRCC:[0-9]+]], $[[FGRCC:f[0-9]+]] +; GPR-NOT: not $[[GPRCC]], $[[GPRCC]] +; GPR: beqz $[[GPRCC]], $BB2_2 + %cmp = fcmp ugt float %f2, %f3 br i1 %cmp, label %if.else, label %if.then @@ -63,8 +99,19 @@ if.end: ; preds = %if.else, %if.then define void @func3(double %f2, double %f3) nounwind { entry: -; CHECK: c.eq.d -; CHECK: bc1f +; ALL-LABEL: func3: + +; 32-FCC: c.eq.d $f12, $f14 +; 64-FCC: c.eq.d $f12, $f13 +; FCC: bc1f $BB3_2 + +; 32-GPR: cmp.eq.d $[[FGRCC:f[0-9]+]], $f12, $f14 +; 64-GPR: cmp.eq.d $[[FGRCC:f[0-9]+]], $f12, $f13 +; GPR: mfc1 $[[GPRCC:[0-9]+]], $[[FGRCC:f[0-9]+]] +; FIXME: We ought to be able to transform not+bnez -> beqz +; GPR: not $[[GPRCC]], $[[GPRCC]] +; GPR: bnez $[[GPRCC]], $BB3_2 + %cmp = fcmp oeq double %f2, %f3 br i1 %cmp, label %if.then, label %if.else @@ -82,8 +129,18 @@ if.end: ; preds = %if.else, %if.then define void @func4(double %f2, double %f3) nounwind { entry: -; CHECK: c.olt.d -; CHECK: bc1f +; ALL-LABEL: func4: + +; 32-FCC: c.olt.d $f12, $f14 +; 64-FCC: c.olt.d $f12, $f13 +; FCC: bc1f $BB4_2 + +; 32-GPR: cmp.ule.d $[[FGRCC:f[0-9]+]], $f14, $f12 +; 64-GPR: cmp.ule.d $[[FGRCC:f[0-9]+]], $f13, $f12 +; GPR: mfc1 $[[GPRCC:[0-9]+]], $[[FGRCC:f[0-9]+]] +; GPR-NOT: not $[[GPRCC]], $[[GPRCC]] +; GPR: bnez $[[GPRCC]], $BB4_2 + %cmp = fcmp olt double %f2, %f3 br i1 %cmp, label %if.then, label %if.else @@ -101,8 +158,18 @@ if.end: ; preds = %if.else, %if.then define void @func5(double %f2, double %f3) nounwind { entry: -; CHECK: c.ole.d -; CHECK: bc1t +; ALL-LABEL: func5: + +; 32-FCC: c.ole.d $f12, $f14 +; 64-FCC: c.ole.d $f12, $f13 +; FCC: bc1t $BB5_2 + +; 32-GPR: cmp.ult.d $[[FGRCC:f[0-9]+]], $f14, $f12 +; 64-GPR: cmp.ult.d $[[FGRCC:f[0-9]+]], $f13, $f12 +; GPR: mfc1 $[[GPRCC:[0-9]+]], $[[FGRCC:f[0-9]+]] +; GPR-NOT: not $[[GPRCC]], $[[GPRCC]] +; GPR: beqz $[[GPRCC]], $BB5_2 + %cmp = fcmp ugt double %f2, %f3 br i1 %cmp, label %if.else, label %if.then diff --git a/test/CodeGen/Mips/inlineasm-cnstrnt-reg.ll b/test/CodeGen/Mips/inlineasm-cnstrnt-reg.ll index 9464918..a67ddce 100644 --- a/test/CodeGen/Mips/inlineasm-cnstrnt-reg.ll +++ b/test/CodeGen/Mips/inlineasm-cnstrnt-reg.ll @@ -1,6 +1,7 @@ ; Positive test for inline register constraints ; -; RUN: llc -march=mipsel < %s | FileCheck %s +; RUN: llc -march=mipsel -mcpu=mips32 < %s | FileCheck %s +; RUN: llc -march=mipsel -mcpu=mips32r2 < %s | FileCheck %s define i32 @main() nounwind { entry: diff --git a/test/CodeGen/Mips/lit.local.cfg b/test/CodeGen/Mips/lit.local.cfg index 1fa54b4..a3183a2 100644 --- a/test/CodeGen/Mips/lit.local.cfg +++ b/test/CodeGen/Mips/lit.local.cfg @@ -1,4 +1,3 @@ -targets = set(config.root.targets_to_build.split()) -if not 'Mips' in targets: +if not 'Mips' in config.root.targets: config.unsupported = True diff --git a/test/CodeGen/Mips/llvm-ir/call.ll b/test/CodeGen/Mips/llvm-ir/call.ll new file mode 100644 index 0000000..4cbf43c --- /dev/null +++ b/test/CodeGen/Mips/llvm-ir/call.ll @@ -0,0 +1,166 @@ +; Test the 'call' instruction and the tailcall variant. + +; FIXME: We should remove the need for -enable-mips-tail-calls +; RUN: llc -march=mips -mcpu=mips32 -enable-mips-tail-calls < %s | FileCheck %s -check-prefix=ALL -check-prefix=O32 +; RUN: llc -march=mips -mcpu=mips32r2 -enable-mips-tail-calls < %s | FileCheck %s -check-prefix=ALL -check-prefix=O32 +; RUN: llc -march=mips -mcpu=mips32r6 -enable-mips-tail-calls < %s | FileCheck %s -check-prefix=ALL -check-prefix=O32 +; RUN: llc -march=mips64 -mcpu=mips4 -enable-mips-tail-calls < %s | FileCheck %s -check-prefix=ALL -check-prefix=N64 +; RUN: llc -march=mips64 -mcpu=mips64 -enable-mips-tail-calls < %s | FileCheck %s -check-prefix=ALL -check-prefix=N64 +; RUN: llc -march=mips64 -mcpu=mips64r2 -enable-mips-tail-calls < %s | FileCheck %s -check-prefix=ALL -check-prefix=N64 +; RUN: llc -march=mips64 -mcpu=mips64r6 -enable-mips-tail-calls < %s | FileCheck %s -check-prefix=ALL -check-prefix=N64 + +declare void @extern_void_void() +declare i32 @extern_i32_void() +declare float @extern_float_void() + +define i32 @call_void_void() { +; ALL-LABEL: call_void_void: + +; O32: lw $[[TGT:[0-9]+]], %call16(extern_void_void)($gp) + +; N64: ld $[[TGT:[0-9]+]], %call16(extern_void_void)($gp) + +; ALL: jalr $[[TGT]] + + call void @extern_void_void() + ret i32 0 +} + +define i32 @call_i32_void() { +; ALL-LABEL: call_i32_void: + +; O32: lw $[[TGT:[0-9]+]], %call16(extern_i32_void)($gp) + +; N64: ld $[[TGT:[0-9]+]], %call16(extern_i32_void)($gp) + +; ALL: jalr $[[TGT]] + + %1 = call i32 @extern_i32_void() + %2 = add i32 %1, 1 + ret i32 %2 +} + +define float @call_float_void() { +; ALL-LABEL: call_float_void: + +; FIXME: Not sure why we don't use $gp directly on such a simple test. We should +; look into it at some point. +; O32: addu $[[GP:[0-9]+]], ${{[0-9]+}}, $25 +; O32: lw $[[TGT:[0-9]+]], %call16(extern_float_void)($[[GP]]) + +; N64: ld $[[TGT:[0-9]+]], %call16(extern_float_void)($gp) + +; ALL: jalr $[[TGT]] + +; O32: move $gp, $[[GP]] + + %1 = call float @extern_float_void() + %2 = fadd float %1, 1.0 + ret float %2 +} + +define void @musttail_call_void_void() { +; ALL-LABEL: musttail_call_void_void: + +; O32: lw $[[TGT:[0-9]+]], %call16(extern_void_void)($gp) + +; N64: ld $[[TGT:[0-9]+]], %call16(extern_void_void)($gp) + +; NOT-R6: jr $[[TGT]] +; R6: r6.jr $[[TGT]] + + musttail call void @extern_void_void() + ret void +} + +define i32 @musttail_call_i32_void() { +; ALL-LABEL: musttail_call_i32_void: + +; O32: lw $[[TGT:[0-9]+]], %call16(extern_i32_void)($gp) + +; N64: ld $[[TGT:[0-9]+]], %call16(extern_i32_void)($gp) + +; NOT-R6: jr $[[TGT]] +; R6: r6.jr $[[TGT]] + + %1 = musttail call i32 @extern_i32_void() + ret i32 %1 +} + +define float @musttail_call_float_void() { +; ALL-LABEL: musttail_call_float_void: + +; O32: lw $[[TGT:[0-9]+]], %call16(extern_float_void)($gp) + +; N64: ld $[[TGT:[0-9]+]], %call16(extern_float_void)($gp) + +; NOT-R6: jr $[[TGT]] +; R6: r6.jr $[[TGT]] + + %1 = musttail call float @extern_float_void() + ret float %1 +} + +define i32 @indirect_call_void_void(void ()* %addr) { +; ALL-LABEL: indirect_call_void_void: + +; ALL: move $25, $4 +; ALL: jalr $25 + + call void %addr() + ret i32 0 +} + +define i32 @indirect_call_i32_void(i32 ()* %addr) { +; ALL-LABEL: indirect_call_i32_void: + +; ALL: move $25, $4 +; ALL: jalr $25 + + %1 = call i32 %addr() + %2 = add i32 %1, 1 + ret i32 %2 +} + +define float @indirect_call_float_void(float ()* %addr) { +; ALL-LABEL: indirect_call_float_void: + +; ALL: move $25, $4 +; ALL: jalr $25 + + %1 = call float %addr() + %2 = fadd float %1, 1.0 + ret float %2 +} + +; We can't use 'musttail' here because the verifier is too conservative and +; prohibits any prototype difference. +define void @tail_indirect_call_void_void(void ()* %addr) { +; ALL-LABEL: tail_indirect_call_void_void: + +; ALL: move $25, $4 +; ALL: jr $25 + + tail call void %addr() + ret void +} + +define i32 @tail_indirect_call_i32_void(i32 ()* %addr) { +; ALL-LABEL: tail_indirect_call_i32_void: + +; ALL: move $25, $4 +; ALL: jr $25 + + %1 = tail call i32 %addr() + ret i32 %1 +} + +define float @tail_indirect_call_float_void(float ()* %addr) { +; ALL-LABEL: tail_indirect_call_float_void: + +; ALL: move $25, $4 +; ALL: jr $25 + + %1 = tail call float %addr() + ret float %1 +} diff --git a/test/CodeGen/Mips/llvm-ir/indirectbr.ll b/test/CodeGen/Mips/llvm-ir/indirectbr.ll new file mode 100644 index 0000000..d8fd787 --- /dev/null +++ b/test/CodeGen/Mips/llvm-ir/indirectbr.ll @@ -0,0 +1,34 @@ +; Test all important variants of the unconditional 'br' instruction. + +; RUN: llc -march=mips -mcpu=mips32 -asm-show-inst < %s | FileCheck %s -check-prefix=ALL -check-prefix=NOT-R6 +; RUN: llc -march=mips -mcpu=mips32r2 -asm-show-inst < %s | FileCheck %s -check-prefix=ALL -check-prefix=NOT-R6 +; RUN: llc -march=mips -mcpu=mips32r6 -asm-show-inst < %s | FileCheck %s -check-prefix=ALL -check-prefix=R6 +; RUN: llc -march=mips64 -mcpu=mips4 -asm-show-inst < %s | FileCheck %s -check-prefix=ALL -check-prefix=NOT-R6 +; RUN: llc -march=mips64 -mcpu=mips64 -asm-show-inst < %s | FileCheck %s -check-prefix=ALL -check-prefix=NOT-R6 +; RUN: llc -march=mips64 -mcpu=mips64r2 -asm-show-inst < %s | FileCheck %s -check-prefix=ALL -check-prefix=NOT-R6 +; RUN: llc -march=mips64 -mcpu=mips64r6 -asm-show-inst < %s | FileCheck %s -check-prefix=ALL -check-prefix=R6 + +define i32 @br(i8 *%addr) { +; ALL-LABEL: br: +; NOT-R6: jr $4 # <MCInst #{{[0-9]+}} JR +; R6: jr $4 # <MCInst #{{[0-9]+}} JALR + +; ALL: $BB0_1: # %L1 +; NOT-R6: jr $ra # <MCInst #{{[0-9]+}} JR +; R6: jr $ra # <MCInst #{{[0-9]+}} JALR +; ALL: addiu $2, $zero, 0 + +; ALL: $BB0_2: # %L2 +; NOT-R6: jr $ra # <MCInst #{{[0-9]+}} JR +; R6: jr $ra # <MCInst #{{[0-9]+}} JALR +; ALL: addiu $2, $zero, 1 + +entry: + indirectbr i8* %addr, [label %L1, label %L2] + +L1: + ret i32 0 + +L2: + ret i32 1 +} diff --git a/test/CodeGen/Mips/llvm-ir/ret.ll b/test/CodeGen/Mips/llvm-ir/ret.ll new file mode 100644 index 0000000..8f5b115 --- /dev/null +++ b/test/CodeGen/Mips/llvm-ir/ret.ll @@ -0,0 +1,205 @@ +; Test all important variants of the 'ret' instruction. +; +; For non-void returns it is necessary to have something to return so we also +; test constant generation here. +; +; We'll test pointer returns in a separate file since the relocation model +; affects it and it's undesirable to repeat the non-pointer returns for each +; relocation model. + +; RUN: llc -march=mips -mcpu=mips32 -asm-show-inst < %s | FileCheck %s -check-prefix=ALL -check-prefix=GPR32 -check-prefix=NO-MTHC1 -check-prefix=NOT-R6 +; RUN: llc -march=mips -mcpu=mips32r2 -asm-show-inst < %s | FileCheck %s -check-prefix=ALL -check-prefix=GPR32 -check-prefix=MTHC1 -check-prefix=NOT-R6 +; RUN: llc -march=mips -mcpu=mips32r6 -asm-show-inst < %s | FileCheck %s -check-prefix=ALL -check-prefix=GPR32 -check-prefix=MTHC1 -check-prefix=R6 +; RUN: llc -march=mips64 -mcpu=mips4 -asm-show-inst < %s | FileCheck %s -check-prefix=ALL -check-prefix=GPR64 -check-prefix=DMTC1 -check-prefix=NOT-R6 +; RUN: llc -march=mips64 -mcpu=mips64 -asm-show-inst < %s | FileCheck %s -check-prefix=ALL -check-prefix=GPR64 -check-prefix=DMTC1 -check-prefix=NOT-R6 +; RUN: llc -march=mips64 -mcpu=mips64r2 -asm-show-inst < %s | FileCheck %s -check-prefix=ALL -check-prefix=GPR64 -check-prefix=DMTC1 -check-prefix=NOT-R6 +; RUN: llc -march=mips64 -mcpu=mips64r6 -asm-show-inst < %s | FileCheck %s -check-prefix=ALL -check-prefix=GPR64 -check-prefix=DMTC1 -check-prefix=R6 + +define void @ret_void() { +; ALL-LABEL: ret_void: + +; NOT-R6-DAG: jr $ra # <MCInst #{{[0-9]+}} JR +; R6-DAG: jr $ra # <MCInst #{{[0-9]+}} JALR + + ret void +} + +define i8 @ret_i8() { +; ALL-LABEL: ret_i8: +; ALL-DAG: addiu $2, $zero, 3 + +; NOT-R6-DAG: jr $ra # <MCInst #{{[0-9]+}} JR +; R6-DAG: jr $ra # <MCInst #{{[0-9]+}} JALR + + ret i8 3 +} + +define i16 @ret_i16_3() { +; ALL-LABEL: ret_i16_3: +; ALL-DAG: addiu $2, $zero, 3 + +; NOT-R6-DAG: jr $ra # <MCInst #{{[0-9]+}} JR +; R6-DAG: jr $ra # <MCInst #{{[0-9]+}} JALR + + ret i16 3 +} + +define i16 @ret_i16_256() { +; ALL-LABEL: ret_i16_256: +; ALL-DAG: addiu $2, $zero, 256 + +; NOT-R6-DAG: jr $ra # <MCInst #{{[0-9]+}} JR +; R6-DAG: jr $ra # <MCInst #{{[0-9]+}} JALR + + ret i16 256 +} + +define i16 @ret_i16_257() { +; ALL-LABEL: ret_i16_257: +; ALL-DAG: addiu $2, $zero, 257 + +; NOT-R6-DAG: jr $ra # <MCInst #{{[0-9]+}} JR +; R6-DAG: jr $ra # <MCInst #{{[0-9]+}} JALR + + ret i16 257 +} + +define i32 @ret_i32_257() { +; ALL-LABEL: ret_i32_257: +; ALL-DAG: addiu $2, $zero, 257 + +; NOT-R6-DAG: jr $ra # <MCInst #{{[0-9]+}} JR +; R6-DAG: jr $ra # <MCInst #{{[0-9]+}} JALR + + ret i32 257 +} + +define i32 @ret_i32_65536() { +; ALL-LABEL: ret_i32_65536: +; ALL-DAG: lui $2, 1 + +; NOT-R6-DAG: jr $ra # <MCInst #{{[0-9]+}} JR +; R6-DAG: jr $ra # <MCInst #{{[0-9]+}} JALR + + ret i32 65536 +} + +define i32 @ret_i32_65537() { +; ALL-LABEL: ret_i32_65537: +; ALL: lui $[[T0:[0-9]+]], 1 +; ALL-DAG: ori $2, $[[T0]], 1 + +; NOT-R6-DAG: jr $ra # <MCInst #{{[0-9]+}} JR +; R6-DAG: jr $ra # <MCInst #{{[0-9]+}} JALR + + ret i32 65537 +} + +define i64 @ret_i64_65537() { +; ALL-LABEL: ret_i64_65537: +; ALL: lui $[[T0:[0-9]+]], 1 + +; GPR32-DAG: ori $3, $[[T0]], 1 +; GPR32-DAG: addiu $2, $zero, 0 + +; GPR64-DAG: daddiu $2, $[[T0]], 1 + +; NOT-R6-DAG: jr $ra # <MCInst #{{[0-9]+}} JR +; R6-DAG: jr $ra # <MCInst #{{[0-9]+}} JALR + + ret i64 65537 +} + +define i64 @ret_i64_281479271677952() { +; ALL-LABEL: ret_i64_281479271677952: +; ALL-DAG: lui $[[T0:[0-9]+]], 1 + +; GPR32-DAG: ori $2, $[[T0]], 1 +; GPR32-DAG: addiu $3, $zero, 0 + +; GPR64-DAG: daddiu $[[T1:[0-9]+]], $[[T0]], 1 +; GPR64-DAG: dsll $2, $[[T1]], 32 + +; NOT-R6-DAG: jr $ra # <MCInst #{{[0-9]+}} JR +; R6-DAG: jr $ra # <MCInst #{{[0-9]+}} JALR + + ret i64 281479271677952 +} + +define i64 @ret_i64_281479271809026() { +; ALL-LABEL: ret_i64_281479271809026: +; GPR32-DAG: lui $[[T0:[0-9]+]], 1 +; GPR32-DAG: lui $[[T1:[0-9]+]], 2 +; GPR32-DAG: ori $2, $[[T0]], 1 +; GPR32-DAG: ori $3, $[[T1]], 2 + +; GPR64-DAG: ori $[[T0:[0-9]+]], $zero, 32769 +; GPR64-DAG: dsll $[[T1:[0-9]+]], $[[T0]], 16 +; GPR64-DAG: daddiu $[[T0:[0-9]+]], $[[T0]], -32767 +; GPR64-DAG: dsll $[[T1:[0-9]+]], $[[T0]], 17 +; GPR64-DAG: daddiu $2, $[[T1]], 2 + +; NOT-R6-DAG: jr $ra # <MCInst #{{[0-9]+}} JR +; R6-DAG: jr $ra # <MCInst #{{[0-9]+}} JALR + + ret i64 281479271809026 +} + +define float @ret_float_0x0() { +; ALL-LABEL: ret_float_0x0: + +; NO-MTHC1-DAG: mtc1 $zero, $f0 + +; MTHC1-DAG: mtc1 $zero, $f0 + +; DMTC-DAG: dmtc1 $zero, $f0 + +; NOT-R6-DAG: jr $ra # <MCInst #{{[0-9]+}} JR +; R6-DAG: jr $ra # <MCInst #{{[0-9]+}} JALR + + ret float 0x0000000000000000 +} + +define float @ret_float_0x3() { +; ALL-LABEL: ret_float_0x3: + +; Use a constant pool +; O32-DAG: lwc1 $f0, %lo($CPI +; N64-DAG: lwc1 $f0, %got_ofst($CPI + +; NOT-R6-DAG: jr $ra # <MCInst #{{[0-9]+}} JR +; R6-DAG: jr $ra # <MCInst #{{[0-9]+}} JALR + +; float constants are written as double constants + ret float 0x36b8000000000000 +} + +define double @ret_double_0x0() { +; ALL-LABEL: ret_double_0x0: + +; NO-MTHC1-DAG: mtc1 $zero, $f0 +; NO-MTHC1-DAG: mtc1 $zero, $f1 + +; MTHC1-DAG: mtc1 $zero, $f0 +; MTHC1-DAG: mthc1 $zero, $f0 + +; DMTC-DAG: dmtc1 $zero, $f0 + +; NOT-R6-DAG: jr $ra # <MCInst #{{[0-9]+}} JR +; R6-DAG: jr $ra # <MCInst #{{[0-9]+}} JALR + + ret double 0x0000000000000000 +} + +define double @ret_double_0x3() { +; ALL-LABEL: ret_double_0x3: + +; Use a constant pool +; O32-DAG: ldc1 $f0, %lo($CPI +; N64-DAG: ldc1 $f0, %got_ofst($CPI + +; NOT-R6-DAG: jr $ra # <MCInst #{{[0-9]+}} JR +; R6-DAG: jr $ra # <MCInst #{{[0-9]+}} JALR + + ret double 0x0000000000000003 +} diff --git a/test/CodeGen/Mips/longbranch.ll b/test/CodeGen/Mips/longbranch.ll index c7fe6fd..a403744 100644 --- a/test/CodeGen/Mips/longbranch.ll +++ b/test/CodeGen/Mips/longbranch.ll @@ -7,6 +7,8 @@ ; RUN: < %s | FileCheck %s -check-prefix=N64 ; RUN: llc -march=mipsel -mcpu=mips32r2 -mattr=micromips \ ; RUN: -force-mips-long-branch -O3 < %s | FileCheck %s -check-prefix=MICROMIPS +; RUN: llc -mtriple=mipsel-none-nacl -force-mips-long-branch -O3 < %s \ +; RUN: | FileCheck %s -check-prefix=NACL @x = external global i32 @@ -126,4 +128,36 @@ end: ; MICROMIPS: $[[BB2]]: ; MICROMIPS: jr $ra ; MICROMIPS: nop + + +; Check the NaCl version. Check that sp change is not in the branch delay slot +; of "jr $1" instruction. Check that target of indirect branch "jr $1" is +; bundle aligned. + +; NACL: lui $[[R0:[0-9]+]], %hi(_gp_disp) +; NACL: addiu $[[R0]], $[[R0]], %lo(_gp_disp) +; NACL: bnez $4, $[[BB0:BB[0-9_]+]] +; NACL: addu $[[GP:[0-9]+]], $[[R0]], $25 + +; Check for long branch expansion: +; NACL: addiu $sp, $sp, -8 +; NACL-NEXT: sw $ra, 0($sp) +; NACL-NEXT: lui $1, %hi(($[[BB2:BB[0-9_]+]])-($[[BB1:BB[0-9_]+]])) +; NACL-NEXT: bal $[[BB1]] +; NACL-NEXT: addiu $1, $1, %lo(($[[BB2]])-($[[BB1]])) +; NACL-NEXT: $[[BB1]]: +; NACL-NEXT: addu $1, $ra, $1 +; NACL-NEXT: lw $ra, 0($sp) +; NACL-NEXT: addiu $sp, $sp, 8 +; NACL-NEXT: jr $1 +; NACL-NEXT: nop + +; NACL: $[[BB0]]: +; NACL: lw $[[R1:[0-9]+]], %got(x)($[[GP]]) +; NACL: addiu $[[R2:[0-9]+]], $zero, 1 +; NACL: sw $[[R2]], 0($[[R1]]) +; NACL: .align 4 +; NACL-NEXT: $[[BB2]]: +; NACL: jr $ra +; NACL: nop } diff --git a/test/CodeGen/Mips/madd-msub.ll b/test/CodeGen/Mips/madd-msub.ll index 0dbb2c2..8222967 100644 --- a/test/CodeGen/Mips/madd-msub.ll +++ b/test/CodeGen/Mips/madd-msub.ll @@ -1,9 +1,49 @@ -; RUN: llc -march=mips < %s | FileCheck %s -check-prefix=32 -; RUN: llc -march=mips -mattr=dsp < %s | FileCheck %s -check-prefix=DSP +; RUN: llc -march=mips -mcpu=mips32 < %s | FileCheck %s -check-prefix=ALL -check-prefix=32 +; RUN: llc -march=mips -mcpu=mips32r2 < %s | FileCheck %s -check-prefix=ALL -check-prefix=32 +; RUN: llc -march=mips -mcpu=mips32r6 < %s | FileCheck %s -check-prefix=ALL -check-prefix=32R6 +; RUN: llc -march=mips -mcpu=mips32 -mattr=dsp < %s | FileCheck %s -check-prefix=DSP +; RUN: llc -march=mips -mcpu=mips64 < %s | FileCheck %s -check-prefix=ALL -check-prefix=64 +; RUN: llc -march=mips -mcpu=mips64r2 < %s | FileCheck %s -check-prefix=ALL -check-prefix=64 +; RUN: llc -march=mips -mcpu=mips64r6 < %s | FileCheck %s -check-prefix=ALL -check-prefix=64R6 + +; FIXME: The MIPS16 test should check its output ; RUN: llc -march=mips -mcpu=mips16 < %s -; 32: madd ${{[0-9]+}} -; DSP: madd $ac +; ALL-LABEL: madd1: + +; 32-DAG: sra $[[T0:[0-9]+]], $6, 31 +; 32-DAG: mtlo $6 +; 32-DAG: [[m:m]]add ${{[45]}}, ${{[45]}} +; 32-DAG: [[m]]fhi $2 +; 32-DAG: [[m]]flo $3 + +; DSP-DAG: sra $[[T0:[0-9]+]], $6, 31 +; DSP-DAG: mtlo $[[AC:ac[0-3]+]], $6 +; DSP-DAG: madd $[[AC]], ${{[45]}}, ${{[45]}} +; DSP-DAG: mfhi $2, $[[AC]] +; DSP-DAG: mflo $3, $[[AC]] + +; 32R6-DAG: mul $[[T0:[0-9]+]], ${{[45]}}, ${{[45]}} +; 32R6-DAG: addu $[[T1:[0-9]+]], $[[T0]], $6 +; 32R6-DAG: sltu $[[T2:[0-9]+]], $[[T1]], $6 +; 32R6-DAG: sra $[[T3:[0-9]+]], $6, 31 +; 32R6-DAG: addu $[[T4:[0-9]+]], $[[T2]], $[[T3]] +; 32R6-DAG: muh $[[T5:[0-9]+]], ${{[45]}}, ${{[45]}} +; 32R6-DAG: addu $2, $[[T5]], $[[T4]] + +; 64-DAG: sll $[[T0:[0-9]+]], $4, 0 +; 64-DAG: sll $[[T1:[0-9]+]], $5, 0 +; 64-DAG: d[[m:m]]ult $[[T1]], $[[T0]] +; 64-DAG: [[m]]flo $[[T2:[0-9]+]] +; 64-DAG: sll $[[T3:[0-9]+]], $6, 0 +; 64-DAG: daddu $2, $[[T2]], $[[T3]] + +; 64R6-DAG: sll $[[T0:[0-9]+]], $4, 0 +; 64R6-DAG: sll $[[T1:[0-9]+]], $5, 0 +; 64R6-DAG: dmul $[[T2:[0-9]+]], $[[T1]], $[[T0]] +; 64R6-DAG: sll $[[T3:[0-9]+]], $6, 0 +; 64R6-DAG: daddu $2, $[[T2]], $[[T3]] + define i64 @madd1(i32 %a, i32 %b, i32 %c) nounwind readnone { entry: %conv = sext i32 %a to i64 @@ -14,8 +54,47 @@ entry: ret i64 %add } -; 32: maddu ${{[0-9]+}} -; DSP: maddu $ac +; ALL-LABEL: madd2: + +; FIXME: We don't really need this instruction +; 32-DAG: addiu $[[T0:[0-9]+]], $zero, 0 +; 32-DAG: mtlo $6 +; 32-DAG: [[m:m]]addu ${{[45]}}, ${{[45]}} +; 32-DAG: [[m]]fhi $2 +; 32-DAG: [[m]]flo $3 + +; DSP-DAG: addiu $[[T0:[0-9]+]], $zero, 0 +; DSP-DAG: mtlo $[[AC:ac[0-3]+]], $6 +; DSP-DAG: maddu $[[AC]], ${{[45]}}, ${{[45]}} +; DSP-DAG: mfhi $2, $[[AC]] +; DSP-DAG: mflo $3, $[[AC]] + +; 32R6-DAG: mul $[[T0:[0-9]+]], ${{[45]}}, ${{[45]}} +; 32R6-DAG: addu $[[T1:[0-9]+]], $[[T0]], $6 +; 32R6-DAG: sltu $[[T2:[0-9]+]], $[[T1]], $6 +; FIXME: There's a redundant move here. We should remove it +; 32R6-DAG: muhu $[[T3:[0-9]+]], ${{[45]}}, ${{[45]}} +; 32R6-DAG: addu $2, $[[T3]], $[[T2]] + +; 64-DAG: dsll $[[T0:[0-9]+]], $4, 32 +; 64-DAG: dsrl $[[T1:[0-9]+]], $[[T0]], 32 +; 64-DAG: dsll $[[T2:[0-9]+]], $5, 32 +; 64-DAG: dsrl $[[T3:[0-9]+]], $[[T2]], 32 +; 64-DAG: d[[m:m]]ult $[[T3]], $[[T1]] +; 64-DAG: [[m]]flo $[[T4:[0-9]+]] +; 64-DAG: dsll $[[T5:[0-9]+]], $6, 32 +; 64-DAG: dsrl $[[T6:[0-9]+]], $[[T5]], 32 +; 64-DAG: daddu $2, $[[T4]], $[[T6]] + +; 64R6-DAG: dsll $[[T0:[0-9]+]], $4, 32 +; 64R6-DAG: dsrl $[[T1:[0-9]+]], $[[T0]], 32 +; 64R6-DAG: dsll $[[T2:[0-9]+]], $5, 32 +; 64R6-DAG: dsrl $[[T3:[0-9]+]], $[[T2]], 32 +; 64R6-DAG: dmul $[[T4:[0-9]+]], $[[T3]], $[[T1]] +; 64R6-DAG: dsll $[[T5:[0-9]+]], $6, 32 +; 64R6-DAG: dsrl $[[T6:[0-9]+]], $[[T5]], 32 +; 64R6-DAG: daddu $2, $[[T4]], $[[T6]] + define i64 @madd2(i32 %a, i32 %b, i32 %c) nounwind readnone { entry: %conv = zext i32 %a to i64 @@ -26,8 +105,38 @@ entry: ret i64 %add } -; 32: madd ${{[0-9]+}} -; DSP: madd $ac +; ALL-LABEL: madd3: + +; 32-DAG: mthi $6 +; 32-DAG: mtlo $7 +; 32-DAG: [[m:m]]add ${{[45]}}, ${{[45]}} +; 32-DAG: [[m]]fhi $2 +; 32-DAG: [[m]]flo $3 + +; DSP-DAG: mthi $[[AC:ac[0-3]+]], $6 +; DSP-DAG: mtlo $[[AC]], $7 +; DSP-DAG: madd $[[AC]], ${{[45]}}, ${{[45]}} +; DSP-DAG: mfhi $2, $[[AC]] +; DSP-DAG: mflo $3, $[[AC]] + +; 32R6-DAG: mul $[[T0:[0-9]+]], ${{[45]}}, ${{[45]}} +; 32R6-DAG: addu $[[T1:[0-9]+]], $[[T0]], $7 +; 32R6-DAG: sltu $[[T2:[0-9]+]], $[[T1]], $7 +; 32R6-DAG: addu $[[T4:[0-9]+]], $[[T2]], $6 +; 32R6-DAG: muh $[[T5:[0-9]+]], ${{[45]}}, ${{[45]}} +; 32R6-DAG: addu $2, $[[T5]], $[[T4]] + +; 64-DAG: sll $[[T0:[0-9]+]], $4, 0 +; 64-DAG: sll $[[T1:[0-9]+]], $5, 0 +; 64-DAG: d[[m:m]]ult $[[T1]], $[[T0]] +; 64-DAG: [[m]]flo $[[T2:[0-9]+]] +; 64-DAG: daddu $2, $[[T2]], $6 + +; 64R6-DAG: sll $[[T0:[0-9]+]], $4, 0 +; 64R6-DAG: sll $[[T1:[0-9]+]], $5, 0 +; 64R6-DAG: dmul $[[T2:[0-9]+]], $[[T1]], $[[T0]] +; 64R6-DAG: daddu $2, $[[T2]], $6 + define i64 @madd3(i32 %a, i32 %b, i64 %c) nounwind readnone { entry: %conv = sext i32 %a to i64 @@ -37,8 +146,41 @@ entry: ret i64 %add } -; 32: msub ${{[0-9]+}} -; DSP: msub $ac +; ALL-LABEL: msub1: + +; 32-DAG: sra $[[T0:[0-9]+]], $6, 31 +; 32-DAG: mtlo $6 +; 32-DAG: [[m:m]]sub ${{[45]}}, ${{[45]}} +; 32-DAG: [[m]]fhi $2 +; 32-DAG: [[m]]flo $3 + +; DSP-DAG: sra $[[T0:[0-9]+]], $6, 31 +; DSP-DAG: mtlo $[[AC:ac[0-3]+]], $6 +; DSP-DAG: msub $[[AC]], ${{[45]}}, ${{[45]}} +; DSP-DAG: mfhi $2, $[[AC]] +; DSP-DAG: mflo $3, $[[AC]] + +; 32R6-DAG: muh $[[T0:[0-9]+]], ${{[45]}}, ${{[45]}} +; 32R6-DAG: mul $[[T1:[0-9]+]], ${{[45]}}, ${{[45]}} +; 32R6-DAG: sltu $[[T3:[0-9]+]], $6, $[[T1]] +; 32R6-DAG: addu $[[T4:[0-9]+]], $[[T3]], $[[T0]] +; 32R6-DAG: sra $[[T5:[0-9]+]], $6, 31 +; 32R6-DAG: subu $2, $[[T5]], $[[T4]] +; 32R6-DAG: subu $3, $6, $[[T1]] + +; 64-DAG: sll $[[T0:[0-9]+]], $4, 0 +; 64-DAG: sll $[[T1:[0-9]+]], $5, 0 +; 64-DAG: d[[m:m]]ult $[[T1]], $[[T0]] +; 64-DAG: [[m]]flo $[[T2:[0-9]+]] +; 64-DAG: sll $[[T3:[0-9]+]], $6, 0 +; 64-DAG: dsubu $2, $[[T3]], $[[T2]] + +; 64R6-DAG: sll $[[T0:[0-9]+]], $4, 0 +; 64R6-DAG: sll $[[T1:[0-9]+]], $5, 0 +; 64R6-DAG: dmul $[[T2:[0-9]+]], $[[T1]], $[[T0]] +; 64R6-DAG: sll $[[T3:[0-9]+]], $6, 0 +; 64R6-DAG: dsubu $2, $[[T3]], $[[T2]] + define i64 @msub1(i32 %a, i32 %b, i32 %c) nounwind readnone { entry: %conv = sext i32 %c to i64 @@ -49,8 +191,48 @@ entry: ret i64 %sub } -; 32: msubu ${{[0-9]+}} -; DSP: msubu $ac +; ALL-LABEL: msub2: + +; FIXME: We don't really need this instruction +; 32-DAG: addiu $[[T0:[0-9]+]], $zero, 0 +; 32-DAG: mtlo $6 +; 32-DAG: [[m:m]]subu ${{[45]}}, ${{[45]}} +; 32-DAG: [[m]]fhi $2 +; 32-DAG: [[m]]flo $3 + +; DSP-DAG: addiu $[[T0:[0-9]+]], $zero, 0 +; DSP-DAG: mtlo $[[AC:ac[0-3]+]], $6 +; DSP-DAG: msubu $[[AC]], ${{[45]}}, ${{[45]}} +; DSP-DAG: mfhi $2, $[[AC]] +; DSP-DAG: mflo $3, $[[AC]] + +; 32R6-DAG: muhu $[[T0:[0-9]+]], ${{[45]}}, ${{[45]}} +; 32R6-DAG: mul $[[T1:[0-9]+]], ${{[45]}}, ${{[45]}} + +; 32R6-DAG: sltu $[[T2:[0-9]+]], $6, $[[T1]] +; 32R6-DAG: addu $[[T3:[0-9]+]], $[[T2]], $[[T0]] +; 32R6-DAG: negu $2, $[[T3]] +; 32R6-DAG: subu $3, $6, $[[T1]] + +; 64-DAG: dsll $[[T0:[0-9]+]], $4, 32 +; 64-DAG: dsrl $[[T1:[0-9]+]], $[[T0]], 32 +; 64-DAG: dsll $[[T2:[0-9]+]], $5, 32 +; 64-DAG: dsrl $[[T3:[0-9]+]], $[[T2]], 32 +; 64-DAG: d[[m:m]]ult $[[T3]], $[[T1]] +; 64-DAG: [[m]]flo $[[T4:[0-9]+]] +; 64-DAG: dsll $[[T5:[0-9]+]], $6, 32 +; 64-DAG: dsrl $[[T6:[0-9]+]], $[[T5]], 32 +; 64-DAG: dsubu $2, $[[T6]], $[[T4]] + +; 64R6-DAG: dsll $[[T0:[0-9]+]], $4, 32 +; 64R6-DAG: dsrl $[[T1:[0-9]+]], $[[T0]], 32 +; 64R6-DAG: dsll $[[T2:[0-9]+]], $5, 32 +; 64R6-DAG: dsrl $[[T3:[0-9]+]], $[[T2]], 32 +; 64R6-DAG: dmul $[[T4:[0-9]+]], $[[T3]], $[[T1]] +; 64R6-DAG: dsll $[[T5:[0-9]+]], $6, 32 +; 64R6-DAG: dsrl $[[T6:[0-9]+]], $[[T5]], 32 +; 64R6-DAG: dsubu $2, $[[T6]], $[[T4]] + define i64 @msub2(i32 %a, i32 %b, i32 %c) nounwind readnone { entry: %conv = zext i32 %c to i64 @@ -61,8 +243,39 @@ entry: ret i64 %sub } -; 32: msub ${{[0-9]+}} -; DSP: msub $ac +; ALL-LABEL: msub3: + +; FIXME: We don't really need this instruction +; 32-DAG: mthi $6 +; 32-DAG: mtlo $7 +; 32-DAG: [[m:m]]sub ${{[45]}}, ${{[45]}} +; 32-DAG: [[m]]fhi $2 +; 32-DAG: [[m]]flo $3 + +; DSP-DAG: addiu $[[T0:[0-9]+]], $zero, 0 +; DSP-DAG: mtlo $[[AC:ac[0-3]+]], $6 +; DSP-DAG: msub $[[AC]], ${{[45]}}, ${{[45]}} +; DSP-DAG: mfhi $2, $[[AC]] +; DSP-DAG: mflo $3, $[[AC]] + +; 32R6-DAG: muh $[[T0:[0-9]+]], ${{[45]}}, ${{[45]}} +; 32R6-DAG: mul $[[T1:[0-9]+]], ${{[45]}}, ${{[45]}} +; 32R6-DAG: sltu $[[T2:[0-9]+]], $7, $[[T1]] +; 32R6-DAG: addu $[[T3:[0-9]+]], $[[T2]], $[[T0]] +; 32R6-DAG: subu $2, $6, $[[T3]] +; 32R6-DAG: subu $3, $7, $[[T1]] + +; 64-DAG: sll $[[T0:[0-9]+]], $4, 0 +; 64-DAG: sll $[[T1:[0-9]+]], $5, 0 +; 64-DAG: d[[m:m]]ult $[[T1]], $[[T0]] +; 64-DAG: [[m]]flo $[[T2:[0-9]+]] +; 64-DAG: dsubu $2, $6, $[[T2]] + +; 64R6-DAG: sll $[[T0:[0-9]+]], $4, 0 +; 64R6-DAG: sll $[[T1:[0-9]+]], $5, 0 +; 64R6-DAG: dmul $[[T2:[0-9]+]], $[[T1]], $[[T0]] +; 64R6-DAG: dsubu $2, $6, $[[T2]] + define i64 @msub3(i32 %a, i32 %b, i64 %c) nounwind readnone { entry: %conv = sext i32 %a to i64 diff --git a/test/CodeGen/Mips/mips16ex.ll b/test/CodeGen/Mips/mips16ex.ll index ecb30b5..a1a9919 100644 --- a/test/CodeGen/Mips/mips16ex.ll +++ b/test/CodeGen/Mips/mips16ex.ll @@ -1,6 +1,8 @@ ; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=pic -O3 < %s | FileCheck %s -check-prefix=16 -;16: $eh_func_begin0=. +;16: .cfi_personality +;16-NEXT: [[TMP:.*]]: +;16-NEXT: $eh_func_begin0 = ([[TMP]]) @.str = private unnamed_addr constant [7 x i8] c"hello\0A\00", align 1 @_ZTIi = external constant i8* @.str1 = private unnamed_addr constant [15 x i8] c"exception %i \0A\00", align 1 diff --git a/test/CodeGen/Mips/mips64-f128.ll b/test/CodeGen/Mips/mips64-f128.ll index 4d590b6..7f7d515 100644 --- a/test/CodeGen/Mips/mips64-f128.ll +++ b/test/CodeGen/Mips/mips64-f128.ll @@ -1,7 +1,11 @@ ; RUN: llc -mtriple=mips64el-unknown-unknown -mcpu=mips4 -soft-float -O1 \ -; RUN: -disable-mips-delay-filler < %s | FileCheck %s +; RUN: -disable-mips-delay-filler < %s | FileCheck %s -check-prefix=ALL -check-prefix=C_CC_FMT ; RUN: llc -mtriple=mips64el-unknown-unknown -mcpu=mips64 -soft-float -O1 \ -; RUN: -disable-mips-delay-filler < %s | FileCheck %s +; RUN: -disable-mips-delay-filler < %s | FileCheck %s -check-prefix=ALL -check-prefix=C_CC_FMT +; RUN: llc -mtriple=mips64el-unknown-unknown -mcpu=mips64r2 -soft-float -O1 \ +; RUN: -disable-mips-delay-filler < %s | FileCheck %s -check-prefix=ALL -check-prefix=C_CC_FMT +; RUN: llc -mtriple=mips64el-unknown-unknown -mcpu=mips64r6 -soft-float -O1 \ +; RUN: -disable-mips-delay-filler < %s | FileCheck %s -check-prefix=ALL -check-prefix=CMP_CC_FMT @gld0 = external global fp128 @gld1 = external global fp128 @@ -9,8 +13,8 @@ @gf1 = external global float @gd1 = external global double -; CHECK-LABEL: addLD: -; CHECK: ld $25, %call16(__addtf3) +; ALL-LABEL: addLD: +; ALL: ld $25, %call16(__addtf3) define fp128 @addLD() { entry: @@ -20,8 +24,8 @@ entry: ret fp128 %add } -; CHECK-LABEL: subLD: -; CHECK: ld $25, %call16(__subtf3) +; ALL-LABEL: subLD: +; ALL: ld $25, %call16(__subtf3) define fp128 @subLD() { entry: @@ -31,8 +35,8 @@ entry: ret fp128 %sub } -; CHECK-LABEL: mulLD: -; CHECK: ld $25, %call16(__multf3) +; ALL-LABEL: mulLD: +; ALL: ld $25, %call16(__multf3) define fp128 @mulLD() { entry: @@ -42,8 +46,8 @@ entry: ret fp128 %mul } -; CHECK-LABEL: divLD: -; CHECK: ld $25, %call16(__divtf3) +; ALL-LABEL: divLD: +; ALL: ld $25, %call16(__divtf3) define fp128 @divLD() { entry: @@ -53,8 +57,8 @@ entry: ret fp128 %div } -; CHECK-LABEL: conv_LD_char: -; CHECK: ld $25, %call16(__floatsitf) +; ALL-LABEL: conv_LD_char: +; ALL: ld $25, %call16(__floatsitf) define fp128 @conv_LD_char(i8 signext %a) { entry: @@ -62,8 +66,8 @@ entry: ret fp128 %conv } -; CHECK-LABEL: conv_LD_short: -; CHECK: ld $25, %call16(__floatsitf) +; ALL-LABEL: conv_LD_short: +; ALL: ld $25, %call16(__floatsitf) define fp128 @conv_LD_short(i16 signext %a) { entry: @@ -71,8 +75,8 @@ entry: ret fp128 %conv } -; CHECK-LABEL: conv_LD_int: -; CHECK: ld $25, %call16(__floatsitf) +; ALL-LABEL: conv_LD_int: +; ALL: ld $25, %call16(__floatsitf) define fp128 @conv_LD_int(i32 %a) { entry: @@ -80,8 +84,8 @@ entry: ret fp128 %conv } -; CHECK-LABEL: conv_LD_LL: -; CHECK: ld $25, %call16(__floatditf) +; ALL-LABEL: conv_LD_LL: +; ALL: ld $25, %call16(__floatditf) define fp128 @conv_LD_LL(i64 %a) { entry: @@ -89,8 +93,8 @@ entry: ret fp128 %conv } -; CHECK-LABEL: conv_LD_UChar: -; CHECK: ld $25, %call16(__floatunsitf) +; ALL-LABEL: conv_LD_UChar: +; ALL: ld $25, %call16(__floatunsitf) define fp128 @conv_LD_UChar(i8 zeroext %a) { entry: @@ -98,8 +102,8 @@ entry: ret fp128 %conv } -; CHECK-LABEL: conv_LD_UShort: -; CHECK: ld $25, %call16(__floatunsitf) +; ALL-LABEL: conv_LD_UShort: +; ALL: ld $25, %call16(__floatunsitf) define fp128 @conv_LD_UShort(i16 zeroext %a) { entry: @@ -107,8 +111,8 @@ entry: ret fp128 %conv } -; CHECK-LABEL: conv_LD_UInt: -; CHECK: ld $25, %call16(__floatunsitf) +; ALL-LABEL: conv_LD_UInt: +; ALL: ld $25, %call16(__floatunsitf) define fp128 @conv_LD_UInt(i32 %a) { entry: @@ -116,8 +120,8 @@ entry: ret fp128 %conv } -; CHECK-LABEL: conv_LD_ULL: -; CHECK: ld $25, %call16(__floatunditf) +; ALL-LABEL: conv_LD_ULL: +; ALL: ld $25, %call16(__floatunditf) define fp128 @conv_LD_ULL(i64 %a) { entry: @@ -125,8 +129,8 @@ entry: ret fp128 %conv } -; CHECK-LABEL: conv_char_LD: -; CHECK: ld $25, %call16(__fixtfsi) +; ALL-LABEL: conv_char_LD: +; ALL: ld $25, %call16(__fixtfsi) define signext i8 @conv_char_LD(fp128 %a) { entry: @@ -134,8 +138,8 @@ entry: ret i8 %conv } -; CHECK-LABEL: conv_short_LD: -; CHECK: ld $25, %call16(__fixtfsi) +; ALL-LABEL: conv_short_LD: +; ALL: ld $25, %call16(__fixtfsi) define signext i16 @conv_short_LD(fp128 %a) { entry: @@ -143,8 +147,8 @@ entry: ret i16 %conv } -; CHECK-LABEL: conv_int_LD: -; CHECK: ld $25, %call16(__fixtfsi) +; ALL-LABEL: conv_int_LD: +; ALL: ld $25, %call16(__fixtfsi) define i32 @conv_int_LD(fp128 %a) { entry: @@ -152,8 +156,8 @@ entry: ret i32 %conv } -; CHECK-LABEL: conv_LL_LD: -; CHECK: ld $25, %call16(__fixtfdi) +; ALL-LABEL: conv_LL_LD: +; ALL: ld $25, %call16(__fixtfdi) define i64 @conv_LL_LD(fp128 %a) { entry: @@ -161,8 +165,8 @@ entry: ret i64 %conv } -; CHECK-LABEL: conv_UChar_LD: -; CHECK: ld $25, %call16(__fixtfsi) +; ALL-LABEL: conv_UChar_LD: +; ALL: ld $25, %call16(__fixtfsi) define zeroext i8 @conv_UChar_LD(fp128 %a) { entry: @@ -170,8 +174,8 @@ entry: ret i8 %conv } -; CHECK-LABEL: conv_UShort_LD: -; CHECK: ld $25, %call16(__fixtfsi) +; ALL-LABEL: conv_UShort_LD: +; ALL: ld $25, %call16(__fixtfsi) define zeroext i16 @conv_UShort_LD(fp128 %a) { entry: @@ -179,8 +183,8 @@ entry: ret i16 %conv } -; CHECK-LABEL: conv_UInt_LD: -; CHECK: ld $25, %call16(__fixunstfsi) +; ALL-LABEL: conv_UInt_LD: +; ALL: ld $25, %call16(__fixunstfsi) define i32 @conv_UInt_LD(fp128 %a) { entry: @@ -188,8 +192,8 @@ entry: ret i32 %conv } -; CHECK-LABEL: conv_ULL_LD: -; CHECK: ld $25, %call16(__fixunstfdi) +; ALL-LABEL: conv_ULL_LD: +; ALL: ld $25, %call16(__fixunstfdi) define i64 @conv_ULL_LD(fp128 %a) { entry: @@ -197,8 +201,8 @@ entry: ret i64 %conv } -; CHECK-LABEL: conv_LD_float: -; CHECK: ld $25, %call16(__extendsftf2) +; ALL-LABEL: conv_LD_float: +; ALL: ld $25, %call16(__extendsftf2) define fp128 @conv_LD_float(float %a) { entry: @@ -206,8 +210,8 @@ entry: ret fp128 %conv } -; CHECK-LABEL: conv_LD_double: -; CHECK: ld $25, %call16(__extenddftf2) +; ALL-LABEL: conv_LD_double: +; ALL: ld $25, %call16(__extenddftf2) define fp128 @conv_LD_double(double %a) { entry: @@ -215,8 +219,8 @@ entry: ret fp128 %conv } -; CHECK-LABEL: conv_float_LD: -; CHECK: ld $25, %call16(__trunctfsf2) +; ALL-LABEL: conv_float_LD: +; ALL: ld $25, %call16(__trunctfsf2) define float @conv_float_LD(fp128 %a) { entry: @@ -224,8 +228,8 @@ entry: ret float %conv } -; CHECK-LABEL: conv_double_LD: -; CHECK: ld $25, %call16(__trunctfdf2) +; ALL-LABEL: conv_double_LD: +; ALL: ld $25, %call16(__trunctfdf2) define double @conv_double_LD(fp128 %a) { entry: @@ -233,13 +237,13 @@ entry: ret double %conv } -; CHECK-LABEL: libcall1_fabsl: -; CHECK-DAG: ld $[[R0:[0-9]+]], 8($[[R4:[0-9]+]]) -; CHECK-DAG: daddiu $[[R1:[0-9]+]], $zero, 1 -; CHECK-DAG: dsll $[[R2:[0-9]+]], $[[R1]], 63 -; CHECK-DAG: daddiu $[[R3:[0-9]+]], $[[R2]], -1 -; CHECK-DAG: and $4, $[[R0]], $[[R3]] -; CHECK-DAG: ld $2, 0($[[R4]]) +; ALL-LABEL: libcall1_fabsl: +; ALL-DAG: ld $[[R0:[0-9]+]], 8($[[R4:[0-9]+]]) +; ALL-DAG: daddiu $[[R1:[0-9]+]], $zero, 1 +; ALL-DAG: dsll $[[R2:[0-9]+]], $[[R1]], 63 +; ALL-DAG: daddiu $[[R3:[0-9]+]], $[[R2]], -1 +; ALL-DAG: and $4, $[[R0]], $[[R3]] +; ALL-DAG: ld $2, 0($[[R4]]) define fp128 @libcall1_fabsl() { entry: @@ -250,8 +254,8 @@ entry: declare fp128 @fabsl(fp128) #1 -; CHECK-LABEL: libcall1_ceill: -; CHECK: ld $25, %call16(ceill) +; ALL-LABEL: libcall1_ceill: +; ALL: ld $25, %call16(ceill) define fp128 @libcall1_ceill() { entry: @@ -262,8 +266,8 @@ entry: declare fp128 @ceill(fp128) #1 -; CHECK-LABEL: libcall1_sinl: -; CHECK: ld $25, %call16(sinl) +; ALL-LABEL: libcall1_sinl: +; ALL: ld $25, %call16(sinl) define fp128 @libcall1_sinl() { entry: @@ -274,8 +278,8 @@ entry: declare fp128 @sinl(fp128) #2 -; CHECK-LABEL: libcall1_cosl: -; CHECK: ld $25, %call16(cosl) +; ALL-LABEL: libcall1_cosl: +; ALL: ld $25, %call16(cosl) define fp128 @libcall1_cosl() { entry: @@ -286,8 +290,8 @@ entry: declare fp128 @cosl(fp128) #2 -; CHECK-LABEL: libcall1_expl: -; CHECK: ld $25, %call16(expl) +; ALL-LABEL: libcall1_expl: +; ALL: ld $25, %call16(expl) define fp128 @libcall1_expl() { entry: @@ -298,8 +302,8 @@ entry: declare fp128 @expl(fp128) #2 -; CHECK-LABEL: libcall1_exp2l: -; CHECK: ld $25, %call16(exp2l) +; ALL-LABEL: libcall1_exp2l: +; ALL: ld $25, %call16(exp2l) define fp128 @libcall1_exp2l() { entry: @@ -310,8 +314,8 @@ entry: declare fp128 @exp2l(fp128) #2 -; CHECK-LABEL: libcall1_logl: -; CHECK: ld $25, %call16(logl) +; ALL-LABEL: libcall1_logl: +; ALL: ld $25, %call16(logl) define fp128 @libcall1_logl() { entry: @@ -322,8 +326,8 @@ entry: declare fp128 @logl(fp128) #2 -; CHECK-LABEL: libcall1_log2l: -; CHECK: ld $25, %call16(log2l) +; ALL-LABEL: libcall1_log2l: +; ALL: ld $25, %call16(log2l) define fp128 @libcall1_log2l() { entry: @@ -334,8 +338,8 @@ entry: declare fp128 @log2l(fp128) #2 -; CHECK-LABEL: libcall1_log10l: -; CHECK: ld $25, %call16(log10l) +; ALL-LABEL: libcall1_log10l: +; ALL: ld $25, %call16(log10l) define fp128 @libcall1_log10l() { entry: @@ -346,8 +350,8 @@ entry: declare fp128 @log10l(fp128) #2 -; CHECK-LABEL: libcall1_nearbyintl: -; CHECK: ld $25, %call16(nearbyintl) +; ALL-LABEL: libcall1_nearbyintl: +; ALL: ld $25, %call16(nearbyintl) define fp128 @libcall1_nearbyintl() { entry: @@ -358,8 +362,8 @@ entry: declare fp128 @nearbyintl(fp128) #1 -; CHECK-LABEL: libcall1_floorl: -; CHECK: ld $25, %call16(floorl) +; ALL-LABEL: libcall1_floorl: +; ALL: ld $25, %call16(floorl) define fp128 @libcall1_floorl() { entry: @@ -370,8 +374,8 @@ entry: declare fp128 @floorl(fp128) #1 -; CHECK-LABEL: libcall1_sqrtl: -; CHECK: ld $25, %call16(sqrtl) +; ALL-LABEL: libcall1_sqrtl: +; ALL: ld $25, %call16(sqrtl) define fp128 @libcall1_sqrtl() { entry: @@ -382,8 +386,8 @@ entry: declare fp128 @sqrtl(fp128) #2 -; CHECK-LABEL: libcall1_rintl: -; CHECK: ld $25, %call16(rintl) +; ALL-LABEL: libcall1_rintl: +; ALL: ld $25, %call16(rintl) define fp128 @libcall1_rintl() { entry: @@ -394,8 +398,8 @@ entry: declare fp128 @rintl(fp128) #1 -; CHECK-LABEL: libcall_powil: -; CHECK: ld $25, %call16(__powitf2) +; ALL-LABEL: libcall_powil: +; ALL: ld $25, %call16(__powitf2) define fp128 @libcall_powil(fp128 %a, i32 %b) { entry: @@ -405,18 +409,18 @@ entry: declare fp128 @llvm.powi.f128(fp128, i32) #3 -; CHECK-LABEL: libcall2_copysignl: -; CHECK-DAG: daddiu $[[R2:[0-9]+]], $zero, 1 -; CHECK-DAG: dsll $[[R3:[0-9]+]], $[[R2]], 63 -; CHECK-DAG: ld $[[R0:[0-9]+]], %got_disp(gld1) -; CHECK-DAG: ld $[[R1:[0-9]+]], 8($[[R0]]) -; CHECK-DAG: and $[[R4:[0-9]+]], $[[R1]], $[[R3]] -; CHECK-DAG: ld $[[R5:[0-9]+]], %got_disp(gld0) -; CHECK-DAG: ld $[[R6:[0-9]+]], 8($[[R5]]) -; CHECK-DAG: daddiu $[[R7:[0-9]+]], $[[R3]], -1 -; CHECK-DAG: and $[[R8:[0-9]+]], $[[R6]], $[[R7]] -; CHECK-DAG: or $4, $[[R8]], $[[R4]] -; CHECK-DAG: ld $2, 0($[[R5]]) +; ALL-LABEL: libcall2_copysignl: +; ALL-DAG: daddiu $[[R2:[0-9]+]], $zero, 1 +; ALL-DAG: dsll $[[R3:[0-9]+]], $[[R2]], 63 +; ALL-DAG: ld $[[R0:[0-9]+]], %got_disp(gld1) +; ALL-DAG: ld $[[R1:[0-9]+]], 8($[[R0]]) +; ALL-DAG: and $[[R4:[0-9]+]], $[[R1]], $[[R3]] +; ALL-DAG: ld $[[R5:[0-9]+]], %got_disp(gld0) +; ALL-DAG: ld $[[R6:[0-9]+]], 8($[[R5]]) +; ALL-DAG: daddiu $[[R7:[0-9]+]], $[[R3]], -1 +; ALL-DAG: and $[[R8:[0-9]+]], $[[R6]], $[[R7]] +; ALL-DAG: or $4, $[[R8]], $[[R4]] +; ALL-DAG: ld $2, 0($[[R5]]) define fp128 @libcall2_copysignl() { entry: @@ -428,8 +432,8 @@ entry: declare fp128 @copysignl(fp128, fp128) #1 -; CHECK-LABEL: libcall2_powl: -; CHECK: ld $25, %call16(powl) +; ALL-LABEL: libcall2_powl: +; ALL: ld $25, %call16(powl) define fp128 @libcall2_powl() { entry: @@ -441,8 +445,8 @@ entry: declare fp128 @powl(fp128, fp128) #2 -; CHECK-LABEL: libcall2_fmodl: -; CHECK: ld $25, %call16(fmodl) +; ALL-LABEL: libcall2_fmodl: +; ALL: ld $25, %call16(fmodl) define fp128 @libcall2_fmodl() { entry: @@ -454,8 +458,8 @@ entry: declare fp128 @fmodl(fp128, fp128) #2 -; CHECK-LABEL: libcall3_fmal: -; CHECK: ld $25, %call16(fmal) +; ALL-LABEL: libcall3_fmal: +; ALL: ld $25, %call16(fmal) define fp128 @libcall3_fmal() { entry: @@ -468,8 +472,8 @@ entry: declare fp128 @llvm.fma.f128(fp128, fp128, fp128) #4 -; CHECK-LABEL: cmp_lt: -; CHECK: ld $25, %call16(__lttf2) +; ALL-LABEL: cmp_lt: +; ALL: ld $25, %call16(__lttf2) define i32 @cmp_lt(fp128 %a, fp128 %b) { entry: @@ -478,8 +482,8 @@ entry: ret i32 %conv } -; CHECK-LABEL: cmp_le: -; CHECK: ld $25, %call16(__letf2) +; ALL-LABEL: cmp_le: +; ALL: ld $25, %call16(__letf2) define i32 @cmp_le(fp128 %a, fp128 %b) { entry: @@ -488,8 +492,8 @@ entry: ret i32 %conv } -; CHECK-LABEL: cmp_gt: -; CHECK: ld $25, %call16(__gttf2) +; ALL-LABEL: cmp_gt: +; ALL: ld $25, %call16(__gttf2) define i32 @cmp_gt(fp128 %a, fp128 %b) { entry: @@ -498,8 +502,8 @@ entry: ret i32 %conv } -; CHECK-LABEL: cmp_ge: -; CHECK: ld $25, %call16(__getf2) +; ALL-LABEL: cmp_ge: +; ALL: ld $25, %call16(__getf2) define i32 @cmp_ge(fp128 %a, fp128 %b) { entry: @@ -508,8 +512,8 @@ entry: ret i32 %conv } -; CHECK-LABEL: cmp_eq: -; CHECK: ld $25, %call16(__eqtf2) +; ALL-LABEL: cmp_eq: +; ALL: ld $25, %call16(__eqtf2) define i32 @cmp_eq(fp128 %a, fp128 %b) { entry: @@ -518,8 +522,8 @@ entry: ret i32 %conv } -; CHECK-LABEL: cmp_ne: -; CHECK: ld $25, %call16(__netf2) +; ALL-LABEL: cmp_ne: +; ALL: ld $25, %call16(__netf2) define i32 @cmp_ne(fp128 %a, fp128 %b) { entry: @@ -528,10 +532,10 @@ entry: ret i32 %conv } -; CHECK-LABEL: load_LD_LD: -; CHECK: ld $[[R0:[0-9]+]], %got_disp(gld1) -; CHECK: ld $2, 0($[[R0]]) -; CHECK: ld $4, 8($[[R0]]) +; ALL-LABEL: load_LD_LD: +; ALL: ld $[[R0:[0-9]+]], %got_disp(gld1) +; ALL: ld $2, 0($[[R0]]) +; ALL: ld $4, 8($[[R0]]) define fp128 @load_LD_LD() { entry: @@ -539,11 +543,11 @@ entry: ret fp128 %0 } -; CHECK-LABEL: load_LD_float: -; CHECK: ld $[[R0:[0-9]+]], %got_disp(gf1) -; CHECK: lw $4, 0($[[R0]]) -; CHECK: ld $25, %call16(__extendsftf2) -; CHECK: jalr $25 +; ALL-LABEL: load_LD_float: +; ALL: ld $[[R0:[0-9]+]], %got_disp(gf1) +; ALL: lw $4, 0($[[R0]]) +; ALL: ld $25, %call16(__extendsftf2) +; ALL: jalr $25 define fp128 @load_LD_float() { entry: @@ -552,11 +556,11 @@ entry: ret fp128 %conv } -; CHECK-LABEL: load_LD_double: -; CHECK: ld $[[R0:[0-9]+]], %got_disp(gd1) -; CHECK: ld $4, 0($[[R0]]) -; CHECK: ld $25, %call16(__extenddftf2) -; CHECK: jalr $25 +; ALL-LABEL: load_LD_double: +; ALL: ld $[[R0:[0-9]+]], %got_disp(gd1) +; ALL: ld $4, 0($[[R0]]) +; ALL: ld $25, %call16(__extenddftf2) +; ALL: jalr $25 define fp128 @load_LD_double() { entry: @@ -565,13 +569,13 @@ entry: ret fp128 %conv } -; CHECK-LABEL: store_LD_LD: -; CHECK: ld $[[R0:[0-9]+]], %got_disp(gld1) -; CHECK: ld $[[R1:[0-9]+]], 0($[[R0]]) -; CHECK: ld $[[R2:[0-9]+]], 8($[[R0]]) -; CHECK: ld $[[R3:[0-9]+]], %got_disp(gld0) -; CHECK: sd $[[R2]], 8($[[R3]]) -; CHECK: sd $[[R1]], 0($[[R3]]) +; ALL-LABEL: store_LD_LD: +; ALL: ld $[[R0:[0-9]+]], %got_disp(gld1) +; ALL: ld $[[R1:[0-9]+]], 0($[[R0]]) +; ALL: ld $[[R2:[0-9]+]], 8($[[R0]]) +; ALL: ld $[[R3:[0-9]+]], %got_disp(gld0) +; ALL: sd $[[R2]], 8($[[R3]]) +; ALL: sd $[[R1]], 0($[[R3]]) define void @store_LD_LD() { entry: @@ -580,14 +584,14 @@ entry: ret void } -; CHECK-LABEL: store_LD_float: -; CHECK: ld $[[R0:[0-9]+]], %got_disp(gld1) -; CHECK: ld $4, 0($[[R0]]) -; CHECK: ld $5, 8($[[R0]]) -; CHECK: ld $25, %call16(__trunctfsf2) -; CHECK: jalr $25 -; CHECK: ld $[[R1:[0-9]+]], %got_disp(gf1) -; CHECK: sw $2, 0($[[R1]]) +; ALL-LABEL: store_LD_float: +; ALL: ld $[[R0:[0-9]+]], %got_disp(gld1) +; ALL: ld $4, 0($[[R0]]) +; ALL: ld $5, 8($[[R0]]) +; ALL: ld $25, %call16(__trunctfsf2) +; ALL: jalr $25 +; ALL: ld $[[R1:[0-9]+]], %got_disp(gf1) +; ALL: sw $2, 0($[[R1]]) define void @store_LD_float() { entry: @@ -597,14 +601,14 @@ entry: ret void } -; CHECK-LABEL: store_LD_double: -; CHECK: ld $[[R0:[0-9]+]], %got_disp(gld1) -; CHECK: ld $4, 0($[[R0]]) -; CHECK: ld $5, 8($[[R0]]) -; CHECK: ld $25, %call16(__trunctfdf2) -; CHECK: jalr $25 -; CHECK: ld $[[R1:[0-9]+]], %got_disp(gd1) -; CHECK: sd $2, 0($[[R1]]) +; ALL-LABEL: store_LD_double: +; ALL: ld $[[R0:[0-9]+]], %got_disp(gld1) +; ALL: ld $4, 0($[[R0]]) +; ALL: ld $5, 8($[[R0]]) +; ALL: ld $25, %call16(__trunctfdf2) +; ALL: jalr $25 +; ALL: ld $[[R1:[0-9]+]], %got_disp(gd1) +; ALL: sd $2, 0($[[R1]]) define void @store_LD_double() { entry: @@ -614,11 +618,22 @@ entry: ret void } -; CHECK-LABEL: select_LD: -; CHECK: movn $8, $6, $4 -; CHECK: movn $9, $7, $4 -; CHECK: move $2, $8 -; CHECK: move $4, $9 +; ALL-LABEL: select_LD: +; C_CC_FMT: movn $8, $6, $4 +; C_CC_FMT: movn $9, $7, $4 +; C_CC_FMT: move $2, $8 +; C_CC_FMT: move $4, $9 + +; FIXME: This sll works around an implementation detail in the code generator +; (setcc's result is i32 so bits 32-63 are undefined). It's not really +; needed. +; CMP_CC_FMT-DAG: sll $[[CC:[0-9]+]], $4, 0 +; CMP_CC_FMT-DAG: seleqz $[[EQ1:[0-9]+]], $8, $[[CC]] +; CMP_CC_FMT-DAG: selnez $[[NE1:[0-9]+]], $6, $[[CC]] +; CMP_CC_FMT-DAG: or $2, $[[NE1]], $[[EQ1]] +; CMP_CC_FMT-DAG: seleqz $[[EQ2:[0-9]+]], $9, $[[CC]] +; CMP_CC_FMT-DAG: selnez $[[NE2:[0-9]+]], $7, $[[CC]] +; CMP_CC_FMT-DAG: or $4, $[[NE2]], $[[EQ2]] define fp128 @select_LD(i32 %a, i64, fp128 %b, fp128 %c) { entry: @@ -627,18 +642,27 @@ entry: ret fp128 %cond } -; CHECK-LABEL: selectCC_LD: -; CHECK: move $[[R0:[0-9]+]], $11 -; CHECK: move $[[R1:[0-9]+]], $10 -; CHECK: move $[[R2:[0-9]+]], $9 -; CHECK: move $[[R3:[0-9]+]], $8 -; CHECK: ld $25, %call16(__gttf2)($gp) -; CHECK: jalr $25 -; CHECK: slti $1, $2, 1 -; CHECK: movz $[[R1]], $[[R3]], $1 -; CHECK: movz $[[R0]], $[[R2]], $1 -; CHECK: move $2, $[[R1]] -; CHECK: move $4, $[[R0]] +; ALL-LABEL: selectCC_LD: +; ALL: move $[[R0:[0-9]+]], $11 +; ALL: move $[[R1:[0-9]+]], $10 +; ALL: move $[[R2:[0-9]+]], $9 +; ALL: move $[[R3:[0-9]+]], $8 +; ALL: ld $25, %call16(__gttf2)($gp) +; ALL: jalr $25 + +; C_CC_FMT: slti $[[CC:[0-9]+]], $2, 1 +; C_CC_FMT: movz $[[R1]], $[[R3]], $[[CC]] +; C_CC_FMT: movz $[[R0]], $[[R2]], $[[CC]] +; C_CC_FMT: move $2, $[[R1]] +; C_CC_FMT: move $4, $[[R0]] + +; CMP_CC_FMT: slt $[[CC:[0-9]+]], $zero, $2 +; CMP_CC_FMT: seleqz $[[EQ1:[0-9]+]], $[[R1]], $[[CC]] +; CMP_CC_FMT: selnez $[[NE1:[0-9]+]], $[[R3]], $[[CC]] +; CMP_CC_FMT: or $2, $[[NE1]], $[[EQ1]] +; CMP_CC_FMT: seleqz $[[EQ2:[0-9]+]], $[[R0]], $[[CC]] +; CMP_CC_FMT: selnez $[[NE2:[0-9]+]], $[[R2]], $[[CC]] +; CMP_CC_FMT: or $4, $[[NE2]], $[[EQ2]] define fp128 @selectCC_LD(fp128 %a, fp128 %b, fp128 %c, fp128 %d) { entry: diff --git a/test/CodeGen/Mips/mips64-fp-indexed-ls.ll b/test/CodeGen/Mips/mips64-fp-indexed-ls.ll deleted file mode 100644 index bbdc05c..0000000 --- a/test/CodeGen/Mips/mips64-fp-indexed-ls.ll +++ /dev/null @@ -1,110 +0,0 @@ -; RUN: llc -march=mips64el -mcpu=mips64r2 -mattr=n64 < %s | FileCheck %s - -%struct.S = type <{ [4 x float] }> -%struct.S2 = type <{ [4 x double] }> -%struct.S3 = type <{ i8, float }> - -@s = external global [4 x %struct.S] -@gf = external global float -@gd = external global double -@s2 = external global [4 x %struct.S2] -@s3 = external global %struct.S3 - -define float @foo0(float* nocapture %b, i32 %o) nounwind readonly { -entry: -; CHECK: lwxc1 - %idxprom = zext i32 %o to i64 - %arrayidx = getelementptr inbounds float* %b, i64 %idxprom - %0 = load float* %arrayidx, align 4 - ret float %0 -} - -define double @foo1(double* nocapture %b, i32 %o) nounwind readonly { -entry: -; CHECK: ldxc1 - %idxprom = zext i32 %o to i64 - %arrayidx = getelementptr inbounds double* %b, i64 %idxprom - %0 = load double* %arrayidx, align 8 - ret double %0 -} - -define float @foo2(i32 %b, i32 %c) nounwind readonly { -entry: -; CHECK-NOT: luxc1 - %idxprom = zext i32 %c to i64 - %idxprom1 = zext i32 %b to i64 - %arrayidx2 = getelementptr inbounds [4 x %struct.S]* @s, i64 0, i64 %idxprom1, i32 0, i64 %idxprom - %0 = load float* %arrayidx2, align 1 - ret float %0 -} - -define void @foo3(float* nocapture %b, i32 %o) nounwind { -entry: -; CHECK: swxc1 - %0 = load float* @gf, align 4 - %idxprom = zext i32 %o to i64 - %arrayidx = getelementptr inbounds float* %b, i64 %idxprom - store float %0, float* %arrayidx, align 4 - ret void -} - -define void @foo4(double* nocapture %b, i32 %o) nounwind { -entry: -; CHECK: sdxc1 - %0 = load double* @gd, align 8 - %idxprom = zext i32 %o to i64 - %arrayidx = getelementptr inbounds double* %b, i64 %idxprom - store double %0, double* %arrayidx, align 8 - ret void -} - -define void @foo5(i32 %b, i32 %c) nounwind { -entry: -; CHECK-NOT: suxc1 - %0 = load float* @gf, align 4 - %idxprom = zext i32 %c to i64 - %idxprom1 = zext i32 %b to i64 - %arrayidx2 = getelementptr inbounds [4 x %struct.S]* @s, i64 0, i64 %idxprom1, i32 0, i64 %idxprom - store float %0, float* %arrayidx2, align 1 - ret void -} - -define double @foo6(i32 %b, i32 %c) nounwind readonly { -entry: -; CHECK: foo6 -; CHECK-NOT: luxc1 - %idxprom = zext i32 %c to i64 - %idxprom1 = zext i32 %b to i64 - %arrayidx2 = getelementptr inbounds [4 x %struct.S2]* @s2, i64 0, i64 %idxprom1, i32 0, i64 %idxprom - %0 = load double* %arrayidx2, align 1 - ret double %0 -} - -define void @foo7(i32 %b, i32 %c) nounwind { -entry: -; CHECK: foo7 -; CHECK-NOT: suxc1 - %0 = load double* @gd, align 8 - %idxprom = zext i32 %c to i64 - %idxprom1 = zext i32 %b to i64 - %arrayidx2 = getelementptr inbounds [4 x %struct.S2]* @s2, i64 0, i64 %idxprom1, i32 0, i64 %idxprom - store double %0, double* %arrayidx2, align 1 - ret void -} - -define float @foo8() nounwind readonly { -entry: -; CHECK: foo8 -; CHECK-NOT: luxc1 - %0 = load float* getelementptr inbounds (%struct.S3* @s3, i64 0, i32 1), align 1 - ret float %0 -} - -define void @foo9(float %f) nounwind { -entry: -; CHECK: foo9 -; CHECK-NOT: suxc1 - store float %f, float* getelementptr inbounds (%struct.S3* @s3, i64 0, i32 1), align 1 - ret void -} - diff --git a/test/CodeGen/Mips/mips64countleading.ll b/test/CodeGen/Mips/mips64countleading.ll deleted file mode 100644 index 252f323..0000000 --- a/test/CodeGen/Mips/mips64countleading.ll +++ /dev/null @@ -1,24 +0,0 @@ -; RUN: llc -march=mips64el -mcpu=mips4 < %s | FileCheck -check-prefix=CHECK -check-prefix=MIPS4 %s -; RUN: llc -march=mips64el -mcpu=mips64 < %s | FileCheck -check-prefix=CHECK -check-prefix=MIPS64 %s - -define i64 @t1(i64 %X) nounwind readnone { -entry: -; CHECK-LABEL: t1: -; MIPS4-NOT: dclz -; MIPS64: dclz - %tmp1 = tail call i64 @llvm.ctlz.i64(i64 %X, i1 true) - ret i64 %tmp1 -} - -declare i64 @llvm.ctlz.i64(i64, i1) nounwind readnone - -define i64 @t3(i64 %X) nounwind readnone { -entry: -; CHECK-LABEL: t3: -; MIPS4-NOT: dclo -; MIPS64: dclo - %neg = xor i64 %X, -1 - %tmp1 = tail call i64 @llvm.ctlz.i64(i64 %neg, i1 true) - ret i64 %tmp1 -} - diff --git a/test/CodeGen/Mips/mips64instrs.ll b/test/CodeGen/Mips/mips64instrs.ll index 58f11f1..ed617be 100644 --- a/test/CodeGen/Mips/mips64instrs.ll +++ b/test/CodeGen/Mips/mips64instrs.ll @@ -1,99 +1,128 @@ -; RUN: llc -march=mips64el -mcpu=mips4 -verify-machineinstrs < %s | FileCheck -check-prefix=CHECK -check-prefix=MIPS4 %s -; RUN: llc -march=mips64el -mcpu=mips64 -verify-machineinstrs < %s | FileCheck -check-prefix=CHECK -check-prefix=MIPS64 %s +; RUN: llc -march=mips64el -mcpu=mips4 -verify-machineinstrs < %s | FileCheck -check-prefix=ALL -check-prefix=MIPS4 -check-prefix=ACCMULDIV %s +; RUN: llc -march=mips64el -mcpu=mips64 -verify-machineinstrs < %s | FileCheck -check-prefix=ALL -check-prefix=HAS-DCLO -check-prefix=ACCMULDIV %s +; RUN: llc -march=mips64el -mcpu=mips64r2 -verify-machineinstrs < %s | FileCheck -check-prefix=ALL -check-prefix=HAS-DCLO -check-prefix=ACCMULDIV %s +; RUN: llc -march=mips64el -mcpu=mips64r6 -verify-machineinstrs < %s | FileCheck -check-prefix=ALL -check-prefix=HAS-DCLO -check-prefix=GPRMULDIV %s @gll0 = common global i64 0, align 8 @gll1 = common global i64 0, align 8 define i64 @f0(i64 %a0, i64 %a1) nounwind readnone { entry: -; CHECK: daddu +; ALL-LABEL: f0: +; ALL: daddu $2, ${{[45]}}, ${{[45]}} %add = add nsw i64 %a1, %a0 ret i64 %add } define i64 @f1(i64 %a0, i64 %a1) nounwind readnone { entry: -; CHECK: dsubu +; ALL-LABEL: f1: +; ALL: dsubu $2, $4, $5 %sub = sub nsw i64 %a0, %a1 ret i64 %sub } define i64 @f4(i64 %a0, i64 %a1) nounwind readnone { entry: -; CHECK: and +; ALL-LABEL: f4: +; ALL: and $2, ${{[45]}}, ${{[45]}} %and = and i64 %a1, %a0 ret i64 %and } define i64 @f5(i64 %a0, i64 %a1) nounwind readnone { entry: -; CHECK: or +; ALL-LABEL: f5: +; ALL: or $2, ${{[45]}}, ${{[45]}} %or = or i64 %a1, %a0 ret i64 %or } define i64 @f6(i64 %a0, i64 %a1) nounwind readnone { entry: -; CHECK: xor +; ALL-LABEL: f6: +; ALL: xor $2, ${{[45]}}, ${{[45]}} %xor = xor i64 %a1, %a0 ret i64 %xor } define i64 @f7(i64 %a0) nounwind readnone { entry: -; CHECK: daddiu ${{[0-9]+}}, ${{[0-9]+}}, 20 +; ALL-LABEL: f7: +; ALL: daddiu $2, $4, 20 %add = add nsw i64 %a0, 20 ret i64 %add } define i64 @f8(i64 %a0) nounwind readnone { entry: -; CHECK: daddiu ${{[0-9]+}}, ${{[0-9]+}}, -20 +; ALL-LABEL: f8: +; ALL: daddiu $2, $4, -20 %sub = add nsw i64 %a0, -20 ret i64 %sub } define i64 @f9(i64 %a0) nounwind readnone { entry: -; CHECK: andi ${{[0-9]+}}, ${{[0-9]+}}, 20 +; ALL-LABEL: f9: +; ALL: andi $2, $4, 20 %and = and i64 %a0, 20 ret i64 %and } define i64 @f10(i64 %a0) nounwind readnone { entry: -; CHECK: ori ${{[0-9]+}}, ${{[0-9]+}}, 20 +; ALL-LABEL: f10: +; ALL: ori $2, $4, 20 %or = or i64 %a0, 20 ret i64 %or } define i64 @f11(i64 %a0) nounwind readnone { entry: -; CHECK: xori ${{[0-9]+}}, ${{[0-9]+}}, 20 +; ALL-LABEL: f11: +; ALL: xori $2, $4, 20 %xor = xor i64 %a0, 20 ret i64 %xor } define i64 @f12(i64 %a, i64 %b) nounwind readnone { entry: -; CHECK: mult +; ALL-LABEL: f12: + +; ACCMULDIV: mult ${{[45]}}, ${{[45]}} +; GPRMULDIV: dmul $2, ${{[45]}}, ${{[45]}} + %mul = mul nsw i64 %b, %a ret i64 %mul } define i64 @f13(i64 %a, i64 %b) nounwind readnone { entry: -; CHECK: mult +; ALL-LABEL: f13: + +; ACCMULDIV: mult ${{[45]}}, ${{[45]}} +; GPRMULDIV: dmul $2, ${{[45]}}, ${{[45]}} + %mul = mul i64 %b, %a ret i64 %mul } define i64 @f14(i64 %a, i64 %b) nounwind readnone { entry: -; CHECK-LABEL: f14: -; CHECK: ddiv $zero, ${{[0-9]+}}, $[[R0:[0-9]+]] -; CHECK: teq $[[R0]], $zero, 7 -; CHECK: mflo +; ALL-LABEL: f14: +; ALL-DAG: ld $[[P0:[0-9]+]], %got_disp(gll0)( +; ALL-DAG: ld $[[P1:[0-9]+]], %got_disp(gll1)( +; ALL-DAG: ld $[[T0:[0-9]+]], 0($[[P0]]) +; ALL-DAG: ld $[[T1:[0-9]+]], 0($[[P1]]) + +; ACCMULDIV: ddiv $zero, $[[T0]], $[[T1]] +; ACCMULDIV: teq $[[T1]], $zero, 7 +; ACCMULDIV: mflo $2 + +; GPRMULDIV: ddiv $2, $[[T0]], $[[T1]] +; GPRMULDIV: teq $[[T1]], $zero, 7 + %0 = load i64* @gll0, align 8 %1 = load i64* @gll1, align 8 %div = sdiv i64 %0, %1 @@ -102,10 +131,19 @@ entry: define i64 @f15() nounwind readnone { entry: -; CHECK-LABEL: f15: -; CHECK: ddivu $zero, ${{[0-9]+}}, $[[R0:[0-9]+]] -; CHECK: teq $[[R0]], $zero, 7 -; CHECK: mflo +; ALL-LABEL: f15: +; ALL-DAG: ld $[[P0:[0-9]+]], %got_disp(gll0)( +; ALL-DAG: ld $[[P1:[0-9]+]], %got_disp(gll1)( +; ALL-DAG: ld $[[T0:[0-9]+]], 0($[[P0]]) +; ALL-DAG: ld $[[T1:[0-9]+]], 0($[[P1]]) + +; ACCMULDIV: ddivu $zero, $[[T0]], $[[T1]] +; ACCMULDIV: teq $[[T1]], $zero, 7 +; ACCMULDIV: mflo $2 + +; GPRMULDIV: ddivu $2, $[[T0]], $[[T1]] +; GPRMULDIV: teq $[[T1]], $zero, 7 + %0 = load i64* @gll0, align 8 %1 = load i64* @gll1, align 8 %div = udiv i64 %0, %1 @@ -114,20 +152,30 @@ entry: define i64 @f16(i64 %a, i64 %b) nounwind readnone { entry: -; CHECK-LABEL: f16: -; CHECK: ddiv $zero, ${{[0-9]+}}, $[[R0:[0-9]+]] -; CHECK: teq $[[R0]], $zero, 7 -; CHECK: mfhi +; ALL-LABEL: f16: + +; ACCMULDIV: ddiv $zero, $4, $5 +; ACCMULDIV: teq $5, $zero, 7 +; ACCMULDIV: mfhi $2 + +; GPRMULDIV: dmod $2, $4, $5 +; GPRMULDIV: teq $5, $zero, 7 + %rem = srem i64 %a, %b ret i64 %rem } define i64 @f17(i64 %a, i64 %b) nounwind readnone { entry: -; CHECK-LABEL: f17: -; CHECK: ddivu $zero, ${{[0-9]+}}, $[[R0:[0-9]+]] -; CHECK: teq $[[R0]], $zero, 7 -; CHECK: mfhi +; ALL-LABEL: f17: + +; ACCMULDIV: ddivu $zero, $4, $5 +; ACCMULDIV: teq $5, $zero, 7 +; ACCMULDIV: mfhi $2 + +; GPRMULDIV: dmodu $2, $4, $5 +; GPRMULDIV: teq $5, $zero, 7 + %rem = urem i64 %a, %b ret i64 %rem } @@ -136,24 +184,26 @@ declare i64 @llvm.ctlz.i64(i64, i1) nounwind readnone define i64 @f18(i64 %X) nounwind readnone { entry: -; CHECK-LABEL: f18: +; ALL-LABEL: f18: ; The MIPS4 version is too long to reasonably test. At least check we don't get dclz -; MIPS4-NOT: dclz +; MIPS4-NOT: dclz + +; HAS-DCLO: dclz $2, $4 -; MIPS64: dclz $2, $4 %tmp1 = tail call i64 @llvm.ctlz.i64(i64 %X, i1 true) ret i64 %tmp1 } define i64 @f19(i64 %X) nounwind readnone { entry: -; CHECK-LABEL: f19: +; ALL-LABEL: f19: ; The MIPS4 version is too long to reasonably test. At least check we don't get dclo -; MIPS4-NOT: dclo +; MIPS4-NOT: dclo + +; HAS-DCLO: dclo $2, $4 -; MIPS64: dclo $2, $4 %neg = xor i64 %X, -1 %tmp1 = tail call i64 @llvm.ctlz.i64(i64 %neg, i1 true) ret i64 %tmp1 @@ -161,8 +211,8 @@ entry: define i64 @f20(i64 %a, i64 %b) nounwind readnone { entry: -; CHECK-LABEL: f20: -; CHECK: nor +; ALL-LABEL: f20: +; ALL: nor $2, ${{[45]}}, ${{[45]}} %or = or i64 %b, %a %neg = xor i64 %or, -1 ret i64 %neg diff --git a/test/CodeGen/Mips/mips64muldiv.ll b/test/CodeGen/Mips/mips64muldiv.ll index 39c73e9..32d05a9 100644 --- a/test/CodeGen/Mips/mips64muldiv.ll +++ b/test/CodeGen/Mips/mips64muldiv.ll @@ -1,50 +1,79 @@ -; RUN: llc -march=mips64el -mcpu=mips4 < %s | FileCheck %s -; RUN: llc -march=mips64el -mcpu=mips64 < %s | FileCheck %s +; RUN: llc -march=mips64el -mcpu=mips4 < %s | FileCheck %s -check-prefix=ALL -check-prefix=ACC +; RUN: llc -march=mips64el -mcpu=mips64 < %s | FileCheck %s -check-prefix=ALL -check-prefix=ACC +; RUN: llc -march=mips64el -mcpu=mips64r2 < %s | FileCheck %s -check-prefix=ALL -check-prefix=ACC +; RUN: llc -march=mips64el -mcpu=mips64r6 < %s | FileCheck %s -check-prefix=ALL -check-prefix=GPR + +; FileCheck prefixes: +; ALL - All targets +; ACC - Targets with accumulator based mul/div (i.e. pre-MIPS32r6) +; GPR - Targets with register based mul/div (i.e. MIPS32r6) define i64 @m0(i64 %a0, i64 %a1) nounwind readnone { entry: -; CHECK: dmult -; CHECK: mflo +; ALL-LABEL: m0: +; ACC: dmult ${{[45]}}, ${{[45]}} +; ACC: mflo $2 +; GPR: dmul $2, ${{[45]}}, ${{[45]}} %mul = mul i64 %a1, %a0 ret i64 %mul } define i64 @m1(i64 %a) nounwind readnone { entry: -; CHECK: dmult -; CHECK: mfhi +; ALL-LABEL: m1: +; ALL: lui $[[T0:[0-9]+]], 21845 +; ALL: addiu $[[T0]], $[[T0]], 21845 +; ALL: dsll $[[T0]], $[[T0]], 16 +; ALL: addiu $[[T0]], $[[T0]], 21845 +; ALL: dsll $[[T0]], $[[T0]], 16 +; ALL: addiu $[[T0]], $[[T0]], 21846 + +; ACC: dmult $4, $[[T0]] +; ACC: mfhi $[[T1:[0-9]+]] +; GPR: dmuh $[[T1:[0-9]+]], $4, $[[T0]] + +; ALL: dsrl $2, $[[T1]], 63 +; ALL: daddu $2, $[[T1]], $2 %div = sdiv i64 %a, 3 ret i64 %div } define i64 @d0(i64 %a0, i64 %a1) nounwind readnone { entry: -; CHECK: ddivu -; CHECK: mflo +; ALL-LABEL: d0: +; ACC: ddivu $zero, $4, $5 +; ACC: mflo $2 +; GPR: ddivu $2, $4, $5 %div = udiv i64 %a0, %a1 ret i64 %div } define i64 @d1(i64 %a0, i64 %a1) nounwind readnone { entry: -; CHECK: ddiv -; CHECK: mflo +; ALL-LABEL: d1: +; ACC: ddiv $zero, $4, $5 +; ACC: mflo $2 +; GPR: ddiv $2, $4, $5 %div = sdiv i64 %a0, %a1 ret i64 %div } define i64 @d2(i64 %a0, i64 %a1) nounwind readnone { entry: -; CHECK: ddivu -; CHECK: mfhi +; ALL-LABEL: d2: +; ACC: ddivu $zero, $4, $5 +; ACC: mfhi $2 +; GPR: dmodu $2, $4, $5 %rem = urem i64 %a0, %a1 ret i64 %rem } define i64 @d3(i64 %a0, i64 %a1) nounwind readnone { entry: -; CHECK: ddiv -; CHECK: mfhi +; ALL-LABEL: d3: +; ACC: ddiv $zero, $4, $5 +; ACC: mfhi $2 +; GPR: dmod $2, $4, $5 %rem = srem i64 %a0, %a1 ret i64 %rem } diff --git a/test/CodeGen/Mips/mno-ldc1-sdc1.ll b/test/CodeGen/Mips/mno-ldc1-sdc1.ll index f4854f8..244b03d 100644 --- a/test/CodeGen/Mips/mno-ldc1-sdc1.ll +++ b/test/CodeGen/Mips/mno-ldc1-sdc1.ll @@ -1,33 +1,113 @@ -; RUN: llc -march=mipsel -relocation-model=pic -mno-ldc1-sdc1 -mcpu=mips32r2 \ -; RUN: < %s | FileCheck %s -check-prefix=LE-PIC -; RUN: llc -march=mipsel -relocation-model=static -mno-ldc1-sdc1 < %s | \ -; RUN: FileCheck %s -check-prefix=LE-STATIC -; RUN: llc -march=mips -relocation-model=pic -mno-ldc1-sdc1 < %s | \ -; RUN: FileCheck %s -check-prefix=BE-PIC +; Check that [sl]dc1 are normally emitted. MIPS32r2 should have [sl]dxc1 too. +; RUN: llc -march=mipsel -mcpu=mips32 < %s | \ +; RUN: FileCheck %s -check-prefix=ALL -check-prefix=32R1-LDC1 ; RUN: llc -march=mipsel -mcpu=mips32r2 < %s | \ -; RUN: FileCheck %s -check-prefix=CHECK-LDC1-SDC1 +; RUN: FileCheck %s -check-prefix=ALL -check-prefix=32R2-LDXC1 +; RUN: llc -march=mipsel -mcpu=mips32r6 < %s | \ +; RUN: FileCheck %s -check-prefix=ALL -check-prefix=32R6-LDC1 + +; Check that -mno-ldc1-sdc1 disables [sl]dc1 +; RUN: llc -march=mipsel -relocation-model=pic -mno-ldc1-sdc1 \ +; RUN: -mcpu=mips32 < %s | \ +; RUN: FileCheck %s -check-prefix=ALL -check-prefix=32R1 \ +; RUN: -check-prefix=32R1-LE -check-prefix=32R1-LE-PIC +; RUN: llc -march=mipsel -relocation-model=pic -mno-ldc1-sdc1 \ +; RUN: -mcpu=mips32r2 < %s | \ +; RUN: FileCheck %s -check-prefix=ALL -check-prefix=32R2 \ +; RUN: -check-prefix=32R2-LE -check-prefix=32R2-LE-PIC +; RUN: llc -march=mipsel -relocation-model=pic -mno-ldc1-sdc1 \ +; RUN: -mcpu=mips32r6 < %s | \ +; RUN: FileCheck %s -check-prefix=ALL -check-prefix=32R6 \ +; RUN: -check-prefix=32R6-LE -check-prefix=32R6-LE-PIC + +; Check again for big-endian +; RUN: llc -march=mips -relocation-model=pic -mno-ldc1-sdc1 \ +; RUN: -mcpu=mips32 < %s | \ +; RUN: FileCheck %s -check-prefix=ALL -check-prefix=32R1 \ +; RUN: -check-prefix=32R1-BE -check-prefix=32R1-BE-PIC +; RUN: llc -march=mips -relocation-model=pic -mno-ldc1-sdc1 \ +; RUN: -mcpu=mips32r2 < %s | \ +; RUN: FileCheck %s -check-prefix=ALL -check-prefix=32R2 \ +; RUN: -check-prefix=32R2-BE -check-prefix=32R2-BE-PIC +; RUN: llc -march=mips -relocation-model=pic -mno-ldc1-sdc1 \ +; RUN: -mcpu=mips32r6 < %s | \ +; RUN: FileCheck %s -check-prefix=ALL -check-prefix=32R6 \ +; RUN: -check-prefix=32R6-BE -check-prefix=32R6-BE-PIC + +; Check again for the static relocation model +; RUN: llc -march=mipsel -relocation-model=static -mno-ldc1-sdc1 \ +; RUN: -mcpu=mips32 < %s | \ +; RUN: FileCheck %s -check-prefix=ALL -check-prefix=32R1 \ +; RUN: -check-prefix=32R1-LE -check-prefix=32R1-LE-STATIC +; RUN: llc -march=mipsel -relocation-model=static -mno-ldc1-sdc1 \ +; RUN: -mcpu=mips32r2 < %s | \ +; RUN: FileCheck %s -check-prefix=ALL -check-prefix=32R2 \ +; RUN: -check-prefix=32R2-LE -check-prefix=32R2-LE-STATIC +; RUN: llc -march=mipsel -relocation-model=static -mno-ldc1-sdc1 \ +; RUN: -mcpu=mips32r6 < %s | \ +; RUN: FileCheck %s -check-prefix=ALL -check-prefix=32R6 \ +; RUN: -check-prefix=32R6-LE -check-prefix=32R6-LE-STATIC @g0 = common global double 0.000000e+00, align 8 -; LE-PIC-LABEL: test_ldc1: -; LE-PIC-DAG: lw $[[R0:[0-9]+]], 0(${{[0-9]+}}) -; LE-PIC-DAG: lw $[[R1:[0-9]+]], 4(${{[0-9]+}}) -; LE-PIC-DAG: mtc1 $[[R0]], $f0 -; LE-PIC-DAG: mtc1 $[[R1]], $f1 -; LE-STATIC-LABEL: test_ldc1: -; LE-STATIC-DAG: lui $[[R0:[0-9]+]], %hi(g0) -; LE-STATIC-DAG: lw $[[R1:[0-9]+]], %lo(g0)($[[R0]]) -; LE-STATIC-DAG: addiu $[[R2:[0-9]+]], $[[R0]], %lo(g0) -; LE-STATIC-DAG: lw $[[R3:[0-9]+]], 4($[[R2]]) -; LE-STATIC-DAG: mtc1 $[[R1]], $f0 -; LE-STATIC-DAG: mtc1 $[[R3]], $f1 -; BE-PIC-LABEL: test_ldc1: -; BE-PIC-DAG: lw $[[R0:[0-9]+]], 0(${{[0-9]+}}) -; BE-PIC-DAG: lw $[[R1:[0-9]+]], 4(${{[0-9]+}}) -; BE-PIC-DAG: mtc1 $[[R1]], $f0 -; BE-PIC-DAG: mtc1 $[[R0]], $f1 -; CHECK-LDC1-SDC1-LABEL: test_ldc1: -; CHECK-LDC1-SDC1: ldc1 $f{{[0-9]+}} +; ALL-LABEL: test_ldc1: + +; 32R1-LE-PIC-DAG: lw $[[R0:[0-9]+]], 0(${{[0-9]+}}) +; 32R1-LE-PIC-DAG: lw $[[R1:[0-9]+]], 4(${{[0-9]+}}) +; 32R1-LE-PIC-DAG: mtc1 $[[R0]], $f0 +; 32R1-LE-PIC-DAG: mtc1 $[[R1]], $f1 + +; 32R2-LE-PIC-DAG: lw $[[R0:[0-9]+]], 0(${{[0-9]+}}) +; 32R2-LE-PIC-DAG: lw $[[R1:[0-9]+]], 4(${{[0-9]+}}) +; 32R2-LE-PIC-DAG: mtc1 $[[R0]], $f0 +; 32R2-LE-PIC-DAG: mthc1 $[[R1]], $f0 + +; 32R6-LE-PIC-DAG: lw $[[R0:[0-9]+]], 0(${{[0-9]+}}) +; 32R6-LE-PIC-DAG: lw $[[R1:[0-9]+]], 4(${{[0-9]+}}) +; 32R6-LE-PIC-DAG: mtc1 $[[R0]], $f0 +; 32R6-LE-PIC-DAG: mthc1 $[[R1]], $f0 + +; 32R1-LE-STATIC-DAG: lui $[[R0:[0-9]+]], %hi(g0) +; 32R1-LE-STATIC-DAG: lw $[[R1:[0-9]+]], %lo(g0)($[[R0]]) +; 32R1-LE-STATIC-DAG: addiu $[[R2:[0-9]+]], $[[R0]], %lo(g0) +; 32R1-LE-STATIC-DAG: lw $[[R3:[0-9]+]], 4($[[R2]]) +; 32R1-LE-STATIC-DAG: mtc1 $[[R1]], $f0 +; 32R1-LE-STATIC-DAG: mtc1 $[[R3]], $f1 + +; 32R2-LE-STATIC-DAG: lui $[[R0:[0-9]+]], %hi(g0) +; 32R2-LE-STATIC-DAG: lw $[[R1:[0-9]+]], %lo(g0)($[[R0]]) +; 32R2-LE-STATIC-DAG: addiu $[[R2:[0-9]+]], $[[R0]], %lo(g0) +; 32R2-LE-STATIC-DAG: lw $[[R3:[0-9]+]], 4($[[R2]]) +; 32R2-LE-STATIC-DAG: mtc1 $[[R1]], $f0 +; 32R2-LE-STATIC-DAG: mthc1 $[[R3]], $f0 + +; 32R6-LE-STATIC-DAG: lui $[[R0:[0-9]+]], %hi(g0) +; 32R6-LE-STATIC-DAG: lw $[[R1:[0-9]+]], %lo(g0)($[[R0]]) +; 32R6-LE-STATIC-DAG: addiu $[[R2:[0-9]+]], $[[R0]], %lo(g0) +; 32R6-LE-STATIC-DAG: lw $[[R3:[0-9]+]], 4($[[R2]]) +; 32R6-LE-STATIC-DAG: mtc1 $[[R1]], $f0 +; 32R6-LE-STATIC-DAG: mthc1 $[[R3]], $f0 + +; 32R1-BE-PIC-DAG: lw $[[R0:[0-9]+]], 0(${{[0-9]+}}) +; 32R1-BE-PIC-DAG: lw $[[R1:[0-9]+]], 4(${{[0-9]+}}) +; 32R1-BE-PIC-DAG: mtc1 $[[R1]], $f0 +; 32R1-BE-PIC-DAG: mtc1 $[[R0]], $f1 + +; 32R2-BE-PIC-DAG: lw $[[R0:[0-9]+]], 0(${{[0-9]+}}) +; 32R2-BE-PIC-DAG: lw $[[R1:[0-9]+]], 4(${{[0-9]+}}) +; 32R2-BE-PIC-DAG: mtc1 $[[R1]], $f0 +; 32R2-BE-PIC-DAG: mthc1 $[[R0]], $f0 + +; 32R6-BE-PIC-DAG: lw $[[R0:[0-9]+]], 0(${{[0-9]+}}) +; 32R6-BE-PIC-DAG: lw $[[R1:[0-9]+]], 4(${{[0-9]+}}) +; 32R6-BE-PIC-DAG: mtc1 $[[R1]], $f0 +; 32R6-BE-PIC-DAG: mthc1 $[[R0]], $f0 + +; 32R1-LDC1: ldc1 $f0, 0(${{[0-9]+}}) + +; 32R2-LDXC1: ldc1 $f0, 0(${{[0-9]+}}) + +; 32R6-LDC1: ldc1 $f0, 0(${{[0-9]+}}) define double @test_ldc1() { entry: @@ -35,25 +115,64 @@ entry: ret double %0 } -; LE-PIC-LABEL: test_sdc1: -; LE-PIC-DAG: mfc1 $[[R0:[0-9]+]], $f12 -; LE-PIC-DAG: mfc1 $[[R1:[0-9]+]], $f13 -; LE-PIC-DAG: sw $[[R0]], 0(${{[0-9]+}}) -; LE-PIC-DAG: sw $[[R1]], 4(${{[0-9]+}}) -; LE-STATIC-LABEL: test_sdc1: -; LE-STATIC-DAG: mfc1 $[[R0:[0-9]+]], $f12 -; LE-STATIC-DAG: mfc1 $[[R1:[0-9]+]], $f13 -; LE-STATIC-DAG: lui $[[R2:[0-9]+]], %hi(g0) -; LE-STATIC-DAG: sw $[[R0]], %lo(g0)($[[R2]]) -; LE-STATIC-DAG: addiu $[[R3:[0-9]+]], $[[R2]], %lo(g0) -; LE-STATIC-DAG: sw $[[R1]], 4($[[R3]]) -; BE-PIC-LABEL: test_sdc1: -; BE-PIC-DAG: mfc1 $[[R0:[0-9]+]], $f12 -; BE-PIC-DAG: mfc1 $[[R1:[0-9]+]], $f13 -; BE-PIC-DAG: sw $[[R1]], 0(${{[0-9]+}}) -; BE-PIC-DAG: sw $[[R0]], 4(${{[0-9]+}}) -; CHECK-LDC1-SDC1-LABEL: test_sdc1: -; CHECK-LDC1-SDC1: sdc1 $f{{[0-9]+}} +; ALL-LABEL: test_sdc1: + +; 32R1-LE-PIC-DAG: mfc1 $[[R0:[0-9]+]], $f12 +; 32R1-LE-PIC-DAG: mfc1 $[[R1:[0-9]+]], $f13 +; 32R1-LE-PIC-DAG: sw $[[R0]], 0(${{[0-9]+}}) +; 32R1-LE-PIC-DAG: sw $[[R1]], 4(${{[0-9]+}}) + +; 32R2-LE-PIC-DAG: mfc1 $[[R0:[0-9]+]], $f12 +; 32R2-LE-PIC-DAG: mfc1 $[[R1:[0-9]+]], $f13 +; 32R2-LE-PIC-DAG: sw $[[R0]], 0(${{[0-9]+}}) +; 32R2-LE-PIC-DAG: sw $[[R1]], 4(${{[0-9]+}}) + +; 32R6-LE-PIC-DAG: mfc1 $[[R0:[0-9]+]], $f12 +; 32R6-LE-PIC-DAG: mfhc1 $[[R1:[0-9]+]], $f12 +; 32R6-LE-PIC-DAG: sw $[[R0]], 0(${{[0-9]+}}) +; 32R6-LE-PIC-DAG: sw $[[R1]], 4(${{[0-9]+}}) + +; 32R1-LE-STATIC-DAG: mfc1 $[[R0:[0-9]+]], $f12 +; 32R1-LE-STATIC-DAG: mfc1 $[[R1:[0-9]+]], $f13 +; 32R1-LE-STATIC-DAG: lui $[[R2:[0-9]+]], %hi(g0) +; 32R1-LE-STATIC-DAG: sw $[[R0]], %lo(g0)($[[R2]]) +; 32R1-LE-STATIC-DAG: addiu $[[R3:[0-9]+]], $[[R2]], %lo(g0) +; 32R1-LE-STATIC-DAG: sw $[[R1]], 4($[[R3]]) + +; 32R2-LE-STATIC-DAG: mfc1 $[[R0:[0-9]+]], $f12 +; 32R2-LE-STATIC-DAG: mfc1 $[[R1:[0-9]+]], $f13 +; 32R2-LE-STATIC-DAG: lui $[[R2:[0-9]+]], %hi(g0) +; 32R2-LE-STATIC-DAG: sw $[[R0]], %lo(g0)($[[R2]]) +; 32R2-LE-STATIC-DAG: addiu $[[R3:[0-9]+]], $[[R2]], %lo(g0) +; 32R2-LE-STATIC-DAG: sw $[[R1]], 4($[[R3]]) + +; 32R6-LE-STATIC-DAG: mfc1 $[[R0:[0-9]+]], $f12 +; 32R6-LE-STATIC-DAG: mfhc1 $[[R1:[0-9]+]], $f12 +; 32R6-LE-STATIC-DAG: lui $[[R2:[0-9]+]], %hi(g0) +; 32R6-LE-STATIC-DAG: sw $[[R0]], %lo(g0)($[[R2]]) +; 32R6-LE-STATIC-DAG: addiu $[[R3:[0-9]+]], $[[R2]], %lo(g0) +; 32R6-LE-STATIC-DAG: sw $[[R1]], 4($[[R3]]) + +; 32R1-BE-PIC-DAG: mfc1 $[[R0:[0-9]+]], $f12 +; 32R1-BE-PIC-DAG: mfc1 $[[R1:[0-9]+]], $f13 +; 32R1-BE-PIC-DAG: sw $[[R1]], 0(${{[0-9]+}}) +; 32R1-BE-PIC-DAG: sw $[[R0]], 4(${{[0-9]+}}) + +; 32R2-BE-PIC-DAG: mfc1 $[[R0:[0-9]+]], $f12 +; 32R2-BE-PIC-DAG: mfc1 $[[R1:[0-9]+]], $f13 +; 32R2-BE-PIC-DAG: sw $[[R1]], 0(${{[0-9]+}}) +; 32R2-BE-PIC-DAG: sw $[[R0]], 4(${{[0-9]+}}) + +; 32R6-BE-PIC-DAG: mfc1 $[[R0:[0-9]+]], $f12 +; 32R6-BE-PIC-DAG: mfhc1 $[[R1:[0-9]+]], $f12 +; 32R6-BE-PIC-DAG: sw $[[R1]], 0(${{[0-9]+}}) +; 32R6-BE-PIC-DAG: sw $[[R0]], 4(${{[0-9]+}}) + +; 32R1-LDC1: sdc1 $f{{[0-9]+}}, 0(${{[0-9]+}}) + +; 32R2-LDXC1: sdc1 $f{{[0-9]+}}, 0(${{[0-9]+}}) + +; 32R6-LDC1: sdc1 $f{{[0-9]+}}, 0(${{[0-9]+}}) define void @test_sdc1(double %a) { entry: @@ -61,14 +180,35 @@ entry: ret void } +; ALL-LABEL: test_ldxc1: + +; 32R1-LE-DAG: lw $[[R0:[0-9]+]], 0(${{[0-9]+}}) +; 32R1-LE-DAG: lw $[[R1:[0-9]+]], 4(${{[0-9]+}}) +; 32R1-BE-DAG: lw $[[R0:[0-9]+]], 4(${{[0-9]+}}) +; 32R1-BE-DAG: lw $[[R1:[0-9]+]], 0(${{[0-9]+}}) +; 32R1-DAG: mtc1 $[[R0]], $f0 +; 32R1-DAG: mtc1 $[[R1]], $f1 + +; 32R2-LE-DAG: lw $[[R0:[0-9]+]], 0(${{[0-9]+}}) +; 32R2-LE-DAG: lw $[[R1:[0-9]+]], 4(${{[0-9]+}}) +; 32R2-BE-DAG: lw $[[R0:[0-9]+]], 4(${{[0-9]+}}) +; 32R2-BE-DAG: lw $[[R1:[0-9]+]], 0(${{[0-9]+}}) +; 32R2-DAG: mtc1 $[[R0]], $f0 +; 32R2-DAG: mthc1 $[[R1]], $f0 -; LE-PIC-LABEL: test_ldxc1: -; LE-PIC-DAG: lw $[[R0:[0-9]+]], 0(${{[0-9]+}}) -; LE-PIC-DAG: lw $[[R1:[0-9]+]], 4(${{[0-9]+}}) -; LE-PIC-DAG: mtc1 $[[R0]], $f0 -; LE-PIC-DAG: mtc1 $[[R1]], $f1 -; CHECK-LDC1-SDC1-LABEL: test_ldxc1: -; CHECK-LDC1-SDC1: ldxc1 $f{{[0-9]+}} +; 32R6-LE-DAG: lw $[[R0:[0-9]+]], 0(${{[0-9]+}}) +; 32R6-LE-DAG: lw $[[R1:[0-9]+]], 4(${{[0-9]+}}) +; 32R6-BE-DAG: lw $[[R0:[0-9]+]], 4(${{[0-9]+}}) +; 32R6-BE-DAG: lw $[[R1:[0-9]+]], 0(${{[0-9]+}}) +; 32R6-DAG: mtc1 $[[R0]], $f0 +; 32R6-DAG: mthc1 $[[R1]], $f0 + +; 32R1-LDC1: ldc1 $f0, 0(${{[0-9]+}}) + +; 32R2-LDXC1: sll $[[OFFSET:[0-9]+]], $5, 3 +; 32R2-LDXC1: ldxc1 $f0, $[[OFFSET]]($4) + +; 32R6-LDC1: ldc1 $f0, 0(${{[0-9]+}}) define double @test_ldxc1(double* nocapture readonly %a, i32 %i) { entry: @@ -77,13 +217,29 @@ entry: ret double %0 } -; LE-PIC-LABEL: test_sdxc1: -; LE-PIC-DAG: mfc1 $[[R0:[0-9]+]], $f12 -; LE-PIC-DAG: mfc1 $[[R1:[0-9]+]], $f13 -; LE-PIC-DAG: sw $[[R0]], 0(${{[0-9]+}}) -; LE-PIC-DAG: sw $[[R1]], 4(${{[0-9]+}}) -; CHECK-LDC1-SDC1-LABEL: test_sdxc1: -; CHECK-LDC1-SDC1: sdxc1 $f{{[0-9]+}} +; ALL-LABEL: test_sdxc1: + +; 32R1-DAG: mfc1 $[[R0:[0-9]+]], $f12 +; 32R1-DAG: mfc1 $[[R1:[0-9]+]], $f13 +; 32R1-DAG: sw $[[R0]], 0(${{[0-9]+}}) +; 32R1-DAG: sw $[[R1]], 4(${{[0-9]+}}) + +; 32R2-DAG: mfc1 $[[R0:[0-9]+]], $f12 +; 32R2-DAG: mfc1 $[[R1:[0-9]+]], $f13 +; 32R2-DAG: sw $[[R0]], 0(${{[0-9]+}}) +; 32R2-DAG: sw $[[R1]], 4(${{[0-9]+}}) + +; 32R6-DAG: mfc1 $[[R0:[0-9]+]], $f12 +; 32R6-DAG: mfhc1 $[[R1:[0-9]+]], $f12 +; 32R6-DAG: sw $[[R0]], 0(${{[0-9]+}}) +; 32R6-DAG: sw $[[R1]], 4(${{[0-9]+}}) + +; 32R1-LDC1: sdc1 $f{{[0-9]+}}, 0(${{[0-9]+}}) + +; 32R2-LDXC1: sll $[[OFFSET:[0-9]+]], $7, 3 +; 32R2-LDXC1: sdxc1 $f{{[0-9]+}}, $[[OFFSET]]($6) + +; 32R6-LDC1: sdc1 $f{{[0-9]+}}, 0(${{[0-9]+}}) define void @test_sdxc1(double %b, double* nocapture %a, i32 %i) { entry: diff --git a/test/CodeGen/Mips/msa/special.ll b/test/CodeGen/Mips/msa/special.ll index f65a14f..b9badf5 100644 --- a/test/CodeGen/Mips/msa/special.ll +++ b/test/CodeGen/Mips/msa/special.ll @@ -4,6 +4,10 @@ ; RUN: FileCheck %s --check-prefix=MIPS32 ; RUN: llc -march=mips64 -mcpu=mips64r2 -mattr=+msa,+fp64 < %s | \ ; RUN: FileCheck %s --check-prefix=MIPS64 +; RUN: llc -march=mips -mcpu=mips32r6 -mattr=+msa < %s | \ +; RUN: FileCheck %s --check-prefix=MIPS32 +; RUN: llc -march=mips64 -mcpu=mips64r6 -mattr=+msa < %s | \ +; RUN: FileCheck %s --check-prefix=MIPS64 define i32 @llvm_mips_lsa_test(i32 %a, i32 %b) nounwind { entry: diff --git a/test/CodeGen/Mips/no-odd-spreg.ll b/test/CodeGen/Mips/no-odd-spreg.ll new file mode 100644 index 0000000..b42ed6a --- /dev/null +++ b/test/CodeGen/Mips/no-odd-spreg.ll @@ -0,0 +1,54 @@ +; RUN: llc -march=mipsel -mcpu=mips32 < %s | FileCheck %s -check-prefix=ALL -check-prefix=ODDSPREG +; RUN: llc -march=mipsel -mcpu=mips32 -mattr=+nooddspreg < %s | FileCheck %s -check-prefix=ALL -check-prefix=NOODDSPREG +; RUN: llc -march=mipsel -mcpu=mips32r6 -mattr=fp64 < %s | FileCheck %s -check-prefix=ALL -check-prefix=ODDSPREG +; RUN: llc -march=mipsel -mcpu=mips32r6 -mattr=fp64,+nooddspreg < %s | FileCheck %s -check-prefix=ALL -check-prefix=NOODDSPREG + +; ODDSPREG: .module oddspreg +; NOODDSPREG: .module nooddspreg + +define float @two_floats(float %a) { +entry: + ; Clobber all except $f12 and $f13 + ; + ; The intention is that if odd single precision registers are permitted, the + ; allocator will choose $f12 and $f13 to avoid the spill/reload. + ; + ; On the other hand, if odd single precision registers are not permitted, it + ; will be forced to spill/reload either %a or %0. + + %0 = fadd float %a, 1.0 + call void asm "# Clobber", "~{$f0},~{$f1},~{$f2},~{$f3},~{$f4},~{$f5},~{$f6},~{$f7},~{$f8},~{$f9},~{$f10},~{$f11},~{$f14},~{$f15},~{$f16},~{$f17},~{$f18},~{$f19},~{$f20},~{$f21},~{$f22},~{$f23},~{$f24},~{$f25},~{$f26},~{$f27},~{$f28},~{$f29},~{$f30},~{$f31}"() + %1 = fadd float %a, %0 + ret float %1 +} + +; ALL-LABEL: two_floats: +; ODDSPREG: add.s $f13, $f12, ${{f[0-9]+}} +; ODDSPREG-NOT: swc1 +; ODDSPREG-NOT: lwc1 +; ODDSPREG: add.s $f0, $f12, $f13 + +; NOODDSPREG: add.s $[[T0:f[0-9]*[02468]]], $f12, ${{f[0-9]+}} +; NOODDSPREG: swc1 $[[T0]], +; NOODDSPREG: lwc1 $[[T1:f[0-9]*[02468]]], +; NOODDSPREG: add.s $f0, $f12, $[[T1]] + +define double @two_doubles(double %a) { +entry: + ; Clobber all except $f12 and $f13 + ; + ; -mno-odd-sp-reg doesn't need to affect double precision values so both cases + ; use $f12 and $f13. + + %0 = fadd double %a, 1.0 + call void asm "# Clobber", "~{$f0},~{$f1},~{$f2},~{$f3},~{$f4},~{$f5},~{$f6},~{$f7},~{$f8},~{$f9},~{$f10},~{$f11},~{$f14},~{$f15},~{$f16},~{$f17},~{$f18},~{$f19},~{$f20},~{$f21},~{$f22},~{$f23},~{$f24},~{$f25},~{$f26},~{$f27},~{$f28},~{$f29},~{$f30},~{$f31}"() + %1 = fadd double %a, %0 + ret double %1 +} + +; ALL-LABEL: two_doubles: +; ALL: add.d $[[T0:f[0-9]+]], $f12, ${{f[0-9]+}} +; ALL: add.d $f0, $f12, $[[T0]] + + +; INVALID: -mattr=+nooddspreg is not currently permitted for a 32-bit FPU register file (FR=0 mode). diff --git a/test/CodeGen/Mips/null-streamer.ll b/test/CodeGen/Mips/null-streamer.ll new file mode 100644 index 0000000..56cebbf --- /dev/null +++ b/test/CodeGen/Mips/null-streamer.ll @@ -0,0 +1,7 @@ +; Test the null streamer with a terget streamer. +; RUN: llc -O0 -filetype=null -mtriple=mips-linux < %s + +define i32 @main() { +entry: + ret i32 0 +} diff --git a/test/CodeGen/Mips/prevent-hoisting.ll b/test/CodeGen/Mips/prevent-hoisting.ll new file mode 100644 index 0000000..da665c2 --- /dev/null +++ b/test/CodeGen/Mips/prevent-hoisting.ll @@ -0,0 +1,144 @@ +; RUN: llc -march=mipsel -O3 < %s | FileCheck %s + + +; MIPS direct branches implicitly define register $at. This test makes sure that +; code hoisting optimization (which moves identical instructions at the start of +; two basic blocks to the common predecessor block) takes this into account and +; doesn't move definition of $at to the predecessor block (which would make $at +; live-in at the start of successor block). + + +; CHECK-LABEL: readLumaCoeff8x8_CABAC + +; The check for "addiu" instruction is added so that we can match the correct "b" instruction. +; CHECK: addiu ${{[0-9]+}}, $zero, -1 +; CHECK: b $[[BB0:BB[0-9_]+]] + +; Check that sll instruction that writes to $1 starts basic block. +; CHECK: {{BB[0-9_#]+}}: +; CHECK-NEXT: sll $1, $[[R0:[0-9]+]], 4 + +; Check that identical sll instruction starts another basic block. +; CHECK: [[BB0]]: +; CHECK-NEXT: sll $1, $[[R0]], 4 + + +%struct.img_par = type { i32, i32, i32, i32, i32*, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, [16 x [16 x i16]], [6 x [32 x i32]], [16 x [16 x i32]], [4 x [12 x [4 x [4 x i32]]]], [16 x i32], i8**, i32*, i32***, i32**, i32, i32, i32, i32, %struct.Slice*, %struct.macroblock*, i32, i32, i32, i32, i32, i32, %struct.DecRefPicMarking_s*, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, [3 x i32], i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32***, i32***, i32****, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, [3 x [2 x i32]], [3 x [2 x i32]], i32, i32, i32, i32, %struct.timeb, %struct.timeb, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32 } +%struct.Slice = type { i32, i32, i32, i32, i32, i32, i32, i32, i32, %struct.datapartition*, %struct.MotionInfoContexts*, %struct.TextureInfoContexts*, i32, i32*, i32*, i32*, i32, i32*, i32*, i32*, i32 (%struct.img_par*, %struct.inp_par*)*, i32, i32, i32, i32 } +%struct.datapartition = type { %struct.Bitstream*, %struct.DecodingEnvironment, i32 (%struct.syntaxelement*, %struct.img_par*, %struct.datapartition*)* } +%struct.Bitstream = type { i32, i32, i32, i32, i8*, i32 } +%struct.DecodingEnvironment = type { i32, i32, i32, i32, i32, i8*, i32* } +%struct.syntaxelement = type { i32, i32, i32, i32, i32, i32, i32, i32, void (i32, i32, i32*, i32*)*, void (%struct.syntaxelement*, %struct.img_par*, %struct.DecodingEnvironment*)* } +%struct.MotionInfoContexts = type { [4 x [11 x %struct.BiContextType]], [2 x [9 x %struct.BiContextType]], [2 x [10 x %struct.BiContextType]], [2 x [6 x %struct.BiContextType]], [4 x %struct.BiContextType], [4 x %struct.BiContextType], [3 x %struct.BiContextType] } +%struct.BiContextType = type { i16, i8 } +%struct.TextureInfoContexts = type { [2 x %struct.BiContextType], [4 x %struct.BiContextType], [3 x [4 x %struct.BiContextType]], [10 x [4 x %struct.BiContextType]], [10 x [15 x %struct.BiContextType]], [10 x [15 x %struct.BiContextType]], [10 x [5 x %struct.BiContextType]], [10 x [5 x %struct.BiContextType]], [10 x [15 x %struct.BiContextType]], [10 x [15 x %struct.BiContextType]] } +%struct.inp_par = type { [1000 x i8], [1000 x i8], [1000 x i8], i32, i32, i32, i32, i32, i32, i32, i32 } +%struct.macroblock = type { i32, [2 x i32], i32, i32, %struct.macroblock*, %struct.macroblock*, i32, [2 x [4 x [4 x [2 x i32]]]], i32, i64, i64, i32, i32, [4 x i8], [4 x i8], i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32 } +%struct.DecRefPicMarking_s = type { i32, i32, i32, i32, i32, %struct.DecRefPicMarking_s* } +%struct.timeb = type { i32, i16, i16, i16 } + +@assignSE2partition = external global [0 x [20 x i32]] +@FIELD_SCAN8x8 = external constant [64 x [2 x i8]] + + +define void @readLumaCoeff8x8_CABAC(%struct.img_par* %img, i32 %b8) { + + %1 = load i32* undef, align 4 + br i1 false, label %2, label %3 + +; <label>:2 ; preds = %0 + br label %3 + +; <label>:3 ; preds = %2, %0 + br i1 undef, label %switch.lookup, label %4 + +switch.lookup: ; preds = %3 + br label %4 + +; <label>:4 ; preds = %switch.lookup, %3 + br i1 undef, label %5, label %6 + +; <label>:5 ; preds = %4 + br label %6 + +; <label>:6 ; preds = %5, %4 + %7 = phi [2 x i8]* [ getelementptr inbounds ([64 x [2 x i8]]* @FIELD_SCAN8x8, i32 0, i32 0), %4 ], [ null, %5 ] + br i1 undef, label %switch.lookup6, label %8 + +switch.lookup6: ; preds = %6 + br label %8 + +; <label>:8 ; preds = %switch.lookup6, %6 + br i1 undef, label %.loopexit, label %9 + +; <label>:9 ; preds = %8 + %10 = and i32 %b8, 1 + %11 = shl nuw nsw i32 %10, 3 + %12 = getelementptr inbounds %struct.Slice* null, i32 0, i32 9 + br i1 undef, label %.preheader, label %.preheader11 + +.preheader11: ; preds = %21, %9 + %k.014 = phi i32 [ %27, %21 ], [ 0, %9 ] + %coef_ctr.013 = phi i32 [ %23, %21 ], [ -1, %9 ] + br i1 false, label %13, label %14 + +; <label>:13 ; preds = %.preheader11 + br label %15 + +; <label>:14 ; preds = %.preheader11 + br label %15 + +; <label>:15 ; preds = %14, %13 + %16 = getelementptr inbounds [0 x [20 x i32]]* @assignSE2partition, i32 0, i32 %1, i32 undef + %17 = load i32* %16, align 4 + %18 = getelementptr inbounds %struct.datapartition* null, i32 %17, i32 2 + %19 = load i32 (%struct.syntaxelement*, %struct.img_par*, %struct.datapartition*)** %18, align 4 + %20 = call i32 %19(%struct.syntaxelement* undef, %struct.img_par* %img, %struct.datapartition* undef) + br i1 false, label %.loopexit, label %21 + +; <label>:21 ; preds = %15 + %22 = add i32 %coef_ctr.013, 1 + %23 = add i32 %22, 0 + %24 = getelementptr inbounds [2 x i8]* %7, i32 %23, i32 0 + %25 = add nsw i32 0, %11 + %26 = getelementptr inbounds %struct.img_par* %img, i32 0, i32 27, i32 undef, i32 %25 + store i32 0, i32* %26, align 4 + %27 = add nsw i32 %k.014, 1 + %28 = icmp slt i32 %27, 65 + br i1 %28, label %.preheader11, label %.loopexit + +.preheader: ; preds = %36, %9 + %k.110 = phi i32 [ %45, %36 ], [ 0, %9 ] + %coef_ctr.29 = phi i32 [ %39, %36 ], [ -1, %9 ] + br i1 false, label %29, label %30 + +; <label>:29 ; preds = %.preheader + br label %31 + +; <label>:30 ; preds = %.preheader + br label %31 + +; <label>:31 ; preds = %30, %29 + %32 = getelementptr inbounds [0 x [20 x i32]]* @assignSE2partition, i32 0, i32 %1, i32 undef + %33 = load i32* %32, align 4 + %34 = getelementptr inbounds %struct.datapartition* null, i32 %33 + %35 = call i32 undef(%struct.syntaxelement* undef, %struct.img_par* %img, %struct.datapartition* %34) + br i1 false, label %.loopexit, label %36 + +; <label>:36 ; preds = %31 + %37 = load i32* undef, align 4 + %38 = add i32 %coef_ctr.29, 1 + %39 = add i32 %38, %37 + %40 = getelementptr inbounds [2 x i8]* %7, i32 %39, i32 0 + %41 = load i8* %40, align 1 + %42 = zext i8 %41 to i32 + %43 = add nsw i32 %42, %11 + %44 = getelementptr inbounds %struct.img_par* %img, i32 0, i32 27, i32 undef, i32 %43 + store i32 0, i32* %44, align 4 + %45 = add nsw i32 %k.110, 1 + %46 = icmp slt i32 %45, 65 + br i1 %46, label %.preheader, label %.loopexit + +.loopexit: ; preds = %36, %31, %21, %15, %8 + ret void +} diff --git a/test/CodeGen/Mips/select.ll b/test/CodeGen/Mips/select.ll index 06e2a86..eb2198b 100644 --- a/test/CodeGen/Mips/select.ll +++ b/test/CodeGen/Mips/select.ll @@ -1,135 +1,705 @@ -; RUN: llc < %s -march=mipsel | FileCheck %s -check-prefix=CHECK +; RUN: llc < %s -march=mipsel -mcpu=mips32 | FileCheck %s -check-prefix=ALL -check-prefix=32 +; RUN: llc < %s -march=mipsel -mcpu=mips32r2 | FileCheck %s -check-prefix=ALL -check-prefix=32R2 +; RUN: llc < %s -march=mipsel -mcpu=mips32r6 | FileCheck %s -check-prefix=ALL -check-prefix=32R6 +; RUN: llc < %s -march=mips64el -mcpu=mips64 | FileCheck %s -check-prefix=ALL -check-prefix=64 +; RUN: llc < %s -march=mips64el -mcpu=mips64r2 | FileCheck %s -check-prefix=ALL -check-prefix=64R2 +; RUN: llc < %s -march=mips64el -mcpu=mips64r6 | FileCheck %s -check-prefix=ALL -check-prefix=64R6 @d2 = external global double @d3 = external global double -define i32 @sel1(i32 %s, i32 %f0, i32 %f1) nounwind readnone { +define i32 @i32_icmp_ne_i32_val(i32 %s, i32 %f0, i32 %f1) nounwind readnone { entry: -; CHECK: movn +; ALL-LABEL: i32_icmp_ne_i32_val: + +; 32: movn $5, $6, $4 +; 32: move $2, $5 + +; 32R2: movn $5, $6, $4 +; 32R2: move $2, $5 + +; 32R6-DAG: seleqz $[[T0:[0-9]+]], $5, $4 +; 32R6-DAG: selnez $[[T1:[0-9]+]], $6, $4 +; 32R6: or $2, $[[T1]], $[[T0]] + +; 64: movn $5, $6, $4 +; 64: move $2, $5 + +; 64R2: movn $5, $6, $4 +; 64R2: move $2, $5 + +; 64R6-DAG: seleqz $[[T0:[0-9]+]], $5, $4 +; 64R6-DAG: selnez $[[T1:[0-9]+]], $6, $4 +; 64R6: or $2, $[[T1]], $[[T0]] + %tobool = icmp ne i32 %s, 0 %cond = select i1 %tobool, i32 %f1, i32 %f0 ret i32 %cond } -define float @sel2(i32 %s, float %f0, float %f1) nounwind readnone { +define i64 @i32_icmp_ne_i64_val(i32 %s, i64 %f0, i64 %f1) nounwind readnone { +entry: +; ALL-LABEL: i32_icmp_ne_i64_val: + +; 32-DAG: lw $[[F1:[0-9]+]], 16($sp) +; 32-DAG: movn $6, $[[F1]], $4 +; 32-DAG: lw $[[F1H:[0-9]+]], 20($sp) +; 32: movn $7, $[[F1H]], $4 +; 32: move $2, $6 +; 32: move $3, $7 + +; 32R2-DAG: lw $[[F1:[0-9]+]], 16($sp) +; 32R2-DAG: movn $6, $[[F1]], $4 +; 32R2-DAG: lw $[[F1H:[0-9]+]], 20($sp) +; 32R2: movn $7, $[[F1H]], $4 +; 32R2: move $2, $6 +; 32R2: move $3, $7 + +; 32R6-DAG: lw $[[F1:[0-9]+]], 16($sp) +; 32R6-DAG: seleqz $[[T0:[0-9]+]], $6, $4 +; 32R6-DAG: selnez $[[T1:[0-9]+]], $[[F1]], $4 +; 32R6: or $2, $[[T1]], $[[T0]] +; 32R6-DAG: lw $[[F1H:[0-9]+]], 20($sp) +; 32R6-DAG: seleqz $[[T0:[0-9]+]], $7, $4 +; 32R6-DAG: selnez $[[T1:[0-9]+]], $[[F1H]], $4 +; 32R6: or $3, $[[T1]], $[[T0]] + +; 64: movn $5, $6, $4 +; 64: move $2, $5 + +; 64R2: movn $5, $6, $4 +; 64R2: move $2, $5 + +; FIXME: This sll works around an implementation detail in the code generator +; (setcc's result is i32 so bits 32-63 are undefined). It's not really +; needed. +; 64R6-DAG: sll $[[CC:[0-9]+]], $4, 0 +; 64R6-DAG: seleqz $[[T0:[0-9]+]], $5, $[[CC]] +; 64R6-DAG: selnez $[[T1:[0-9]+]], $6, $[[CC]] +; 64R6: or $2, $[[T1]], $[[T0]] + + %tobool = icmp ne i32 %s, 0 + %cond = select i1 %tobool, i64 %f1, i64 %f0 + ret i64 %cond +} + +define i64 @i64_icmp_ne_i64_val(i64 %s, i64 %f0, i64 %f1) nounwind readnone { entry: -; CHECK: movn.s +; ALL-LABEL: i64_icmp_ne_i64_val: + +; 32-DAG: or $[[CC:[0-9]+]], $4 +; 32-DAG: lw $[[F1:[0-9]+]], 16($sp) +; 32-DAG: movn $6, $[[F1]], $[[CC]] +; 32-DAG: lw $[[F1H:[0-9]+]], 20($sp) +; 32: movn $7, $[[F1H]], $[[CC]] +; 32: move $2, $6 +; 32: move $3, $7 + +; 32R2-DAG: or $[[CC:[0-9]+]], $4 +; 32R2-DAG: lw $[[F1:[0-9]+]], 16($sp) +; 32R2-DAG: movn $6, $[[F1]], $[[CC]] +; 32R2-DAG: lw $[[F1H:[0-9]+]], 20($sp) +; 32R2: movn $7, $[[F1H]], $[[CC]] +; 32R2: move $2, $6 +; 32R2: move $3, $7 + +; 32R6-DAG: lw $[[F1:[0-9]+]], 16($sp) +; 32R6-DAG: or $[[T2:[0-9]+]], $4, $5 +; 32R6-DAG: seleqz $[[T0:[0-9]+]], $6, $[[T2]] +; 32R6-DAG: selnez $[[T1:[0-9]+]], $[[F1]], $[[T2]] +; 32R6: or $2, $[[T1]], $[[T0]] +; 32R6-DAG: lw $[[F1H:[0-9]+]], 20($sp) +; 32R6-DAG: seleqz $[[T0:[0-9]+]], $7, $[[T2]] +; 32R6-DAG: selnez $[[T1:[0-9]+]], $[[F1H]], $[[T2]] +; 32R6: or $3, $[[T1]], $[[T0]] + +; 64: movn $5, $6, $4 +; 64: move $2, $5 + +; 64R2: movn $5, $6, $4 +; 64R2: move $2, $5 + +; 64R6-DAG: seleqz $[[T0:[0-9]+]], $5, $4 +; 64R6-DAG: selnez $[[T1:[0-9]+]], $6, $4 +; 64R6: or $2, $[[T1]], $[[T0]] + + %tobool = icmp ne i64 %s, 0 + %cond = select i1 %tobool, i64 %f1, i64 %f0 + ret i64 %cond +} + +define float @i32_icmp_ne_f32_val(i32 %s, float %f0, float %f1) nounwind readnone { +entry: +; ALL-LABEL: i32_icmp_ne_f32_val: + +; 32-DAG: mtc1 $5, $[[F0:f[0-9]+]] +; 32-DAG: mtc1 $6, $[[F1:f0]] +; 32: movn.s $[[F1]], $[[F0]], $4 + +; 32R2-DAG: mtc1 $5, $[[F0:f[0-9]+]] +; 32R2-DAG: mtc1 $6, $[[F1:f0]] +; 32R2: movn.s $[[F1]], $[[F0]], $4 + +; 32R6-DAG: mtc1 $5, $[[F0:f[0-9]+]] +; 32R6-DAG: mtc1 $6, $[[F1:f[0-9]+]] +; 32R6: sltu $[[T0:[0-9]+]], $zero, $4 +; 32R6: mtc1 $[[T0]], $[[CC:f0]] +; 32R6: sel.s $[[CC]], $[[F1]], $[[F0]] + +; 64: movn.s $f14, $f13, $4 +; 64: mov.s $f0, $f14 + +; 64R2: movn.s $f14, $f13, $4 +; 64R2: mov.s $f0, $f14 + +; 64R6: sltu $[[T0:[0-9]+]], $zero, $4 +; 64R6: mtc1 $[[T0]], $[[CC:f0]] +; 64R6: sel.s $[[CC]], $f14, $f13 + %tobool = icmp ne i32 %s, 0 %cond = select i1 %tobool, float %f0, float %f1 ret float %cond } -define double @sel2_1(i32 %s, double %f0, double %f1) nounwind readnone { +define double @i32_icmp_ne_f64_val(i32 %s, double %f0, double %f1) nounwind readnone { entry: -; CHECK: movn.d +; ALL-LABEL: i32_icmp_ne_f64_val: + +; 32-DAG: mtc1 $6, $[[F0:f[1-3]*[02468]+]] +; 32-DAG: mtc1 $7, $[[F0H:f[1-3]*[13579]+]] +; 32-DAG: ldc1 $[[F1:f0]], 16($sp) +; 32: movn.d $[[F1]], $[[F0]], $4 + +; 32R2-DAG: mtc1 $6, $[[F0:f[0-9]+]] +; 32R2-DAG: mthc1 $7, $[[F0]] +; 32R2-DAG: ldc1 $[[F1:f0]], 16($sp) +; 32R2: movn.d $[[F1]], $[[F0]], $4 + +; 32R6-DAG: mtc1 $6, $[[F0:f[0-9]+]] +; 32R6-DAG: mthc1 $7, $[[F0]] +; 32R6-DAG: sltu $[[T0:[0-9]+]], $zero, $4 +; 32R6-DAG: mtc1 $[[T0]], $[[CC:f0]] +; 32R6-DAG: ldc1 $[[F1:f[0-9]+]], 16($sp) +; 32R6: sel.d $[[CC]], $[[F1]], $[[F0]] + +; 64: movn.d $f14, $f13, $4 +; 64: mov.d $f0, $f14 + +; 64R2: movn.d $f14, $f13, $4 +; 64R2: mov.d $f0, $f14 + +; 64R6-DAG: sltu $[[T0:[0-9]+]], $zero, $4 +; 64R6-DAG: mtc1 $[[T0]], $[[CC:f0]] +; 64R6: sel.d $[[CC]], $f14, $f13 + %tobool = icmp ne i32 %s, 0 %cond = select i1 %tobool, double %f0, double %f1 ret double %cond } -define float @sel3(float %f0, float %f1, float %f2, float %f3) nounwind readnone { +define float @f32_fcmp_oeq_f32_val(float %f0, float %f1, float %f2, float %f3) nounwind readnone { entry: -; CHECK: c.eq.s -; CHECK: movt.s +; ALL-LABEL: f32_fcmp_oeq_f32_val: + +; 32-DAG: mtc1 $6, $[[F2:f[0-9]+]] +; 32-DAG: mtc1 $7, $[[F3:f[0-9]+]] +; 32: c.eq.s $[[F2]], $[[F3]] +; 32: movt.s $f14, $f12, $fcc0 +; 32: mov.s $f0, $f14 + +; 32R2-DAG: mtc1 $6, $[[F2:f[0-9]+]] +; 32R2-DAG: mtc1 $7, $[[F3:f[0-9]+]] +; 32R2: c.eq.s $[[F2]], $[[F3]] +; 32R2: movt.s $f14, $f12, $fcc0 +; 32R2: mov.s $f0, $f14 + +; 32R6-DAG: mtc1 $6, $[[F2:f[0-9]+]] +; 32R6-DAG: mtc1 $7, $[[F3:f[0-9]+]] +; 32R6: cmp.eq.s $[[CC:f0]], $[[F2]], $[[F3]] +; 32R6: sel.s $[[CC]], $f14, $f12 + +; 64: c.eq.s $f14, $f15 +; 64: movt.s $f13, $f12, $fcc0 +; 64: mov.s $f0, $f13 + +; 64R2: c.eq.s $f14, $f15 +; 64R2: movt.s $f13, $f12, $fcc0 +; 64R2: mov.s $f0, $f13 + +; 64R6: cmp.eq.s $[[CC:f0]], $f14, $f15 +; 64R6: sel.s $[[CC]], $f13, $f12 + %cmp = fcmp oeq float %f2, %f3 %cond = select i1 %cmp, float %f0, float %f1 ret float %cond } -define float @sel4(float %f0, float %f1, float %f2, float %f3) nounwind readnone { +define float @f32_fcmp_olt_f32_val(float %f0, float %f1, float %f2, float %f3) nounwind readnone { entry: -; CHECK: c.olt.s -; CHECK: movt.s +; ALL-LABEL: f32_fcmp_olt_f32_val: + +; 32-DAG: mtc1 $6, $[[F2:f[0-9]+]] +; 32-DAG: mtc1 $7, $[[F3:f[0-9]+]] +; 32: c.olt.s $[[F2]], $[[F3]] +; 32: movt.s $f14, $f12, $fcc0 +; 32: mov.s $f0, $f14 + +; 32R2-DAG: mtc1 $6, $[[F2:f[0-9]+]] +; 32R2-DAG: mtc1 $7, $[[F3:f[0-9]+]] +; 32R2: c.olt.s $[[F2]], $[[F3]] +; 32R2: movt.s $f14, $f12, $fcc0 +; 32R2: mov.s $f0, $f14 + +; 32R6-DAG: mtc1 $6, $[[F2:f[0-9]+]] +; 32R6-DAG: mtc1 $7, $[[F3:f[0-9]+]] +; 32R6: cmp.lt.s $[[CC:f0]], $[[F2]], $[[F3]] +; 32R6: sel.s $[[CC]], $f14, $f12 + +; 64: c.olt.s $f14, $f15 +; 64: movt.s $f13, $f12, $fcc0 +; 64: mov.s $f0, $f13 + +; 64R2: c.olt.s $f14, $f15 +; 64R2: movt.s $f13, $f12, $fcc0 +; 64R2: mov.s $f0, $f13 + +; 64R6: cmp.lt.s $[[CC:f0]], $f14, $f15 +; 64R6: sel.s $[[CC]], $f13, $f12 + %cmp = fcmp olt float %f2, %f3 %cond = select i1 %cmp, float %f0, float %f1 ret float %cond } -define float @sel5(float %f0, float %f1, float %f2, float %f3) nounwind readnone { +define float @f32_fcmp_ogt_f32_val(float %f0, float %f1, float %f2, float %f3) nounwind readnone { entry: -; CHECK: c.ule.s -; CHECK: movf.s +; ALL-LABEL: f32_fcmp_ogt_f32_val: + +; 32-DAG: mtc1 $6, $[[F2:f[0-9]+]] +; 32-DAG: mtc1 $7, $[[F3:f[0-9]+]] +; 32: c.ule.s $[[F2]], $[[F3]] +; 32: movf.s $f14, $f12, $fcc0 +; 32: mov.s $f0, $f14 + +; 32R2-DAG: mtc1 $6, $[[F2:f[0-9]+]] +; 32R2-DAG: mtc1 $7, $[[F3:f[0-9]+]] +; 32R2: c.ule.s $[[F2]], $[[F3]] +; 32R2: movf.s $f14, $f12, $fcc0 +; 32R2: mov.s $f0, $f14 + +; 32R6-DAG: mtc1 $6, $[[F2:f[0-9]+]] +; 32R6-DAG: mtc1 $7, $[[F3:f[0-9]+]] +; 32R6: cmp.lt.s $[[CC:f0]], $[[F3]], $[[F2]] +; 32R6: sel.s $[[CC]], $f14, $f12 + +; 64: c.ule.s $f14, $f15 +; 64: movf.s $f13, $f12, $fcc0 +; 64: mov.s $f0, $f13 + +; 64R2: c.ule.s $f14, $f15 +; 64R2: movf.s $f13, $f12, $fcc0 +; 64R2: mov.s $f0, $f13 + +; 64R6: cmp.lt.s $[[CC:f0]], $f15, $f14 +; 64R6: sel.s $[[CC]], $f13, $f12 + %cmp = fcmp ogt float %f2, %f3 %cond = select i1 %cmp, float %f0, float %f1 ret float %cond } -define double @sel5_1(double %f0, double %f1, float %f2, float %f3) nounwind readnone { +define double @f32_fcmp_ogt_f64_val(double %f0, double %f1, float %f2, float %f3) nounwind readnone { entry: -; CHECK: c.ule.s -; CHECK: movf.d +; ALL-LABEL: f32_fcmp_ogt_f64_val: + +; 32-DAG: lwc1 $[[F2:f[0-9]+]], 16($sp) +; 32-DAG: lwc1 $[[F3:f[0-9]+]], 20($sp) +; 32: c.ule.s $[[F2]], $[[F3]] +; 32: movf.d $f14, $f12, $fcc0 +; 32: mov.d $f0, $f14 + +; 32R2-DAG: lwc1 $[[F2:f[0-9]+]], 16($sp) +; 32R2-DAG: lwc1 $[[F3:f[0-9]+]], 20($sp) +; 32R2: c.ule.s $[[F2]], $[[F3]] +; 32R2: movf.d $f14, $f12, $fcc0 +; 32R2: mov.d $f0, $f14 + +; 32R6-DAG: lwc1 $[[F2:f[0-9]+]], 16($sp) +; 32R6-DAG: lwc1 $[[F3:f[0-9]+]], 20($sp) +; 32R6: cmp.lt.s $[[CC:f0]], $[[F3]], $[[F2]] +; 32R6: sel.d $[[CC]], $f14, $f12 + +; 64: c.ule.s $f14, $f15 +; 64: movf.d $f13, $f12, $fcc0 +; 64: mov.d $f0, $f13 + +; 64R2: c.ule.s $f14, $f15 +; 64R2: movf.d $f13, $f12, $fcc0 +; 64R2: mov.d $f0, $f13 + +; 64R6: cmp.lt.s $[[CC:f0]], $f15, $f14 +; 64R6: sel.d $[[CC]], $f13, $f12 + %cmp = fcmp ogt float %f2, %f3 %cond = select i1 %cmp, double %f0, double %f1 ret double %cond } -define double @sel6(double %f0, double %f1, double %f2, double %f3) nounwind readnone { +define double @f64_fcmp_oeq_f64_val(double %f0, double %f1, double %f2, double %f3) nounwind readnone { entry: -; CHECK: c.eq.d -; CHECK: movt.d +; ALL-LABEL: f64_fcmp_oeq_f64_val: + +; 32-DAG: ldc1 $[[F2:f[0-9]+]], 16($sp) +; 32-DAG: ldc1 $[[F3:f[0-9]+]], 24($sp) +; 32: c.eq.d $[[F2]], $[[F3]] +; 32: movt.d $f14, $f12, $fcc0 +; 32: mov.d $f0, $f14 + +; 32R2-DAG: ldc1 $[[F2:f[0-9]+]], 16($sp) +; 32R2-DAG: ldc1 $[[F3:f[0-9]+]], 24($sp) +; 32R2: c.eq.d $[[F2]], $[[F3]] +; 32R2: movt.d $f14, $f12, $fcc0 +; 32R2: mov.d $f0, $f14 + +; 32R6-DAG: ldc1 $[[F2:f[0-9]+]], 16($sp) +; 32R6-DAG: ldc1 $[[F3:f[0-9]+]], 24($sp) +; 32R6: cmp.eq.d $[[CC:f0]], $[[F2]], $[[F3]] +; 32R6: sel.d $[[CC]], $f14, $f12 + +; 64: c.eq.d $f14, $f15 +; 64: movt.d $f13, $f12, $fcc0 +; 64: mov.d $f0, $f13 + +; 64R2: c.eq.d $f14, $f15 +; 64R2: movt.d $f13, $f12, $fcc0 +; 64R2: mov.d $f0, $f13 + +; 64R6: cmp.eq.d $[[CC:f0]], $f14, $f15 +; 64R6: sel.d $[[CC]], $f13, $f12 + %cmp = fcmp oeq double %f2, %f3 %cond = select i1 %cmp, double %f0, double %f1 ret double %cond } -define double @sel7(double %f0, double %f1, double %f2, double %f3) nounwind readnone { +define double @f64_fcmp_olt_f64_val(double %f0, double %f1, double %f2, double %f3) nounwind readnone { entry: -; CHECK: c.olt.d -; CHECK: movt.d +; ALL-LABEL: f64_fcmp_olt_f64_val: + +; 32-DAG: ldc1 $[[F2:f[0-9]+]], 16($sp) +; 32-DAG: ldc1 $[[F3:f[0-9]+]], 24($sp) +; 32: c.olt.d $[[F2]], $[[F3]] +; 32: movt.d $f14, $f12, $fcc0 +; 32: mov.d $f0, $f14 + +; 32R2-DAG: ldc1 $[[F2:f[0-9]+]], 16($sp) +; 32R2-DAG: ldc1 $[[F3:f[0-9]+]], 24($sp) +; 32R2: c.olt.d $[[F2]], $[[F3]] +; 32R2: movt.d $f14, $f12, $fcc0 +; 32R2: mov.d $f0, $f14 + +; 32R6-DAG: ldc1 $[[F2:f[0-9]+]], 16($sp) +; 32R6-DAG: ldc1 $[[F3:f[0-9]+]], 24($sp) +; 32R6: cmp.lt.d $[[CC:f0]], $[[F2]], $[[F3]] +; 32R6: sel.d $[[CC]], $f14, $f12 + +; 64: c.olt.d $f14, $f15 +; 64: movt.d $f13, $f12, $fcc0 +; 64: mov.d $f0, $f13 + +; 64R2: c.olt.d $f14, $f15 +; 64R2: movt.d $f13, $f12, $fcc0 +; 64R2: mov.d $f0, $f13 + +; 64R6: cmp.lt.d $[[CC:f0]], $f14, $f15 +; 64R6: sel.d $[[CC]], $f13, $f12 + %cmp = fcmp olt double %f2, %f3 %cond = select i1 %cmp, double %f0, double %f1 ret double %cond } -define double @sel8(double %f0, double %f1, double %f2, double %f3) nounwind readnone { +define double @f64_fcmp_ogt_f64_val(double %f0, double %f1, double %f2, double %f3) nounwind readnone { entry: -; CHECK: c.ule.d -; CHECK: movf.d +; ALL-LABEL: f64_fcmp_ogt_f64_val: + +; 32-DAG: ldc1 $[[F2:f[0-9]+]], 16($sp) +; 32-DAG: ldc1 $[[F3:f[0-9]+]], 24($sp) +; 32: c.ule.d $[[F2]], $[[F3]] +; 32: movf.d $f14, $f12, $fcc0 +; 32: mov.d $f0, $f14 + +; 32R2-DAG: ldc1 $[[F2:f[0-9]+]], 16($sp) +; 32R2-DAG: ldc1 $[[F3:f[0-9]+]], 24($sp) +; 32R2: c.ule.d $[[F2]], $[[F3]] +; 32R2: movf.d $f14, $f12, $fcc0 +; 32R2: mov.d $f0, $f14 + +; 32R6-DAG: ldc1 $[[F2:f[0-9]+]], 16($sp) +; 32R6-DAG: ldc1 $[[F3:f[0-9]+]], 24($sp) +; 32R6: cmp.lt.d $[[CC:f0]], $[[F3]], $[[F2]] +; 32R6: sel.d $[[CC]], $f14, $f12 + +; 64: c.ule.d $f14, $f15 +; 64: movf.d $f13, $f12, $fcc0 +; 64: mov.d $f0, $f13 + +; 64R2: c.ule.d $f14, $f15 +; 64R2: movf.d $f13, $f12, $fcc0 +; 64R2: mov.d $f0, $f13 + +; 64R6: cmp.lt.d $[[CC:f0]], $f15, $f14 +; 64R6: sel.d $[[CC]], $f13, $f12 + %cmp = fcmp ogt double %f2, %f3 %cond = select i1 %cmp, double %f0, double %f1 ret double %cond } -define float @sel8_1(float %f0, float %f1, double %f2, double %f3) nounwind readnone { +define float @f64_fcmp_ogt_f32_val(float %f0, float %f1, double %f2, double %f3) nounwind readnone { entry: -; CHECK: c.ule.d -; CHECK: movf.s +; ALL-LABEL: f64_fcmp_ogt_f32_val: + +; 32-DAG: mtc1 $6, $[[F2:f[1-3]*[02468]+]] +; 32-DAG: mtc1 $7, $[[F2H:f[1-3]*[13579]+]] +; 32-DAG: ldc1 $[[F3:f[0-9]+]], 16($sp) +; 32: c.ule.d $[[F2]], $[[F3]] +; 32: movf.s $f14, $f12, $fcc0 +; 32: mov.s $f0, $f14 + +; 32R2-DAG: mtc1 $6, $[[F2:f[0-9]+]] +; 32R2-DAG: mthc1 $7, $[[F2]] +; 32R2-DAG: ldc1 $[[F3:f[0-9]+]], 16($sp) +; 32R2: c.ule.d $[[F2]], $[[F3]] +; 32R2: movf.s $f14, $f12, $fcc0 +; 32R2: mov.s $f0, $f14 + +; 32R6-DAG: mtc1 $6, $[[F2:f[0-9]+]] +; 32R6-DAG: mthc1 $7, $[[F2]] +; 32R6-DAG: ldc1 $[[F3:f[0-9]+]], 16($sp) +; 32R6: cmp.lt.d $[[CC:f0]], $[[F3]], $[[F2]] +; 32R6: sel.s $[[CC]], $f14, $f12 + +; 64: c.ule.d $f14, $f15 +; 64: movf.s $f13, $f12, $fcc0 +; 64: mov.s $f0, $f13 + +; 64R2: c.ule.d $f14, $f15 +; 64R2: movf.s $f13, $f12, $fcc0 +; 64R2: mov.s $f0, $f13 + +; 64R6: cmp.lt.d $[[CC:f0]], $f15, $f14 +; 64R6: sel.s $[[CC]], $f13, $f12 + %cmp = fcmp ogt double %f2, %f3 %cond = select i1 %cmp, float %f0, float %f1 ret float %cond } -define i32 @sel9(i32 %f0, i32 %f1, float %f2, float %f3) nounwind readnone { +define i32 @f32_fcmp_oeq_i32_val(i32 %f0, i32 %f1, float %f2, float %f3) nounwind readnone { entry: -; CHECK: c.eq.s -; CHECK: movt +; ALL-LABEL: f32_fcmp_oeq_i32_val: + +; 32-DAG: mtc1 $6, $[[F2:f[0-9]+]] +; 32-DAG: mtc1 $7, $[[F3:f[0-9]+]] +; 32: c.eq.s $[[F2]], $[[F3]] +; 32: movt $5, $4, $fcc0 +; 32: move $2, $5 + +; 32R2-DAG: mtc1 $6, $[[F2:f[0-9]+]] +; 32R2-DAG: mtc1 $7, $[[F3:f[0-9]+]] +; 32R2: c.eq.s $[[F2]], $[[F3]] +; 32R2: movt $5, $4, $fcc0 +; 32R2: move $2, $5 + +; 32R6-DAG: mtc1 $6, $[[F2:f[0-9]+]] +; 32R6-DAG: mtc1 $7, $[[F3:f[0-9]+]] +; 32R6: cmp.eq.s $[[CC:f[0-9]+]], $[[F2]], $[[F3]] +; 32R6: mfc1 $[[CCGPR:[0-9]+]], $[[CC]] +; 32R6: andi $[[CCGPR]], $[[CCGPR]], 1 +; 32R6: seleqz $[[EQ:[0-9]+]], $5, $[[CCGPR]] +; 32R6: selnez $[[NE:[0-9]+]], $4, $[[CCGPR]] +; 32R6: or $2, $[[NE]], $[[EQ]] + +; 64: c.eq.s $f14, $f15 +; 64: movt $5, $4, $fcc0 +; 64: move $2, $5 + +; 64R2: c.eq.s $f14, $f15 +; 64R2: movt $5, $4, $fcc0 +; 64R2: move $2, $5 + +; 64R6: cmp.eq.s $[[CC:f[0-9]+]], $f14, $f15 +; 64R6: mfc1 $[[CCGPR:[0-9]+]], $[[CC]] +; 64R6: andi $[[CCGPR]], $[[CCGPR]], 1 +; 64R6: seleqz $[[EQ:[0-9]+]], $5, $[[CCGPR]] +; 64R6: selnez $[[NE:[0-9]+]], $4, $[[CCGPR]] +; 64R6: or $2, $[[NE]], $[[EQ]] + %cmp = fcmp oeq float %f2, %f3 %cond = select i1 %cmp, i32 %f0, i32 %f1 ret i32 %cond } -define i32 @sel10(i32 %f0, i32 %f1, float %f2, float %f3) nounwind readnone { +define i32 @f32_fcmp_olt_i32_val(i32 %f0, i32 %f1, float %f2, float %f3) nounwind readnone { entry: -; CHECK: c.olt.s -; CHECK: movt +; ALL-LABEL: f32_fcmp_olt_i32_val: + +; 32-DAG: mtc1 $6, $[[F2:f[0-9]+]] +; 32-DAG: mtc1 $7, $[[F3:f[0-9]+]] +; 32: c.olt.s $[[F2]], $[[F3]] +; 32: movt $5, $4, $fcc0 +; 32: move $2, $5 + +; 32R2-DAG: mtc1 $6, $[[F2:f[0-9]+]] +; 32R2-DAG: mtc1 $7, $[[F3:f[0-9]+]] +; 32R2: c.olt.s $[[F2]], $[[F3]] +; 32R2: movt $5, $4, $fcc0 +; 32R2: move $2, $5 + +; 32R6-DAG: mtc1 $6, $[[F2:f[0-9]+]] +; 32R6-DAG: mtc1 $7, $[[F3:f[0-9]+]] +; 32R6: cmp.lt.s $[[CC:f[0-9]+]], $[[F2]], $[[F3]] +; 32R6: mfc1 $[[CCGPR:[0-9]+]], $[[CC]] +; 32R6: andi $[[CCGPR]], $[[CCGPR]], 1 +; 32R6: seleqz $[[EQ:[0-9]+]], $5, $[[CCGPR]] +; 32R6: selnez $[[NE:[0-9]+]], $4, $[[CCGPR]] +; 32R6: or $2, $[[NE]], $[[EQ]] + +; 64: c.olt.s $f14, $f15 +; 64: movt $5, $4, $fcc0 +; 64: move $2, $5 + +; 64R2: c.olt.s $f14, $f15 +; 64R2: movt $5, $4, $fcc0 +; 64R2: move $2, $5 + +; 64R6: cmp.lt.s $[[CC:f[0-9]+]], $f14, $f15 +; 64R6: mfc1 $[[CCGPR:[0-9]+]], $[[CC]] +; 64R6: andi $[[CCGPR]], $[[CCGPR]], 1 +; 64R6: seleqz $[[EQ:[0-9]+]], $5, $[[CCGPR]] +; 64R6: selnez $[[NE:[0-9]+]], $4, $[[CCGPR]] +; 64R6: or $2, $[[NE]], $[[EQ]] %cmp = fcmp olt float %f2, %f3 %cond = select i1 %cmp, i32 %f0, i32 %f1 ret i32 %cond } -define i32 @sel11(i32 %f0, i32 %f1, float %f2, float %f3) nounwind readnone { +define i32 @f32_fcmp_ogt_i32_val(i32 %f0, i32 %f1, float %f2, float %f3) nounwind readnone { entry: -; CHECK: c.ule.s -; CHECK: movf +; ALL-LABEL: f32_fcmp_ogt_i32_val: + +; 32-DAG: mtc1 $6, $[[F2:f[0-9]+]] +; 32-DAG: mtc1 $7, $[[F3:f[0-9]+]] +; 32: c.ule.s $[[F2]], $[[F3]] +; 32: movf $5, $4, $fcc0 +; 32: move $2, $5 + +; 32R2-DAG: mtc1 $6, $[[F2:f[0-9]+]] +; 32R2-DAG: mtc1 $7, $[[F3:f[0-9]+]] +; 32R2: c.ule.s $[[F2]], $[[F3]] +; 32R2: movf $5, $4, $fcc0 +; 32R2: move $2, $5 + +; 32R6-DAG: mtc1 $6, $[[F2:f[0-9]+]] +; 32R6-DAG: mtc1 $7, $[[F3:f[0-9]+]] +; 32R6: cmp.lt.s $[[CC:f[0-9]+]], $[[F3]], $[[F2]] +; 32R6: mfc1 $[[CCGPR:[0-9]+]], $[[CC]] +; 32R6: andi $[[CCGPR]], $[[CCGPR]], 1 +; 32R6: seleqz $[[EQ:[0-9]+]], $5, $[[CCGPR]] +; 32R6: selnez $[[NE:[0-9]+]], $4, $[[CCGPR]] +; 32R6: or $2, $[[NE]], $[[EQ]] + +; 64: c.ule.s $f14, $f15 +; 64: movf $5, $4, $fcc0 +; 64: move $2, $5 + +; 64R2: c.ule.s $f14, $f15 +; 64R2: movf $5, $4, $fcc0 +; 64R2: move $2, $5 + +; 64R6: cmp.lt.s $[[CC:f[0-9]+]], $f15, $f14 +; 64R6: mfc1 $[[CCGPR:[0-9]+]], $[[CC]] +; 64R6: andi $[[CCGPR]], $[[CCGPR]], 1 +; 64R6: seleqz $[[EQ:[0-9]+]], $5, $[[CCGPR]] +; 64R6: selnez $[[NE:[0-9]+]], $4, $[[CCGPR]] +; 64R6: or $2, $[[NE]], $[[EQ]] + %cmp = fcmp ogt float %f2, %f3 %cond = select i1 %cmp, i32 %f0, i32 %f1 ret i32 %cond } -define i32 @sel12(i32 %f0, i32 %f1) nounwind readonly { +define i32 @f64_fcmp_oeq_i32_val(i32 %f0, i32 %f1) nounwind readonly { entry: -; CHECK: c.eq.d -; CHECK: movt +; ALL-LABEL: f64_fcmp_oeq_i32_val: + +; 32-DAG: addiu $[[T0:[0-9]+]], ${{[0-9]+}}, %lo(_gp_disp) +; 32-DAG: addu $[[GOT:[0-9]+]], $[[T0]], $25 +; 32-DAG: lw $[[D2:[0-9]+]], %got(d2)($1) +; 32-DAG: ldc1 $[[TMP:f[0-9]+]], 0($[[D2]]) +; 32-DAG: lw $[[D3:[0-9]+]], %got(d3)($1) +; 32-DAG: ldc1 $[[TMP1:f[0-9]+]], 0($[[D3]]) +; 32: c.eq.d $[[TMP]], $[[TMP1]] +; 32: movt $5, $4, $fcc0 +; 32: move $2, $5 + +; 32R2-DAG: addiu $[[T0:[0-9]+]], ${{[0-9]+}}, %lo(_gp_disp) +; 32R2-DAG: addu $[[GOT:[0-9]+]], $[[T0]], $25 +; 32R2-DAG: lw $[[D2:[0-9]+]], %got(d2)($1) +; 32R2-DAG: ldc1 $[[TMP:f[0-9]+]], 0($[[D2]]) +; 32R2-DAG: lw $[[D3:[0-9]+]], %got(d3)($1) +; 32R2-DAG: ldc1 $[[TMP1:f[0-9]+]], 0($[[D3]]) +; 32R2: c.eq.d $[[TMP]], $[[TMP1]] +; 32R2: movt $5, $4, $fcc0 +; 32R2: move $2, $5 + +; 32R6-DAG: addiu $[[T0:[0-9]+]], ${{[0-9]+}}, %lo(_gp_disp) +; 32R6-DAG: addu $[[GOT:[0-9]+]], $[[T0]], $25 +; 32R6-DAG: lw $[[D2:[0-9]+]], %got(d2)($1) +; 32R6-DAG: ldc1 $[[TMP:f[0-9]+]], 0($[[D2]]) +; 32R6-DAG: lw $[[D3:[0-9]+]], %got(d3)($1) +; 32R6-DAG: ldc1 $[[TMP1:f[0-9]+]], 0($[[D3]]) +; 32R6: cmp.eq.d $[[CC:f[0-9]+]], $[[TMP]], $[[TMP1]] +; 32R6: mfc1 $[[CCGPR:[0-9]+]], $[[CC]] +; 32R6: andi $[[CCGPR]], $[[CCGPR]], 1 +; 32R6: seleqz $[[EQ:[0-9]+]], $5, $[[CCGPR]] +; 32R6: selnez $[[NE:[0-9]+]], $4, $[[CCGPR]] +; 32R6: or $2, $[[NE]], $[[EQ]] + +; 64-DAG: daddiu $[[T0:[0-9]+]], ${{[0-9]+}}, %lo(%neg(%gp_rel(f64_fcmp_oeq_i32_val))) +; 64-DAG: daddu $[[GOT:[0-9]+]], $[[T0]], $25 +; 64-DAG: ld $[[D2:[0-9]+]], %got_disp(d2)($1) +; 64-DAG: ldc1 $[[TMP:f[0-9]+]], 0($[[D2]]) +; 64-DAG: ld $[[D3:[0-9]+]], %got_disp(d3)($1) +; 64-DAG: ldc1 $[[TMP1:f[0-9]+]], 0($[[D3]]) +; 64: c.eq.d $[[TMP]], $[[TMP1]] +; 64: movt $5, $4, $fcc0 +; 64: move $2, $5 + +; 64R2-DAG: daddiu $[[T0:[0-9]+]], ${{[0-9]+}}, %lo(%neg(%gp_rel(f64_fcmp_oeq_i32_val))) +; 64R2-DAG: daddu $[[GOT:[0-9]+]], $[[T0]], $25 +; 64R2-DAG: ld $[[D2:[0-9]+]], %got_disp(d2)($1) +; 64R2-DAG: ldc1 $[[TMP:f[0-9]+]], 0($[[D2]]) +; 64R2-DAG: ld $[[D3:[0-9]+]], %got_disp(d3)($1) +; 64R2-DAG: ldc1 $[[TMP1:f[0-9]+]], 0($[[D3]]) +; 64R2: c.eq.d $[[TMP]], $[[TMP1]] +; 64R2: movt $5, $4, $fcc0 +; 64R2: move $2, $5 + +; 64R6-DAG: daddiu $[[T0:[0-9]+]], ${{[0-9]+}}, %lo(%neg(%gp_rel(f64_fcmp_oeq_i32_val))) +; 64R6-DAG: daddu $[[GOT:[0-9]+]], $[[T0]], $25 +; 64R6-DAG: ld $[[D2:[0-9]+]], %got_disp(d2)($1) +; 64R6-DAG: ldc1 $[[TMP:f[0-9]+]], 0($[[D2]]) +; 64R6-DAG: ld $[[D3:[0-9]+]], %got_disp(d3)($1) +; 64R6-DAG: ldc1 $[[TMP1:f[0-9]+]], 0($[[D3]]) +; 64R6: cmp.eq.d $[[CC:f[0-9]+]], $[[TMP]], $[[TMP1]] +; 64R6: mfc1 $[[CCGPR:[0-9]+]], $[[CC]] +; 64R6: andi $[[CCGPR]], $[[CCGPR]], 1 +; 64R6: seleqz $[[EQ:[0-9]+]], $5, $[[CCGPR]] +; 64R6: selnez $[[NE:[0-9]+]], $4, $[[CCGPR]] +; 64R6: or $2, $[[NE]], $[[EQ]] + %tmp = load double* @d2, align 8 %tmp1 = load double* @d3, align 8 %cmp = fcmp oeq double %tmp, %tmp1 @@ -137,10 +707,76 @@ entry: ret i32 %cond } -define i32 @sel13(i32 %f0, i32 %f1) nounwind readonly { +define i32 @f64_fcmp_olt_i32_val(i32 %f0, i32 %f1) nounwind readonly { entry: -; CHECK: c.olt.d -; CHECK: movt +; ALL-LABEL: f64_fcmp_olt_i32_val: + +; 32-DAG: addiu $[[T0:[0-9]+]], ${{[0-9]+}}, %lo(_gp_disp) +; 32-DAG: addu $[[GOT:[0-9]+]], $[[T0]], $25 +; 32-DAG: lw $[[D2:[0-9]+]], %got(d2)($1) +; 32-DAG: ldc1 $[[TMP:f[0-9]+]], 0($[[D2]]) +; 32-DAG: lw $[[D3:[0-9]+]], %got(d3)($1) +; 32-DAG: ldc1 $[[TMP1:f[0-9]+]], 0($[[D3]]) +; 32: c.olt.d $[[TMP]], $[[TMP1]] +; 32: movt $5, $4, $fcc0 +; 32: move $2, $5 + +; 32R2-DAG: addiu $[[T0:[0-9]+]], ${{[0-9]+}}, %lo(_gp_disp) +; 32R2-DAG: addu $[[GOT:[0-9]+]], $[[T0]], $25 +; 32R2-DAG: lw $[[D2:[0-9]+]], %got(d2)($1) +; 32R2-DAG: ldc1 $[[TMP:f[0-9]+]], 0($[[D2]]) +; 32R2-DAG: lw $[[D3:[0-9]+]], %got(d3)($1) +; 32R2-DAG: ldc1 $[[TMP1:f[0-9]+]], 0($[[D3]]) +; 32R2: c.olt.d $[[TMP]], $[[TMP1]] +; 32R2: movt $5, $4, $fcc0 +; 32R2: move $2, $5 + +; 32R6-DAG: addiu $[[T0:[0-9]+]], ${{[0-9]+}}, %lo(_gp_disp) +; 32R6-DAG: addu $[[GOT:[0-9]+]], $[[T0]], $25 +; 32R6-DAG: lw $[[D2:[0-9]+]], %got(d2)($1) +; 32R6-DAG: ldc1 $[[TMP:f[0-9]+]], 0($[[D2]]) +; 32R6-DAG: lw $[[D3:[0-9]+]], %got(d3)($1) +; 32R6-DAG: ldc1 $[[TMP1:f[0-9]+]], 0($[[D3]]) +; 32R6: cmp.lt.d $[[CC:f[0-9]+]], $[[TMP]], $[[TMP1]] +; 32R6: mfc1 $[[CCGPR:[0-9]+]], $[[CC]] +; 32R6: andi $[[CCGPR]], $[[CCGPR]], 1 +; 32R6: seleqz $[[EQ:[0-9]+]], $5, $[[CCGPR]] +; 32R6: selnez $[[NE:[0-9]+]], $4, $[[CCGPR]] +; 32R6: or $2, $[[NE]], $[[EQ]] + +; 64-DAG: daddiu $[[T0:[0-9]+]], ${{[0-9]+}}, %lo(%neg(%gp_rel(f64_fcmp_olt_i32_val))) +; 64-DAG: daddu $[[GOT:[0-9]+]], $[[T0]], $25 +; 64-DAG: ld $[[D2:[0-9]+]], %got_disp(d2)($1) +; 64-DAG: ldc1 $[[TMP:f[0-9]+]], 0($[[D2]]) +; 64-DAG: ld $[[D3:[0-9]+]], %got_disp(d3)($1) +; 64-DAG: ldc1 $[[TMP1:f[0-9]+]], 0($[[D3]]) +; 64: c.olt.d $[[TMP]], $[[TMP1]] +; 64: movt $5, $4, $fcc0 +; 64: move $2, $5 + +; 64R2-DAG: daddiu $[[T0:[0-9]+]], ${{[0-9]+}}, %lo(%neg(%gp_rel(f64_fcmp_olt_i32_val))) +; 64R2-DAG: daddu $[[GOT:[0-9]+]], $[[T0]], $25 +; 64R2-DAG: ld $[[D2:[0-9]+]], %got_disp(d2)($1) +; 64R2-DAG: ldc1 $[[TMP:f[0-9]+]], 0($[[D2]]) +; 64R2-DAG: ld $[[D3:[0-9]+]], %got_disp(d3)($1) +; 64R2-DAG: ldc1 $[[TMP1:f[0-9]+]], 0($[[D3]]) +; 64R2: c.olt.d $[[TMP]], $[[TMP1]] +; 64R2: movt $5, $4, $fcc0 +; 64R2: move $2, $5 + +; 64R6-DAG: daddiu $[[T0:[0-9]+]], ${{[0-9]+}}, %lo(%neg(%gp_rel(f64_fcmp_olt_i32_val))) +; 64R6-DAG: daddu $[[GOT:[0-9]+]], $[[T0]], $25 +; 64R6-DAG: ld $[[D2:[0-9]+]], %got_disp(d2)($1) +; 64R6-DAG: ldc1 $[[TMP:f[0-9]+]], 0($[[D2]]) +; 64R6-DAG: ld $[[D3:[0-9]+]], %got_disp(d3)($1) +; 64R6-DAG: ldc1 $[[TMP1:f[0-9]+]], 0($[[D3]]) +; 64R6: cmp.lt.d $[[CC:f[0-9]+]], $[[TMP]], $[[TMP1]] +; 64R6: mfc1 $[[CCGPR:[0-9]+]], $[[CC]] +; 64R6: andi $[[CCGPR]], $[[CCGPR]], 1 +; 64R6: seleqz $[[EQ:[0-9]+]], $5, $[[CCGPR]] +; 64R6: selnez $[[NE:[0-9]+]], $4, $[[CCGPR]] +; 64R6: or $2, $[[NE]], $[[EQ]] + %tmp = load double* @d2, align 8 %tmp1 = load double* @d3, align 8 %cmp = fcmp olt double %tmp, %tmp1 @@ -148,10 +784,76 @@ entry: ret i32 %cond } -define i32 @sel14(i32 %f0, i32 %f1) nounwind readonly { +define i32 @f64_fcmp_ogt_i32_val(i32 %f0, i32 %f1) nounwind readonly { entry: -; CHECK: c.ule.d -; CHECK: movf +; ALL-LABEL: f64_fcmp_ogt_i32_val: + +; 32-DAG: addiu $[[T0:[0-9]+]], ${{[0-9]+}}, %lo(_gp_disp) +; 32-DAG: addu $[[GOT:[0-9]+]], $[[T0]], $25 +; 32-DAG: lw $[[D2:[0-9]+]], %got(d2)($1) +; 32-DAG: ldc1 $[[TMP:f[0-9]+]], 0($[[D2]]) +; 32-DAG: lw $[[D3:[0-9]+]], %got(d3)($1) +; 32-DAG: ldc1 $[[TMP1:f[0-9]+]], 0($[[D3]]) +; 32: c.ule.d $[[TMP]], $[[TMP1]] +; 32: movf $5, $4, $fcc0 +; 32: move $2, $5 + +; 32R2-DAG: addiu $[[T0:[0-9]+]], ${{[0-9]+}}, %lo(_gp_disp) +; 32R2-DAG: addu $[[GOT:[0-9]+]], $[[T0]], $25 +; 32R2-DAG: lw $[[D2:[0-9]+]], %got(d2)($1) +; 32R2-DAG: ldc1 $[[TMP:f[0-9]+]], 0($[[D2]]) +; 32R2-DAG: lw $[[D3:[0-9]+]], %got(d3)($1) +; 32R2-DAG: ldc1 $[[TMP1:f[0-9]+]], 0($[[D3]]) +; 32R2: c.ule.d $[[TMP]], $[[TMP1]] +; 32R2: movf $5, $4, $fcc0 +; 32R2: move $2, $5 + +; 32R6-DAG: addiu $[[T0:[0-9]+]], ${{[0-9]+}}, %lo(_gp_disp) +; 32R6-DAG: addu $[[GOT:[0-9]+]], $[[T0]], $25 +; 32R6-DAG: lw $[[D2:[0-9]+]], %got(d2)($1) +; 32R6-DAG: ldc1 $[[TMP:f[0-9]+]], 0($[[D2]]) +; 32R6-DAG: lw $[[D3:[0-9]+]], %got(d3)($1) +; 32R6-DAG: ldc1 $[[TMP1:f[0-9]+]], 0($[[D3]]) +; 32R6: cmp.lt.d $[[CC:f[0-9]+]], $[[TMP1]], $[[TMP]] +; 32R6: mfc1 $[[CCGPR:[0-9]+]], $[[CC]] +; 32R6: andi $[[CCGPR]], $[[CCGPR]], 1 +; 32R6: seleqz $[[EQ:[0-9]+]], $5, $[[CCGPR]] +; 32R6: selnez $[[NE:[0-9]+]], $4, $[[CCGPR]] +; 32R6: or $2, $[[NE]], $[[EQ]] + +; 64-DAG: daddiu $[[T0:[0-9]+]], ${{[0-9]+}}, %lo(%neg(%gp_rel(f64_fcmp_ogt_i32_val))) +; 64-DAG: daddu $[[GOT:[0-9]+]], $[[T0]], $25 +; 64-DAG: ld $[[D2:[0-9]+]], %got_disp(d2)($1) +; 64-DAG: ldc1 $[[TMP:f[0-9]+]], 0($[[D2]]) +; 64-DAG: ld $[[D3:[0-9]+]], %got_disp(d3)($1) +; 64-DAG: ldc1 $[[TMP1:f[0-9]+]], 0($[[D3]]) +; 64: c.ule.d $[[TMP]], $[[TMP1]] +; 64: movf $5, $4, $fcc0 +; 64: move $2, $5 + +; 64R2-DAG: daddiu $[[T0:[0-9]+]], ${{[0-9]+}}, %lo(%neg(%gp_rel(f64_fcmp_ogt_i32_val))) +; 64R2-DAG: daddu $[[GOT:[0-9]+]], $[[T0]], $25 +; 64R2-DAG: ld $[[D2:[0-9]+]], %got_disp(d2)($1) +; 64R2-DAG: ldc1 $[[TMP:f[0-9]+]], 0($[[D2]]) +; 64R2-DAG: ld $[[D3:[0-9]+]], %got_disp(d3)($1) +; 64R2-DAG: ldc1 $[[TMP1:f[0-9]+]], 0($[[D3]]) +; 64R2: c.ule.d $[[TMP]], $[[TMP1]] +; 64R2: movf $5, $4, $fcc0 +; 64R2: move $2, $5 + +; 64R6-DAG: daddiu $[[T0:[0-9]+]], ${{[0-9]+}}, %lo(%neg(%gp_rel(f64_fcmp_ogt_i32_val))) +; 64R6-DAG: daddu $[[GOT:[0-9]+]], $[[T0]], $25 +; 64R6-DAG: ld $[[D2:[0-9]+]], %got_disp(d2)($1) +; 64R6-DAG: ldc1 $[[TMP:f[0-9]+]], 0($[[D2]]) +; 64R6-DAG: ld $[[D3:[0-9]+]], %got_disp(d3)($1) +; 64R6-DAG: ldc1 $[[TMP1:f[0-9]+]], 0($[[D3]]) +; 64R6: cmp.lt.d $[[CC:f[0-9]+]], $[[TMP1]], $[[TMP]] +; 64R6: mfc1 $[[CCGPR:[0-9]+]], $[[CC]] +; 64R6: andi $[[CCGPR]], $[[CCGPR]], 1 +; 64R6: seleqz $[[EQ:[0-9]+]], $5, $[[CCGPR]] +; 64R6: selnez $[[NE:[0-9]+]], $4, $[[CCGPR]] +; 64R6: or $2, $[[NE]], $[[EQ]] + %tmp = load double* @d2, align 8 %tmp1 = load double* @d3, align 8 %cmp = fcmp ogt double %tmp, %tmp1 diff --git a/test/CodeGen/Mips/selectcc.ll b/test/CodeGen/Mips/selectcc.ll index aeef60e..9790a0a 100644 --- a/test/CodeGen/Mips/selectcc.ll +++ b/test/CodeGen/Mips/selectcc.ll @@ -1,5 +1,7 @@ -; RUN: llc -march=mipsel < %s -; RUN: llc -march=mipsel -pre-RA-sched=source < %s | FileCheck %s --check-prefix=SOURCE-SCHED +; RUN: llc -march=mipsel -mcpu=mips32 < %s +; RUN: llc -march=mipsel -mcpu=mips32 -pre-RA-sched=source < %s | FileCheck %s --check-prefix=SOURCE-SCHED +; RUN: llc -march=mipsel -mcpu=mips32r2 < %s +; RUN: llc -march=mipsel -mcpu=mips32r2 -pre-RA-sched=source < %s | FileCheck %s --check-prefix=SOURCE-SCHED @gf0 = external global float @gf1 = external global float @@ -16,13 +18,11 @@ entry: ; SOURCE-SCHED: lw ; SOURCE-SCHED: lui ; SOURCE-SCHED: sw -; SOURCE-SCHED: addiu -; SOURCE-SCHED: addiu -; SOURCE-SCHED: c.olt.s -; SOURCE-SCHED: movt +; SOURCE-SCHED: lw +; SOURCE-SCHED: lwc1 ; SOURCE-SCHED: mtc1 +; SOURCE-SCHED: c.olt.s ; SOURCE-SCHED: jr - store float 0.000000e+00, float* @gf0, align 4 store float 1.000000e+00, float* @gf1, align 4 %cmp = fcmp olt float %a, %b diff --git a/test/CodeGen/Mips/tls-alias.ll b/test/CodeGen/Mips/tls-alias.ll index 80fbe87..b61f84e 100644 --- a/test/CodeGen/Mips/tls-alias.ll +++ b/test/CodeGen/Mips/tls-alias.ll @@ -1,7 +1,7 @@ ; RUN: llc -march=mipsel -relocation-model=pic -disable-mips-delay-filler < %s | FileCheck %s @foo = thread_local global i32 42 -@bar = hidden alias i32* @foo +@bar = hidden thread_local alias i32* @foo define i32* @zed() { ; CHECK-DAG: __tls_get_addr diff --git a/test/CodeGen/Mips/zeroreg.ll b/test/CodeGen/Mips/zeroreg.ll index e0e93e2..a1b6cb0 100644 --- a/test/CodeGen/Mips/zeroreg.ll +++ b/test/CodeGen/Mips/zeroreg.ll @@ -1,21 +1,109 @@ -; RUN: llc < %s -march=mipsel | FileCheck %s +; RUN: llc < %s -march=mipsel -mcpu=mips32 | FileCheck %s -check-prefix=ALL -check-prefix=32-CMOV +; RUN: llc < %s -march=mipsel -mcpu=mips32r2 | FileCheck %s -check-prefix=ALL -check-prefix=32-CMOV +; RUN: llc < %s -march=mipsel -mcpu=mips32r6 | FileCheck %s -check-prefix=ALL -check-prefix=32R6 +; RUN: llc < %s -march=mipsel -mcpu=mips4 | FileCheck %s -check-prefix=ALL -check-prefix=64-CMOV +; RUN: llc < %s -march=mipsel -mcpu=mips64 | FileCheck %s -check-prefix=ALL -check-prefix=64-CMOV +; RUN: llc < %s -march=mipsel -mcpu=mips64r2 | FileCheck %s -check-prefix=ALL -check-prefix=64-CMOV +; RUN: llc < %s -march=mipsel -mcpu=mips64r6 | FileCheck %s -check-prefix=ALL -check-prefix=64R6 @g1 = external global i32 -define i32 @foo0(i32 %s) nounwind readonly { +define i32 @sel_icmp_nez_i32_z0(i32 %s) nounwind readonly { entry: -; CHECK: movn ${{[0-9]+}}, $zero +; ALL-LABEL: sel_icmp_nez_i32_z0: + +; 32-CMOV: lw $2, 0(${{[0-9]+}}) +; 32-CMOV: movn $2, $zero, $4 + +; 32R6: lw $[[R0:[0-9]+]], 0(${{[0-9]+}}) +; 32R6: seleqz $2, $[[R0]], $4 + +; 64-CMOV: lw $2, 0(${{[0-9]+}}) +; 64-CMOV: movn $2, $zero, $4 + +; 64R6: lw $[[R0:[0-9]+]], 0(${{[0-9]+}}) +; 64R6: seleqz $2, $[[R0]], $4 + %tobool = icmp ne i32 %s, 0 %0 = load i32* @g1, align 4 %cond = select i1 %tobool, i32 0, i32 %0 ret i32 %cond } -define i32 @foo1(i32 %s) nounwind readonly { +define i32 @sel_icmp_nez_i32_z1(i32 %s) nounwind readonly { entry: -; CHECK: movz ${{[0-9]+}}, $zero +; ALL-LABEL: sel_icmp_nez_i32_z1: + +; 32-CMOV: lw $2, 0(${{[0-9]+}}) +; 32-CMOV: movz $2, $zero, $4 + +; 32R6: lw $[[R0:[0-9]+]], 0(${{[0-9]+}}) +; 32R6: selnez $2, $[[R0]], $4 + +; 64-CMOV: lw $2, 0(${{[0-9]+}}) +; 64-CMOV: movz $2, $zero, $4 + +; 64R6: lw $[[R0:[0-9]+]], 0(${{[0-9]+}}) +; 64R6: selnez $2, $[[R0]], $4 + %tobool = icmp ne i32 %s, 0 %0 = load i32* @g1, align 4 %cond = select i1 %tobool, i32 %0, i32 0 ret i32 %cond } + +@g2 = external global i64 + +define i64 @sel_icmp_nez_i64_z0(i64 %s) nounwind readonly { +entry: +; ALL-LABEL: sel_icmp_nez_i64_z0: + +; 32-CMOV-DAG: lw $[[R0:2]], 0(${{[0-9]+}}) +; 32-CMOV-DAG: lw $[[R1:3]], 4(${{[0-9]+}}) +; 32-CMOV-DAG: movn $[[R0]], $zero, $4 +; 32-CMOV-DAG: movn $[[R1]], $zero, $4 + +; 32R6-DAG: lw $[[R0:[0-9]+]], 0(${{[0-9]+}}) +; 32R6-DAG: lw $[[R1:[0-9]+]], 4(${{[0-9]+}}) +; 32R6-DAG: or $[[CC:[0-9]+]], $4, $5 +; 32R6-DAG: seleqz $2, $[[R0]], $[[CC]] +; 32R6-DAG: seleqz $3, $[[R1]], $[[CC]] + +; 64-CMOV: ld $2, 0(${{[0-9]+}}) +; 64-CMOV: movn $2, $zero, $4 + +; 64R6: ld $[[R0:[0-9]+]], 0(${{[0-9]+}}) +; 64R6: seleqz $2, $[[R0]], $4 + + %tobool = icmp ne i64 %s, 0 + %0 = load i64* @g2, align 4 + %cond = select i1 %tobool, i64 0, i64 %0 + ret i64 %cond +} + +define i64 @sel_icmp_nez_i64_z1(i64 %s) nounwind readonly { +entry: +; ALL-LABEL: sel_icmp_nez_i64_z1: + +; 32-CMOV-DAG: lw $[[R0:2]], 0(${{[0-9]+}}) +; 32-CMOV-DAG: lw $[[R1:3]], 4(${{[0-9]+}}) +; 32-CMOV-DAG: movz $[[R0]], $zero, $4 +; 32-CMOV-DAG: movz $[[R1]], $zero, $4 + +; 32R6-DAG: lw $[[R0:[0-9]+]], 0(${{[0-9]+}}) +; 32R6-DAG: lw $[[R1:[0-9]+]], 4(${{[0-9]+}}) +; 32R6-DAG: or $[[CC:[0-9]+]], $4, $5 +; 32R6-DAG: selnez $2, $[[R0]], $[[CC]] +; 32R6-DAG: selnez $3, $[[R1]], $[[CC]] + +; 64-CMOV: ld $2, 0(${{[0-9]+}}) +; 64-CMOV: movz $2, $zero, $4 + +; 64R6: ld $[[R0:[0-9]+]], 0(${{[0-9]+}}) +; 64R6: selnez $2, $[[R0]], $4 + + %tobool = icmp ne i64 %s, 0 + %0 = load i64* @g2, align 4 + %cond = select i1 %tobool, i64 %0, i64 0 + ret i64 %cond +} |