[llvm] r244665 - WebAssembly: implement comparison.

JF Bastien via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 11 14:02:46 PDT 2015


Author: jfb
Date: Tue Aug 11 16:02:46 2015
New Revision: 244665

URL: http://llvm.org/viewvc/llvm-project?rev=244665&view=rev
Log:
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

Added:
    llvm/trunk/test/CodeGen/WebAssembly/comparisons_f32.ll
    llvm/trunk/test/CodeGen/WebAssembly/comparisons_f64.ll
    llvm/trunk/test/CodeGen/WebAssembly/comparisons_i32.ll
    llvm/trunk/test/CodeGen/WebAssembly/comparisons_i64.ll
Modified:
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrFloat.td
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrFormats.td
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrInteger.td

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp?rev=244665&r1=244664&r2=244665&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp Tue Aug 11 16:02:46 2015
@@ -110,9 +110,14 @@ WebAssemblyTargetLowering::WebAssemblyTa
 
   // 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,

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrFloat.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrFloat.td?rev=244665&r1=244664&r2=244665&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrFloat.td (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrFloat.td Tue Aug 11 16:02:46 2015
@@ -28,15 +28,12 @@ defm COPYSIGN : BinaryFP<fcopysign>;
  * 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>;
 

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrFormats.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrFormats.td?rev=244665&r1=244664&r2=244665&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrFormats.td (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrFormats.td Tue Aug 11 16:02:46 2015
@@ -53,3 +53,15 @@ multiclass BinaryFP<SDNode node> {
   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))]>;
