Added support for FP conditional move instructions and fixed bugs in handling of FP comparisons.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@128650 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/CodeGen/Mips/2008-07-23-fpcmp.ll b/test/CodeGen/Mips/2008-07-23-fpcmp.ll
index ca837ff..519e4b9 100644
--- a/test/CodeGen/Mips/2008-07-23-fpcmp.ll
+++ b/test/CodeGen/Mips/2008-07-23-fpcmp.ll
@@ -2,6 +2,10 @@
 ; RUN: grep {c\\..*\\.s} %t | count 3
 ; RUN: grep {bc1\[tf\]} %t | count 3
 
+; FIXME: Disabled because branch instructions are generated where
+; conditional move instructions are expected.
+; REQUIRES: disabled
+
 target datalayout = "e-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64"
 target triple = "mipsallegrexel-unknown-psp-elf"
 
diff --git a/test/CodeGen/Mips/2008-07-29-icmp.ll b/test/CodeGen/Mips/2008-07-29-icmp.ll
index 52a4b08..e85a749 100644
--- a/test/CodeGen/Mips/2008-07-29-icmp.ll
+++ b/test/CodeGen/Mips/2008-07-29-icmp.ll
@@ -1,5 +1,9 @@
 ; RUN: llc < %s -march=mips | grep {b\[ne\]\[eq\]} | count 1
 
+; FIXME: Disabled because branch instructions are generated where
+; conditional move instructions are expected.
+; REQUIRES: disabled
+
 target datalayout = "e-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64"
 target triple = "mipsallegrexel-unknown-psp-elf"
 
