From c6a4f5e819217e1e12c458aed8e7b122e23a3a58 Mon Sep 17 00:00:00 2001 From: Stephen Hines Date: Mon, 21 Jul 2014 00:45:20 -0700 Subject: Update LLVM for rebase to r212749. Includes a cherry-pick of: r212948 - fixes a small issue with atomic calls Change-Id: Ib97bd980b59f18142a69506400911a6009d9df18 --- test/CodeGen/Mips/2008-08-01-AsmInline.ll | 2 +- test/CodeGen/Mips/2013-11-18-fp64-const0.ll | 2 +- test/CodeGen/Mips/Fast-ISel/loadstore2.ll | 83 +++ test/CodeGen/Mips/Fast-ISel/simplestorefp1.ll | 38 ++ test/CodeGen/Mips/abiflags-xx.ll | 6 + test/CodeGen/Mips/abiflags32.ll | 12 + test/CodeGen/Mips/analyzebranch.ll | 35 +- test/CodeGen/Mips/atomic.ll | 626 +++++++++--------- test/CodeGen/Mips/atomicops.ll | 3 +- test/CodeGen/Mips/buildpairextractelementf64.ll | 4 +- test/CodeGen/Mips/cconv/callee-saved-fpxx.ll | 58 ++ test/CodeGen/Mips/cconv/callee-saved-fpxx1.ll | 24 + test/CodeGen/Mips/cmov.ll | 614 +++++++++++++++--- test/CodeGen/Mips/countleading.ll | 90 +++ test/CodeGen/Mips/divrem.ll | 363 ++++++++++- test/CodeGen/Mips/dsp-r1.ll | 2 +- test/CodeGen/Mips/eh-return32.ll | 14 +- test/CodeGen/Mips/eh-return64.ll | 17 +- test/CodeGen/Mips/ehframe-indirect.ll | 34 + test/CodeGen/Mips/fcmp.ll | 783 +++++++++++++++++++++++ test/CodeGen/Mips/fcopysign.ll | 2 +- test/CodeGen/Mips/fmadd1.ll | 324 +++++++++- test/CodeGen/Mips/fp-indexed-ls.ll | 192 +++++- test/CodeGen/Mips/fpbr.ll | 93 ++- test/CodeGen/Mips/inlineasm-cnstrnt-reg.ll | 3 +- test/CodeGen/Mips/lit.local.cfg | 3 +- test/CodeGen/Mips/llvm-ir/call.ll | 166 +++++ test/CodeGen/Mips/llvm-ir/indirectbr.ll | 34 + test/CodeGen/Mips/llvm-ir/ret.ll | 205 ++++++ test/CodeGen/Mips/longbranch.ll | 34 + test/CodeGen/Mips/madd-msub.ll | 241 ++++++- test/CodeGen/Mips/mips16ex.ll | 4 +- test/CodeGen/Mips/mips64-f128.ll | 358 ++++++----- test/CodeGen/Mips/mips64-fp-indexed-ls.ll | 110 ---- test/CodeGen/Mips/mips64countleading.ll | 24 - test/CodeGen/Mips/mips64instrs.ll | 126 ++-- test/CodeGen/Mips/mips64muldiv.ll | 57 +- test/CodeGen/Mips/mno-ldc1-sdc1.ll | 274 ++++++-- test/CodeGen/Mips/msa/special.ll | 4 + test/CodeGen/Mips/no-odd-spreg.ll | 54 ++ test/CodeGen/Mips/null-streamer.ll | 7 + test/CodeGen/Mips/prevent-hoisting.ll | 144 +++++ test/CodeGen/Mips/select.ll | 800 ++++++++++++++++++++++-- test/CodeGen/Mips/selectcc.ll | 14 +- test/CodeGen/Mips/tls-alias.ll | 2 +- test/CodeGen/Mips/zeroreg.ll | 98 ++- 46 files changed, 5166 insertions(+), 1017 deletions(-) create mode 100644 test/CodeGen/Mips/Fast-ISel/loadstore2.ll create mode 100644 test/CodeGen/Mips/Fast-ISel/simplestorefp1.ll create mode 100644 test/CodeGen/Mips/abiflags-xx.ll create mode 100644 test/CodeGen/Mips/abiflags32.ll create mode 100644 test/CodeGen/Mips/cconv/callee-saved-fpxx.ll create mode 100644 test/CodeGen/Mips/cconv/callee-saved-fpxx1.ll create mode 100644 test/CodeGen/Mips/countleading.ll create mode 100644 test/CodeGen/Mips/ehframe-indirect.ll create mode 100644 test/CodeGen/Mips/fcmp.ll create mode 100644 test/CodeGen/Mips/llvm-ir/call.ll create mode 100644 test/CodeGen/Mips/llvm-ir/indirectbr.ll create mode 100644 test/CodeGen/Mips/llvm-ir/ret.ll delete mode 100644 test/CodeGen/Mips/mips64-fp-indexed-ls.ll delete mode 100644 test/CodeGen/Mips/mips64countleading.ll create mode 100644 test/CodeGen/Mips/no-odd-spreg.ll create mode 100644 test/CodeGen/Mips/null-streamer.ll create mode 100644 test/CodeGen/Mips/prevent-hoisting.ll (limited to 'test/CodeGen/Mips') 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 # %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 # -%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 + +;