+}

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrInteger.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrInteger.td?rev=244665&r1=244664&r2=244665&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrInteger.td (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrInteger.td Tue Aug 11 16:02:46 2015
@@ -26,19 +26,16 @@ defm SHL : BinaryInt<shl>;
 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>;

Added: llvm/trunk/test/CodeGen/WebAssembly/comparisons_f32.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/WebAssembly/comparisons_f32.ll?rev=244665&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/WebAssembly/comparisons_f32.ll (added)
+++ llvm/trunk/test/CodeGen/WebAssembly/comparisons_f32.ll Tue Aug 11 16:02:46 2015
@@ -0,0 +1,65 @@
+; RUN: llc < %s -asm-verbose=false | FileCheck %s
+
+; Test that basic 32-bit floating-point comparison operations assemble as
+; expected.
+
+target datalayout = "e-p:32:32-i64:64-v128:8:128-n32:64-S128"
+target triple = "wasm32-unknown-unknown"
+
+; FIXME: add ord and uno tests.
+
+; CHECK-LABEL: oeq_f32:
+; CHECK-NEXT: (setlocal @0 (argument 1))
+; CHECK-NEXT: (setlocal @1 (argument 0))
+; CHECK-NEXT: (setlocal @2 (eq @1 @0))
+; CHECK-NEXT: (setlocal @3 (immediate 1))
+; CHECK-NEXT: (setlocal @4 (and @2 @3))
+; CHECK-NEXT: (return @4)
+define i32 @oeq_f32(float %x, float %y) {
+  %a = fcmp oeq float %x, %y
+  %b = zext i1 %a to i32
+  ret i32 %b
+}
+
+; CHECK-LABEL: une_f32:
+; CHECK: (setlocal @2 (ne @1 @0))
+define i32 @une_f32(float %x, float %y) {
+  %a = fcmp une float %x, %y
+  %b = zext i1 %a to i32
+  ret i32 %b
+}
+
+; CHECK-LABEL: olt_f32:
+; CHECK: (setlocal @2 (lt @1 @0))
+define i32 @olt_f32(float %x, float %y) {
+  %a = fcmp olt float %x, %y
+  %b = zext i1 %a to i32
+  ret i32 %b
+}
+
+; CHECK-LABEL: ole_f32:
+; CHECK: (setlocal @2 (le @1 @0))
+define i32 @ole_f32(float %x, float %y) {
+  %a = fcmp ole float %x, %y
+  %b = zext i1 %a to i32
+  ret i32 %b
+}
+
+; CHECK-LABEL: ogt_f32:
+; CHECK: (setlocal @2 (gt @1 @0))
+define i32 @ogt_f32(float %x, float %y) {
+  %a = fcmp ogt float %x, %y
+  %b = zext i1 %a to i32
+  ret i32 %b
+}
+
+; CHECK-LABEL: oge_f32:
+; CHECK: (setlocal @2 (ge @1 @0))
+define i32 @oge_f32(float %x, float %y) {
+  %a = fcmp oge float %x, %y
+  %b = zext i1 %a to i32
+  ret i32 %b
+}
+
+; FIXME test other FP comparisons: ueq, one, ult, ule, ugt, uge. They currently
+; are broken and failt to match.

Added: llvm/trunk/test/CodeGen/WebAssembly/comparisons_f64.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/WebAssembly/comparisons_f64.ll?rev=244665&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/WebAssembly/comparisons_f64.ll (added)
+++ llvm/trunk/test/CodeGen/WebAssembly/comparisons_f64.ll Tue Aug 11 16:02:46 2015
@@ -0,0 +1,65 @@
+; RUN: llc < %s -asm-verbose=false | FileCheck %s
+
+; Test that basic 64-bit floating-point comparison operations assemble as
+; expected.
+
+target datalayout = "e-p:32:32-i64:64-v128:8:128-n32:64-S128"
+target triple = "wasm32-unknown-unknown"
+
+; FIXME: add ord and uno tests.
+
+; CHECK-LABEL: oeq_f64:
+; CHECK-NEXT: (setlocal @0 (argument 1))
+; CHECK-NEXT: (setlocal @1 (argument 0))
+; CHECK-NEXT: (setlocal @2 (eq @1 @0))
+; CHECK-NEXT: (setlocal @3 (immediate 1))
+; CHECK-NEXT: (setlocal @4 (and @2 @3))
+; CHECK-NEXT: (return @4)
+define i32 @oeq_f64(double %x, double %y) {
+  %a = fcmp oeq double %x, %y
+  %b = zext i1 %a to i32
+  ret i32 %b
+}
+
+; CHECK-LABEL: une_f64:
+; CHECK: (setlocal @2 (ne @1 @0))
+define i32 @une_f64(double %x, double %y) {
+  %a = fcmp une double %x, %y
+  %b = zext i1 %a to i32
+  ret i32 %b
+}
+
+; CHECK-LABEL: olt_f64:
+; CHECK: (setlocal @2 (lt @1 @0))
+define i32 @olt_f64(double %x, double %y) {
+  %a = fcmp olt double %x, %y
+  %b = zext i1 %a to i32
+  ret i32 %b
+}
+
+; CHECK-LABEL: ole_f64:
+; CHECK: (setlocal @2 (le @1 @0))
+define i32 @ole_f64(double %x, double %y) {
+  %a = fcmp ole double %x, %y
+  %b = zext i1 %a to i32
+  ret i32 %b
+}
+
+; CHECK-LABEL: ogt_f64:
+; CHECK: (setlocal @2 (gt @1 @0))
+define i32 @ogt_f64(double %x, double %y) {
+  %a = fcmp ogt double %x, %y
+  %b = zext i1 %a to i32
+  ret i32 %b
+}
+
+; CHECK-LABEL: oge_f64:
+; CHECK: (setlocal @2 (ge @1 @0))
+define i32 @oge_f64(double %x, double %y) {
+  %a = fcmp oge double %x, %y
+  %b = zext i1 %a to i32
+  ret i32 %b
+}
+
+; FIXME test other FP comparisons: ueq, one, ult, ule, ugt, uge. They currently
+; are broken and failt to match.

Added: llvm/trunk/test/CodeGen/WebAssembly/comparisons_i32.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/WebAssembly/comparisons_i32.ll?rev=244665&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/WebAssembly/comparisons_i32.ll (added)
+++ llvm/trunk/test/CodeGen/WebAssembly/comparisons_i32.ll Tue Aug 11 16:02:46 2015
@@ -0,0 +1,91 @@
+; RUN: llc < %s -asm-verbose=false | FileCheck %s
+
+; Test that basic 32-bit integer comparison operations assemble as expected.
+
+target datalayout = "e-p:32:32-i64:64-v128:8:128-n32:64-S128"
+target triple = "wasm32-unknown-unknown"
+
+; CHECK-LABEL: eq_i32:
+; CHECK-NEXT: (setlocal @0 (argument 1))
+; CHECK-NEXT: (setlocal @1 (argument 0))
+; CHECK-NEXT: (setlocal @2 (eq @1 @0))
+; CHECK-NEXT: (setlocal @3 (immediate 1))
+; CHECK-NEXT: (setlocal @4 (and @2 @3))
+; CHECK-NEXT: (return @4)
+define i32 @eq_i32(i32 %x, i32 %y) {
+  %a = icmp eq i32 %x, %y
+  %b = zext i1 %a to i32
+  ret i32 %b
+}
+
+; CHECK-LABEL: ne_i32:
+; CHECK: (setlocal @2 (ne @1 @0))
+define i32 @ne_i32(i32 %x, i32 %y) {
+  %a = icmp ne i32 %x, %y
+  %b = zext i1 %a to i32
+  ret i32 %b
+}
+
+; CHECK-LABEL: slt_i32:
+; CHECK: (setlocal @2 (slt @1 @0))
+define i32 @slt_i32(i32 %x, i32 %y) {
+  %a = icmp slt i32 %x, %y
+  %b = zext i1 %a to i32
+  ret i32 %b
+}
+
+; CHECK-LABEL: sle_i32:
+; CHECK: (setlocal @2 (sle @1 @0))
+define i32 @sle_i32(i32 %x, i32 %y) {
+  %a = icmp sle i32 %x, %y
+  %b = zext i1 %a to i32
+  ret i32 %b
+}
+
+; CHECK-LABEL: ult_i32:
+; CHECK: (setlocal @2 (ult @1 @0))
+define i32 @ult_i32(i32 %x, i32 %y) {
+  %a = icmp ult i32 %x, %y
+  %b = zext i1 %a to i32
+  ret i32 %b
+}
+
+; CHECK-LABEL: ule_i32:
+; CHECK: (setlocal @2 (ule @1 @0))
+define i32 @ule_i32(i32 %x, i32 %y) {
+  %a = icmp ule i32 %x, %y
+  %b = zext i1 %a to i32
+  ret i32 %b
+}
+
+; CHECK-LABEL: sgt_i32:
+; CHECK: (setlocal @2 (sgt @1 @0))
+define i32 @sgt_i32(i32 %x, i32 %y) {
+  %a = icmp sgt i32 %x, %y
+  %b = zext i1 %a to i32
+  ret i32 %b
+}
+
+; CHECK-LABEL: sge_i32:
+; CHECK: (setlocal @2 (sge @1 @0))
+define i32 @sge_i32(i32 %x, i32 %y) {
+  %a = icmp sge i32 %x, %y
+  %b = zext i1 %a to i32
+  ret i32 %b
+}
+
+; CHECK-LABEL: ugt_i32:
+; CHECK: (setlocal @2 (ugt @1 @0))
+define i32 @ugt_i32(i32 %x, i32 %y) {
+  %a = icmp ugt i32 %x, %y
+  %b = zext i1 %a to i32
+  ret i32 %b
+}
+
+; CHECK-LABEL: uge_i32:
+; CHECK: (setlocal @2 (uge @1 @0))
+define i32 @uge_i32(i32 %x, i32 %y) {
+  %a = icmp uge i32 %x, %y
+  %b = zext i1 %a to i32
+  ret i32 %b
+}

Added: llvm/trunk/test/CodeGen/WebAssembly/comparisons_i64.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/WebAssembly/comparisons_i64.ll?rev=244665&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/WebAssembly/comparisons_i64.ll (added)
+++ llvm/trunk/test/CodeGen/WebAssembly/comparisons_i64.ll Tue Aug 11 16:02:46 2015
@@ -0,0 +1,91 @@
+; RUN: llc < %s -asm-verbose=false | FileCheck %s
+
+; Test that basic 64-bit integer comparison operations assemble as expected.
+
+target datalayout = "e-p:32:32-i64:64-v128:8:128-n32:64-S128"
+target triple = "wasm32-unknown-unknown"
+
+; CHECK-LABEL: eq_i64:
+; CHECK-NEXT: (setlocal @0 (argument 1))
+; CHECK-NEXT: (setlocal @1 (argument 0))
+; CHECK-NEXT: (setlocal @2 (eq @1 @0))
+; CHECK-NEXT: (setlocal @3 (immediate 1))
+; CHECK-NEXT: (setlocal @4 (and @2 @3))
+; CHECK-NEXT: (return @4)
+define i32 @eq_i64(i64 %x, i64 %y) {
+  %a = icmp eq i64 %x, %y
+  %b = zext i1 %a to i32
+  ret i32 %b
+}
+
+; CHECK-LABEL: ne_i64:
+; CHECK: (setlocal @2 (ne @1 @0))
+define i32 @ne_i64(i64 %x, i64 %y) {
+  %a = icmp ne i64 %x, %y
+  %b = zext i1 %a to i32
+  ret i32 %b
+}
+
+; CHECK-LABEL: slt_i64:
+; CHECK: (setlocal @2 (slt @1 @0))
+define i32 @slt_i64(i64 %x, i64 %y) {
+  %a = icmp slt i64 %x, %y
+  %b = zext i1 %a to i32
+  ret i32 %b
+}
+
+; CHECK-LABEL: sle_i64:
+; CHECK: (setlocal @2 (sle @1 @0))
+define i32 @sle_i64(i64 %x, i64 %y) {
+  %a = icmp sle i64 %x, %y
+  %b = zext i1 %a to i32
+  ret i32 %b
+}
+
+; CHECK-LABEL: ult_i64:
+; CHECK: (setlocal @2 (ult @1 @0))
+define i32 @ult_i64(i64 %x, i64 %y) {
+  %a = icmp ult i64 %x, %y
+  %b = zext i1 %a to i32
+  ret i32 %b
+}
+
+; CHECK-LABEL: ule_i64:
+; CHECK: (setlocal @2 (ule @1 @0))
+define i32 @ule_i64(i64 %x, i64 %y) {
+  %a = icmp ule i64 %x, %y
+  %b = zext i1 %a to i32
+  ret i32 %b
+}
+
+; CHECK-LABEL: sgt_i64:
+; CHECK: (setlocal @2 (sgt @1 @0))
+define i32 @sgt_i64(i64 %x, i64 %y) {
+  %a = icmp sgt i64 %x, %y
+  %b = zext i1 %a to i32
+  ret i32 %b
+}
+
+; CHECK-LABEL: sge_i64:
+; CHECK: (setlocal @2 (sge @1 @0))
+define i32 @sge_i64(i64 %x, i64 %y) {
+  %a = icmp sge i64 %x, %y
+  %b = zext i1 %a to i32
+  ret i32 %b
+}
+
+; CHECK-LABEL: ugt_i64:
+; CHECK: (setlocal @2 (ugt @1 @0))
+define i32 @ugt_i64(i64 %x, i64 %y) {
+  %a = icmp ugt i64 %x, %y
+  %b = zext i1 %a to i32
+  ret i32 %b
+}
+
+; CHECK-LABEL: uge_i64:
+; CHECK: (setlocal @2 (uge @1 @0))
+define i32 @uge_i64(i64 %x, i64 %y) {
+  %a = icmp uge i64 %x, %y
+  %b = zext i1 %a to i32
+  ret i32 %b
+}




More information about the llvm-commits mailing list