diff --git a/test/CodeGen/Mips/2010-07-20-Select.ll b/test/CodeGen/Mips/2010-07-20-Select.ll
index 891b5d9..a277149 100644
--- a/test/CodeGen/Mips/2010-07-20-Select.ll
+++ b/test/CodeGen/Mips/2010-07-20-Select.ll
@@ -9,12 +9,12 @@
   volatile store i32 0, i32* %c, align 4
   %0 = volatile load i32* %a, align 4             ; <i32> [#uses=1]
   %1 = icmp eq i32 %0, 0                          ; <i1> [#uses=1]
-; CHECK: addiu $3, $zero, 0
+; CHECK: addiu $4, $zero, 0
   %iftmp.0.0 = select i1 %1, i32 3, i32 0         ; <i32> [#uses=1]
   %2 = volatile load i32* %c, align 4             ; <i32> [#uses=1]
   %3 = icmp eq i32 %2, 0                          ; <i1> [#uses=1]
-; CHECK: addiu $3, $zero, 3
-; CHECK: addu $2, $5, $3
+; CHECK: addiu $4, $zero, 3
+; CHECK: addu $2, $3, $4
   %iftmp.2.0 = select i1 %3, i32 0, i32 5         ; <i32> [#uses=1]
   %4 = add nsw i32 %iftmp.2.0, %iftmp.0.0         ; <i32> [#uses=1]
   ret i32 %4
diff --git a/test/CodeGen/Mips/fpbr.ll b/test/CodeGen/Mips/fpbr.ll
new file mode 100644
index 0000000..0a6478b
--- /dev/null
+++ b/test/CodeGen/Mips/fpbr.ll
@@ -0,0 +1,119 @@
+; RUN: llc  < %s -march=mipsel | FileCheck %s
+
+define void @func0(float %f2, float %f3) nounwind {
+entry:
+; CHECK: c.eq.s
+; CHECK: bc1f
+  %cmp = fcmp oeq float %f2, %f3
+  br i1 %cmp, label %if.then, label %if.else
+
+if.then:                                          ; preds = %entry
+  tail call void (...)* @g0() nounwind
+  br label %if.end
+
+if.else:                                          ; preds = %entry
+  tail call void (...)* @g1() nounwind
+  br label %if.end
+
+if.end:                                           ; preds = %if.else, %if.then
+  ret void
+}
+
+declare void @g0(...)
+
+declare void @g1(...)
+
+define void @func1(float %f2, float %f3) nounwind {
+entry:
+; CHECK: c.olt.s
+; CHECK: bc1f
+  %cmp = fcmp olt float %f2, %f3
+  br i1 %cmp, label %if.then, label %if.else
+
+if.then:                                          ; preds = %entry
+  tail call void (...)* @g0() nounwind
+  br label %if.end
+
+if.else:                                          ; preds = %entry
+  tail call void (...)* @g1() nounwind
+  br label %if.end
+
+if.end:                                           ; preds = %if.else, %if.then
+  ret void
+}
+
+define void @func2(float %f2, float %f3) nounwind {
+entry:
+; CHECK: c.ole.s
+; CHECK: bc1f
+  %cmp = fcmp ugt float %f2, %f3
+  br i1 %cmp, label %if.else, label %if.then
+
+if.then:                                          ; preds = %entry
+  tail call void (...)* @g0() nounwind
+  br label %if.end
+
+if.else:                                          ; preds = %entry
+  tail call void (...)* @g1() nounwind
+  br label %if.end
+
+if.end:                                           ; preds = %if.else, %if.then
+  ret void
+}
+
+define void @func3(double %f2, double %f3) nounwind {
+entry:
+; CHECK: c.eq.d
+; CHECK: bc1f
+  %cmp = fcmp oeq double %f2, %f3
+  br i1 %cmp, label %if.then, label %if.else
+
+if.then:                                          ; preds = %entry
+  tail call void (...)* @g0() nounwind
+  br label %if.end
+
+if.else:                                          ; preds = %entry
+  tail call void (...)* @g1() nounwind
+  br label %if.end
+
+if.end:                                           ; preds = %if.else, %if.then
+  ret void
+}
+
+define void @func4(double %f2, double %f3) nounwind {
+entry:
+; CHECK: c.olt.d
+; CHECK: bc1f
+  %cmp = fcmp olt double %f2, %f3
+  br i1 %cmp, label %if.then, label %if.else
+
+if.then:                                          ; preds = %entry
+  tail call void (...)* @g0() nounwind
+  br label %if.end
+
+if.else:                                          ; preds = %entry
+  tail call void (...)* @g1() nounwind
+  br label %if.end
+
+if.end:                                           ; preds = %if.else, %if.then
+  ret void
+}
+
+define void @func5(double %f2, double %f3) nounwind {
+entry:
+; CHECK: c.ole.d
+; CHECK: bc1f
+  %cmp = fcmp ugt double %f2, %f3
+  br i1 %cmp, label %if.else, label %if.then
+
+if.then:                                          ; preds = %entry
+  tail call void (...)* @g0() nounwind
+  br label %if.end
+
+if.else:                                          ; preds = %entry
+  tail call void (...)* @g1() nounwind
+  br label %if.end
+
+if.end:                                           ; preds = %if.else, %if.then
+  ret void
+}
diff --git a/test/CodeGen/Mips/fpcmp.ll b/test/CodeGen/Mips/fpcmp.ll
new file mode 100644
index 0000000..51d55f0
--- /dev/null
+++ b/test/CodeGen/Mips/fpcmp.ll
@@ -0,0 +1,23 @@
+; RUN: llc  < %s -march=mipsel -mcpu=4ke | FileCheck %s -check-prefix=CHECK-MIPS32R2
+; RUN: llc  < %s -march=mipsel | FileCheck %s -check-prefix=CHECK-MIPS1
+
+@g1 = external global i32
+
+define i32 @f(float %f0, float %f1) nounwind {
+entry:
+; CHECK-MIPS32R2: c.olt.s
+; CHECK-MIPS32R2: movt
+; CHECK-MIPS32R2: c.olt.s
+; CHECK-MIPS32R2: movt
+; CHECK-MIPS1: c.olt.s
+; CHECK-MIPS1: bc1f
+; CHECK-MIPS1: c.olt.s
+; CHECK-MIPS1: bc1f
+  %cmp = fcmp olt float %f0, %f1
+  %conv = zext i1 %cmp to i32
+  %tmp2 = load i32* @g1, align 4
+  %add = add nsw i32 %tmp2, %conv
+  store i32 %add, i32* @g1, align 4
+  %cond = select i1 %cmp, i32 10, i32 20
+  ret i32 %cond
+}
diff --git a/test/CodeGen/Mips/select.ll b/test/CodeGen/Mips/select.ll
new file mode 100644
index 0000000..c83fa3e
--- /dev/null
+++ b/test/CodeGen/Mips/select.ll
@@ -0,0 +1,196 @@
+; RUN: llc  < %s -march=mipsel -mcpu=4ke | FileCheck %s -check-prefix=CHECK-MIPS32R2
+; RUN: llc  < %s -march=mipsel | FileCheck %s -check-prefix=CHECK-MIPS1
+
+@d2 = external global double
+@d3 = external global double
+
+define i32 @sel1(i32 %s, i32 %f0, i32 %f1) nounwind readnone {
+entry:
+; CHECK-MIPS32R2: movn
+; CHECK-MIPS1: beq
+  %tobool = icmp ne i32 %s, 0
+  %cond = select i1 %tobool, i32 %f1, i32 %f0
+  ret i32 %cond
+}
+
+define float @sel2(i32 %s, float %f0, float %f1) nounwind readnone {
+entry:
+; CHECK-MIPS32R2: movn.s
+; CHECK-MIPS1: beq
+  %tobool = icmp ne i32 %s, 0
+  %cond = select i1 %tobool, float %f0, float %f1
+  ret float %cond
+}
+
+define double @sel2_1(i32 %s, double %f0, double %f1) nounwind readnone {
+entry:
+; CHECK-MIPS32R2: movn.d
+; CHECK-MIPS1: beq
+  %tobool = icmp ne i32 %s, 0
+  %cond = select i1 %tobool, double %f0, double %f1
+  ret double %cond
+}
+
+define float @sel3(float %f0, float %f1, float %f2, float %f3) nounwind readnone {
+entry:
+; CHECK-MIPS32R2: c.eq.s
+; CHECK-MIPS32R2: movt.s
+; CHECK-MIPS1: c.eq.s
+; CHECK-MIPS1: bc1f
+  %cmp = fcmp oeq float %f2, %f3
+  %cond = select i1 %cmp, float %f0, float %f1
+  ret float %cond
+}
+
+define float @sel4(float %f0, float %f1, float %f2, float %f3) nounwind readnone {
+entry:
+; CHECK-MIPS32R2: c.olt.s
+; CHECK-MIPS32R2: movt.s
+; CHECK-MIPS1: c.olt.s
+; CHECK-MIPS1: bc1f
+  %cmp = fcmp olt float %f2, %f3
+  %cond = select i1 %cmp, float %f0, float %f1
+  ret float %cond
+}
+
+define float @sel5(float %f0, float %f1, float %f2, float %f3) nounwind readnone {
+entry:
+; CHECK-MIPS32R2: c.ule.s
+; CHECK-MIPS32R2: movf.s
+; CHECK-MIPS1: c.ule.s
+; CHECK-MIPS1: bc1t
+  %cmp = fcmp ogt float %f2, %f3
+  %cond = select i1 %cmp, float %f0, float %f1
+  ret float %cond
+}
+
+define double @sel5_1(double %f0, double %f1, float %f2, float %f3) nounwind readnone {
+entry:
+; CHECK-MIPS32R2: c.ule.s
+; CHECK-MIPS32R2: movf.d
+; CHECK-MIPS1: c.ule.s
+; CHECK-MIPS1: bc1t
+  %cmp = fcmp ogt float %f2, %f3
+  %cond = select i1 %cmp, double %f0, double %f1
+  ret double %cond
+}
+
+define double @sel6(double %f0, double %f1, double %f2, double %f3) nounwind readnone {
+entry:
+; CHECK-MIPS32R2: c.eq.d
+; CHECK-MIPS32R2: movt.d
+; CHECK-MIPS1: c.eq.d
+; CHECK-MIPS1: bc1f
+  %cmp = fcmp oeq double %f2, %f3
+  %cond = select i1 %cmp, double %f0, double %f1
+  ret double %cond
+}
+
+define double @sel7(double %f0, double %f1, double %f2, double %f3) nounwind readnone {
+entry:
+; CHECK-MIPS32R2: c.olt.d
+; CHECK-MIPS32R2: movt.d
+; CHECK-MIPS1: c.olt.d
+; CHECK-MIPS1: bc1f
+  %cmp = fcmp olt double %f2, %f3
+  %cond = select i1 %cmp, double %f0, double %f1
+  ret double %cond
+}
+
+define double @sel8(double %f0, double %f1, double %f2, double %f3) nounwind readnone {
+entry:
+; CHECK-MIPS32R2: c.ule.d
+; CHECK-MIPS32R2: movf.d
+; CHECK-MIPS1: c.ule.d
+; CHECK-MIPS1: bc1t
+  %cmp = fcmp ogt double %f2, %f3
+  %cond = select i1 %cmp, double %f0, double %f1
+  ret double %cond
+}
+
+define float @sel8_1(float %f0, float %f1, double %f2, double %f3) nounwind readnone {
+entry:
+; CHECK-MIPS32R2: c.ule.d
+; CHECK-MIPS32R2: movf.s
+; CHECK-MIPS1: c.ule.d
+; CHECK-MIPS1: bc1t
+  %cmp = fcmp ogt double %f2, %f3
+  %cond = select i1 %cmp, float %f0, float %f1
+  ret float %cond
+}
+
+define i32 @sel9(i32 %f0, i32 %f1, float %f2, float %f3) nounwind readnone {
+entry:
+; CHECK-MIPS32R2: c.eq.s
+; CHECK-MIPS32R2: movt
+; CHECK-MIPS1: c.eq.s
+; CHECK-MIPS1: bc1f
+  %cmp = fcmp oeq float %f2, %f3
+  %cond = select i1 %cmp, i32 %f0, i32 %f1
+  ret i32 %cond
+}
+
+define i32 @sel10(i32 %f0, i32 %f1, float %f2, float %f3) nounwind readnone {
+entry:
+; CHECK-MIPS32R2: c.olt.s
+; CHECK-MIPS32R2: movt
+; CHECK-MIPS1: c.olt.s
+; CHECK-MIPS1: bc1f
+  %cmp = fcmp olt float %f2, %f3
+  %cond = select i1 %cmp, i32 %f0, i32 %f1
+  ret i32 %cond
+}
+
+define i32 @sel11(i32 %f0, i32 %f1, float %f2, float %f3) nounwind readnone {
+entry:
+; CHECK-MIPS32R2: c.ule.s
+; CHECK-MIPS32R2: movf
+; CHECK-MIPS1: c.ule.s
+; CHECK-MIPS1: bc1t
+  %cmp = fcmp ogt float %f2, %f3
+  %cond = select i1 %cmp, i32 %f0, i32 %f1
+  ret i32 %cond
+}
+
+define i32 @sel12(i32 %f0, i32 %f1) nounwind readonly {
+entry:
+; CHECK-MIPS32R2: c.eq.d
+; CHECK-MIPS32R2: movt
+; CHECK-MIPS1: c.eq.d
+; CHECK-MIPS1: bc1f
+  %tmp = load double* @d2, align 8, !tbaa !0
+  %tmp1 = load double* @d3, align 8, !tbaa !0
+  %cmp = fcmp oeq double %tmp, %tmp1
+  %cond = select i1 %cmp, i32 %f0, i32 %f1
+  ret i32 %cond
+}
+
+define i32 @sel13(i32 %f0, i32 %f1) nounwind readonly {
+entry:
+; CHECK-MIPS32R2: c.olt.d
+; CHECK-MIPS32R2: movt
+; CHECK-MIPS1: c.olt.d
+; CHECK-MIPS1: bc1f
+  %tmp = load double* @d2, align 8, !tbaa !0
+  %tmp1 = load double* @d3, align 8, !tbaa !0
+  %cmp = fcmp olt double %tmp, %tmp1
+  %cond = select i1 %cmp, i32 %f0, i32 %f1
+  ret i32 %cond
+}
+
+define i32 @sel14(i32 %f0, i32 %f1) nounwind readonly {
+entry:
+; CHECK-MIPS32R2: c.ule.d
+; CHECK-MIPS32R2: movf
+; CHECK-MIPS1: c.ule.d
+; CHECK-MIPS1: bc1t
+  %tmp = load double* @d2, align 8, !tbaa !0
+  %tmp1 = load double* @d3, align 8, !tbaa !0
+  %cmp = fcmp ogt double %tmp, %tmp1
+  %cond = select i1 %cmp, i32 %f0, i32 %f1
+  ret i32 %cond
+}
+
+!0 = metadata !{metadata !"double", metadata !1}
+!1 = metadata !{metadata !"omnipotent char", metadata !2}
+!2 = metadata !{metadata !"Simple C/C++ TBAA", null}