Support vector shift by constant for ARM32.

This also fixes the encoding of right shifts with unsigned elements.

Bug b/37496338

Change-Id: I9a1dc91359daea5f4391a137b7f9e03bd941146b
Reviewed-on: https://chromium-review.googlesource.com/688057
Reviewed-by: Jim Stichnoth <stichnot@chromium.org>
Reviewed-on: https://swiftshader-review.googlesource.com/12668
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Tested-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/third_party/subzero/src/IceTargetLoweringARM32.cpp b/third_party/subzero/src/IceTargetLoweringARM32.cpp
index 3f9a66b..ace8023 100644
--- a/third_party/subzero/src/IceTargetLoweringARM32.cpp
+++ b/third_party/subzero/src/IceTargetLoweringARM32.cpp
@@ -2442,6 +2442,8 @@
     return legalizeToReg(Target, Swapped ? Src0 : Src1);
   }
 
+  Operand *src1() const { return Src1; }
+
 protected:
   Operand *const Src0;
   Operand *const Src1;
@@ -3436,8 +3438,13 @@
         _lsl(T, Src0R, Src1R);
       }
     } else {
-      auto *Src1R = Srcs.unswappedSrc1R(this);
-      _vshl(T, Src0R, Src1R)->setSignType(InstARM32::FS_Unsigned);
+      if (Srcs.hasConstOperand()) {
+        ConstantInteger32 *ShAmt = llvm::cast<ConstantInteger32>(Srcs.src1());
+        _vshl(T, Src0R, ShAmt);
+      } else {
+        auto *Src1R = Srcs.unswappedSrc1R(this);
+        _vshl(T, Src0R, Src1R)->setSignType(InstARM32::FS_Unsigned);
+      }
     }
     _mov(Dest, T);
     return;
@@ -3455,10 +3462,15 @@
         _lsr(T, Src0R, Src1R);
       }
     } else {
-      auto *Src1R = Srcs.unswappedSrc1R(this);
-      auto *Src1RNeg = makeReg(Src1R->getType());
-      _vneg(Src1RNeg, Src1R);
-      _vshl(T, Src0R, Src1RNeg)->setSignType(InstARM32::FS_Unsigned);
+      if (Srcs.hasConstOperand()) {
+        ConstantInteger32 *ShAmt = llvm::cast<ConstantInteger32>(Srcs.src1());
+        _vshr(T, Src0R, ShAmt)->setSignType(InstARM32::FS_Unsigned);
+      } else {
+        auto *Src1R = Srcs.unswappedSrc1R(this);
+        auto *Src1RNeg = makeReg(Src1R->getType());
+        _vneg(Src1RNeg, Src1R);
+        _vshl(T, Src0R, Src1RNeg)->setSignType(InstARM32::FS_Unsigned);
+      }
     }
     _mov(Dest, T);
     return;
@@ -3475,10 +3487,15 @@
         _asr(T, Src0R, Srcs.unswappedSrc1RShAmtImm(this));
       }
     } else {
-      auto *Src1R = Srcs.unswappedSrc1R(this);
-      auto *Src1RNeg = makeReg(Src1R->getType());
-      _vneg(Src1RNeg, Src1R);
-      _vshl(T, Src0R, Src1RNeg)->setSignType(InstARM32::FS_Signed);
+      if (Srcs.hasConstOperand()) {
+        ConstantInteger32 *ShAmt = llvm::cast<ConstantInteger32>(Srcs.src1());
+        _vshr(T, Src0R, ShAmt)->setSignType(InstARM32::FS_Signed);
+      } else {
+        auto *Src1R = Srcs.unswappedSrc1R(this);
+        auto *Src1RNeg = makeReg(Src1R->getType());
+        _vneg(Src1RNeg, Src1R);
+        _vshl(T, Src0R, Src1RNeg)->setSignType(InstARM32::FS_Signed);
+      }
     }
     _mov(Dest, T);
     return;
@@ -5251,7 +5268,6 @@
     return;
   }
   case Intrinsics::Fabs: {
-    Type DestTy = Dest->getType();
     Variable *T = makeReg(DestTy);
     _vabs(T, legalizeToReg(Instr->getArg(0)));
     _mov(Dest, T);
@@ -5286,7 +5302,7 @@
     assert(isScalarFloatingType(Dest->getType()) ||
            getFlags().getApplicationBinaryInterface() != ::Ice::ABI_PNaCl);
     Variable *Src = legalizeToReg(Instr->getArg(0));
-    Variable *T = makeReg(Dest->getType());
+    Variable *T = makeReg(DestTy);
     _vsqrt(T, Src);
     _mov(Dest, T);
     return;