WebAssembly: implement comparison.

Some of the FP comparisons (ueq, one, ult, ule, ugt, uge) are currently broken, I'll fix them in a follow-up.

Reviewers: sunfish

Subscribers: llvm-commits, jfb

Differential Revision: http://reviews.llvm.org/D11924

llvm-svn: 244665
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
index f73500d..bfa442b 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
@@ -110,9 +110,14 @@
 
   // FIXME: many setOperationAction are missing...
 
-  // Don't expand the following types to constant pools.
-  setOperationAction(ISD::ConstantFP, MVT::f32, Legal);
-  setOperationAction(ISD::ConstantFP, MVT::f64, Legal);
+  for (auto T : {MVT::f32, MVT::f64}) {
+    // Don't expand the floating-point types to constant pools.
+    setOperationAction(ISD::ConstantFP, T, Legal);
+    // Expand floating-point comparisons.
+    for (auto CC : {ISD::SETO, ISD::SETUO, ISD::SETUEQ, ISD::SETONE,
+                    ISD::SETULT, ISD::SETULE, ISD::SETUGT, ISD::SETUGE})
+      setCondCodeAction(CC, T, Expand);
+  }
 }
 
 MVT WebAssemblyTargetLowering::getScalarShiftAmountTy(const DataLayout &DL,
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrFloat.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrFloat.td
index b6c09be..16e5c8e 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrFloat.td
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrFloat.td
@@ -28,15 +28,12 @@
  * defm NEARESTINT : UnaryFP<fnearbyint>;
  */
 
-/*
- * TODO(jfb): Add the following for 32-bit and 64-bit.
- *
- * float32.eq: compare equal
- * float32.lt: less than
- * float32.le: less than or equal
- * float32.gt: greater than
- * float32.ge: greater than or equal
- */
+defm EQ : ComparisonFP<SETOEQ>;
+defm NE : ComparisonFP<SETUNE>;
+defm LT : ComparisonFP<SETOLT>;
+defm LE : ComparisonFP<SETOLE>;
+defm GT : ComparisonFP<SETOGT>;
+defm GE : ComparisonFP<SETOGE>;
 
 defm SQRT : UnaryFP<fsqrt>;
 
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrFormats.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrFormats.td
index 513c36f..f4d16d3 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrFormats.td
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrFormats.td
@@ -53,3 +53,15 @@
   def _F64 : I<(outs Float64:$dst), (ins Float64:$lhs, Float64:$rhs),
                [(set Float64:$dst, (node Float64:$lhs, Float64:$rhs))]>;
 }
+multiclass ComparisonInt<CondCode cond> {
+  def _I32 : I<(outs Int32:$dst), (ins Int32:$lhs, Int32:$rhs),
+               [(set Int32:$dst, (setcc Int32:$lhs, Int32:$rhs, cond))]>;
+  def _I64 : I<(outs Int32:$dst), (ins Int64:$lhs, Int64:$rhs),
+               [(set Int32:$dst, (setcc Int64:$lhs, Int64:$rhs, cond))]>;
+}
+multiclass ComparisonFP<CondCode cond> {
+  def _F32 : I<(outs Int32:$dst), (ins Float32:$lhs, Float32:$rhs),
+               [(set Int32:$dst, (setcc Float32:$lhs, Float32:$rhs, cond))]>;
+  def _F64 : I<(outs Int32:$dst), (ins Float64:$lhs, Float64:$rhs),
+               [(set Int32:$dst, (setcc Float64:$lhs, Float64:$rhs, cond))]>;
+}
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrInteger.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrInteger.td
index 5f60fe8..cf2c6a3 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrInteger.td
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrInteger.td
@@ -26,19 +26,16 @@
 defm SHR : BinaryInt<srl>;
 defm SAR : BinaryInt<sra>;
 
-/*
- * TODO(jfb): Add the following for 32-bit and 64-bit.
- *
- * int32.eq: signed-less compare equal
- * int32.slt: signed less than
- * int32.sle: signed less than or equal
- * int32.ult: unsigned less than
- * int32.ule: unsigned less than or equal
- * int32.sgt: signed greater than
- * int32.sge: signed greater than or equal
- * int32.ugt: unsigned greater than
- * int32.uge: unsigned greater than or equal
- */
+defm EQ : ComparisonInt<SETEQ>;
+defm NE : ComparisonInt<SETNE>;
+defm SLT : ComparisonInt<SETLT>;
+defm SLE : ComparisonInt<SETLE>;
+defm ULT : ComparisonInt<SETULT>;
+defm ULE : ComparisonInt<SETULE>;
+defm SGT : ComparisonInt<SETGT>;
+defm SGE : ComparisonInt<SETGE>;
+defm UGT : ComparisonInt<SETUGT>;
+defm UGE : ComparisonInt<SETUGE>;
 
 defm CLZ : UnaryInt<ctlz>;
 defm CTZ : UnaryInt<cttz>;