WebAssembly: implement getScalarShiftAmountTy so we can shift by amount, with type
authorJF Bastien <jfb@google.com>
Mon, 3 Aug 2015 00:00:11 +0000 (00:00 +0000)
committerJF Bastien <jfb@google.com>
Mon, 3 Aug 2015 00:00:11 +0000 (00:00 +0000)
Summary: This currently sets the shift amount RHS to the same type as the LHS, and assumes that the LHS is a simple type. This isn't currently the case e.g. with weird integers sizes, but will eventually be true and will assert if not. That's what you get for having an experimental backend: break it and you get to keep both pieces. Most backends either set the RHS to MVT::i32 or MVT::i64, but WebAssembly is a virtual ISA and tries to have regular-looking binary operations where both operands are the same type (even if a 64-bit RHS shifter is slightly silly, hey it's free!).

Subscribers: llvm-commits, sunfish, jfb

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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@243860 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
lib/Target/WebAssembly/WebAssemblyISelLowering.h
test/CodeGen/WebAssembly/integer64.ll

index f8b4fbd3bdeec8632b7f9782644a1748564bdad0..4360116a7f19122864a5c3cf2a9083cd5da31769 100644 (file)
@@ -111,6 +111,11 @@ WebAssemblyTargetLowering::WebAssemblyTargetLowering(
   // FIXME: setOperationAction...
 }
 
+MVT WebAssemblyTargetLowering::getScalarShiftAmountTy(const DataLayout &DL,
+                                                      EVT VT) const {
+  return VT.getSimpleVT();
+}
+
 //===----------------------------------------------------------------------===//
 // WebAssembly Lowering private implementation.
 //===----------------------------------------------------------------------===//
index 3e8252604d6ce143e4dab0c4b85674d77bcd0d34..12b4fe62864b1654dfdd8a1bfe73c5169f246904 100644 (file)
@@ -45,6 +45,8 @@ private:
   /// right decision when generating code for different targets.
   const WebAssemblySubtarget *Subtarget;
 
+  MVT getScalarShiftAmountTy(const DataLayout &DL, EVT) const override;
+
   bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF,
                       bool isVarArg,
                       const SmallVectorImpl<ISD::OutputArg> &Outs,
index 4ac2846754c4eefb2d3de3a51e5af18f427e1e2a..540646cc3882135669b03b4ab242db0101e100e2 100644 (file)
@@ -109,39 +109,35 @@ define i64 @xor64(i64 %x, i64 %y) {
   ret i64 %a
 }
 
-; FIXME: 64-bit shifts have an extra truncate of the input shift value, which
-;        WebAssembly hasn't taught isel to match yet. Fix with
-;        getScalarShiftAmountTy.
-
-; C;HECK-LABEL: shl64:
-; C;HECK-NEXT: (setlocal @0 (argument 1))
-; C;HECK-NEXT: (setlocal @1 (argument 0))
-; C;HECK-NEXT: (setlocal @2 (SHL_I64 @1 @0))
-; C;HECK-NEXT: (return @2)
-;define i64 @shl64(i64 %x, i64 %y) {
-;  %a = shl i64 %x, %y
-;  ret i64 %a
-;}
-
-; C;HECK-LABEL: shr64:
-; C;HECK-NEXT: (setlocal @0 (argument 1))
-; C;HECK-NEXT: (setlocal @1 (argument 0))
-; C;HECK-NEXT: (setlocal @2 (SHR_I64 @1 @0))
-; C;HECK-NEXT: (return @2)
-;define i64 @shr64(i64 %x, i64 %y) {
-;  %a = lshr i64 %x, %y
-;  ret i64 %a
-;}
-
-; C;HECK-LABEL: sar64:
-; C;HECK-NEXT: (setlocal @0 (argument 1))
-; C;HECK-NEXT: (setlocal @1 (argument 0))
-; C;HECK-NEXT: (setlocal @2 (SAR_I64 @1 @0))
-; C;HECK-NEXT: (return @2)
-;define i64 @sar64(i64 %x, i64 %y) {
-;  %a = ashr i64 %x, %y
-;  ret i64 %a
-;}
+; CHECK-LABEL: shl64:
+; CHECK-NEXT: (setlocal @0 (argument 1))
+; CHECK-NEXT: (setlocal @1 (argument 0))
+; CHECK-NEXT: (setlocal @2 (SHL_I64 @1 @0))
+; CHECK-NEXT: (return @2)
+define i64 @shl64(i64 %x, i64 %y) {
+  %a = shl i64 %x, %y
+  ret i64 %a
+}
+
+; CHECK-LABEL: shr64:
+; CHECK-NEXT: (setlocal @0 (argument 1))
+; CHECK-NEXT: (setlocal @1 (argument 0))
+; CHECK-NEXT: (setlocal @2 (SHR_I64 @1 @0))
+; CHECK-NEXT: (return @2)
+define i64 @shr64(i64 %x, i64 %y) {
+  %a = lshr i64 %x, %y
+  ret i64 %a
+}
+
+; CHECK-LABEL: sar64:
+; CHECK-NEXT: (setlocal @0 (argument 1))
+; CHECK-NEXT: (setlocal @1 (argument 0))
+; CHECK-NEXT: (setlocal @2 (SAR_I64 @1 @0))
+; CHECK-NEXT: (return @2)
+define i64 @sar64(i64 %x, i64 %y) {
+  %a = ashr i64 %x, %y
+  ret i64 %a
+}
 
 ; CHECK-LABEL: clz64:
 ; CHECK-NEXT: (setlocal @0 (argument 0))