From bc6579999067f74b1f18f5bc1a139ae195dec006 Mon Sep 17 00:00:00 2001
From: Dan Gohman <sunfish@mozilla.com>
Date: Sat, 13 Dec 2014 12:20:35 -0800
Subject: [PATCH 1/3] Use SIMD_int32x4_splat instead of a plain constructor

---
 lib/Target/JSBackend/JSBackend.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lib/Target/JSBackend/JSBackend.cpp b/lib/Target/JSBackend/JSBackend.cpp
index 8f924007a28..f76319c00b9 100644
--- a/lib/Target/JSBackend/JSBackend.cpp
+++ b/lib/Target/JSBackend/JSBackend.cpp
@@ -1391,10 +1391,10 @@ void JSWriter::generateFCmpExpression(const FCmpInst *I, raw_string_ostream& Cod
   bool Invert = false;
   switch (cast<FCmpInst>(I)->getPredicate()) {
     case ICmpInst::FCMP_FALSE:
-      Code << "SIMD_int32x4(0, 0, 0, 0)";
+      Code << "SIMD_int32x4_splat(0)";
       return;
     case ICmpInst::FCMP_TRUE:
-      Code << "SIMD_int32x4(-1, -1, -1, -1)";
+      Code << "SIMD_int32x4_splat(-1)";
       return;
     case ICmpInst::FCMP_ONE:
       Code << "SIMD_float32x4_and(SIMD_float32x4_and("

From 048535cc88bf97ad0a8cc1f459e737009404d52b Mon Sep 17 00:00:00 2001
From: Dan Gohman <sunfish@mozilla.com>
Date: Sat, 13 Dec 2014 12:21:22 -0800
Subject: [PATCH 2/3] Fix SIMD codegen for FCmp expressions

FCMP_UEQ, FCMP_ORD, and FCMP_UNO are all handled specially and are not
intended to fall through to the generic code.
---
 lib/Target/JSBackend/JSBackend.cpp |  6 ++---
 test/CodeGen/JS/simd-fcmp.ll       | 37 ++++++++++++++++++++++++++++++
 2 files changed, 40 insertions(+), 3 deletions(-)
 create mode 100644 test/CodeGen/JS/simd-fcmp.ll

diff --git a/lib/Target/JSBackend/JSBackend.cpp b/lib/Target/JSBackend/JSBackend.cpp
index f76319c00b9..4b8da31df04 100644
--- a/lib/Target/JSBackend/JSBackend.cpp
+++ b/lib/Target/JSBackend/JSBackend.cpp
@@ -1413,18 +1413,18 @@ void JSWriter::generateFCmpExpression(const FCmpInst *I, raw_string_ostream& Cod
                                          << getValueAsStr(I->getOperand(1)) << ")), " <<
               "SIMD_float32x4_equal(" << getValueAsStr(I->getOperand(0)) << ", "
                                       << getValueAsStr(I->getOperand(1)) << "))";
-      break;
+      return;
     case FCmpInst::FCMP_ORD:
       Code << "SIMD_float32x4_and("
               "SIMD_float32x4_equal(" << getValueAsStr(I->getOperand(0)) << ", " << getValueAsStr(I->getOperand(0)) << "), " <<
               "SIMD_float32x4_equal(" << getValueAsStr(I->getOperand(1)) << ", " << getValueAsStr(I->getOperand(1)) << "))";
-      break;
+      return;
 
     case FCmpInst::FCMP_UNO:
       Code << "SIMD_float32x4_or("
               "SIMD_float32x4_notEqual(" << getValueAsStr(I->getOperand(0)) << ", " << getValueAsStr(I->getOperand(0)) << "), " <<
               "SIMD_float32x4_notEqual(" << getValueAsStr(I->getOperand(1)) << ", " << getValueAsStr(I->getOperand(1)) << "))";
-      break;
+      return;
 
     case ICmpInst::FCMP_OEQ:  Name = "equal"; break;
     case ICmpInst::FCMP_OGT:  Name = "greaterThan"; break;
diff --git a/test/CodeGen/JS/simd-fcmp.ll b/test/CodeGen/JS/simd-fcmp.ll
new file mode 100644
index 00000000000..eab6748ee75
--- /dev/null
+++ b/test/CodeGen/JS/simd-fcmp.ll
@@ -0,0 +1,37 @@
+; RUN: llc < %s | FileCheck %s
+
+target datalayout = "e-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-p:32:32:32-v128:32:128-n32-S128"
+target triple = "asmjs-unknown-emscripten"
+
+; CHECK: function _test_ueq($a,$b) {
+; CHECK: $a = SIMD_float32x4($a);
+; CHECK: $b = SIMD_float32x4($b);
+; CHECK: SIMD_float32x4_or(SIMD_float32x4_or(SIMD_float32x4_notEqual($a, $a), SIMD_float32x4_notEqual($b, $b)), SIMD_float32x4_equal($a, $b));
+; CHECK: return (SIMD_int32x4($c));
+; CHECK:}
+define <4 x i1> @test_ueq(<4 x float> %a, <4 x float> %b) {
+    %c = fcmp ueq <4 x float> %a, %b
+    ret <4 x i1> %c
+}
+
+; CHECK: function _test_ord($a,$b) {
+; CHECK: $a = SIMD_float32x4($a);
+; CHECK: $b = SIMD_float32x4($b);
+; CHECK: SIMD_float32x4_or(SIMD_float32x4_or(SIMD_float32x4_notEqual($a, $a), SIMD_float32x4_notEqual($b, $b)), SIMD_float32x4_equal($a, $b));
+; CHECK: return (SIMD_int32x4($c));
+; CHECK:}
+define <4 x i1> @test_ord(<4 x float> %a, <4 x float> %b) {
+    %c = fcmp ueq <4 x float> %a, %b
+    ret <4 x i1> %c
+}
+
+; CHECK:function _test_uno($a,$b) {
+; CHECK: $a = SIMD_float32x4($a);
+; CHECK: $b = SIMD_float32x4($b);
+; CHECK: SIMD_float32x4_or(SIMD_float32x4_or(SIMD_float32x4_notEqual($a, $a), SIMD_float32x4_notEqual($b, $b)), SIMD_float32x4_equal($a, $b));
+; CHECK: return (SIMD_int32x4($c));
+; CHECK:}
+define <4 x i1> @test_uno(<4 x float> %a, <4 x float> %b) {
+    %c = fcmp ueq <4 x float> %a, %b
+    ret <4 x i1> %c
+}

From a5e8942da586a7ef0ed02361b77a3010f16428cf Mon Sep 17 00:00:00 2001
From: Alon Zakai <alonzakai@gmail.com>
Date: Tue, 16 Dec 2014 11:04:14 -0800
Subject: [PATCH 3/3] 1.28.1

---
 emscripten-version.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/emscripten-version.txt b/emscripten-version.txt
index b1a41036cde..6a10ff7aa23 100644
--- a/emscripten-version.txt
+++ b/emscripten-version.txt
@@ -1,2 +1,2 @@
-1.28.0
+1.28.1