OSDN Git Service

Fix lowering ARM shift by zero as a move.
authorNicolas Capens <capn@google.com>
Mon, 1 May 2017 19:31:29 +0000 (15:31 -0400)
committerNicolas Capens <nicolascapens@google.com>
Tue, 2 May 2017 14:22:38 +0000 (14:22 +0000)
ARM does not support shifting by 0. An immediate value of 0 is interpreted as
shifting by 32. See section A8.4.1 Constant shifts of the ARMv7-A/R reference
manual.

Change-Id: I289a7c6091c04387700dc2e9b3f959639bd919ce
Reviewed-on: https://chromium-review.googlesource.com/491949
Reviewed-by: Jim Stichnoth <stichnot@chromium.org>
src/IceTargetLoweringARM32.cpp

index 6cc225c..3271271 100644 (file)
@@ -2513,6 +2513,13 @@ public:
     return legalizeToReg(Target, Swapped ? Src0 : Src1);
   }
 
+  bool isSrc1ImmediateZero() const {
+    if (!swappedOperands() && hasConstOperand()) {
+      return getConstantValue() == 0;
+    }
+    return false;
+  }
+
   bool immediateIsFlexEncodable() const {
     uint32_t Rotate, Imm8;
     return OperandARM32FlexImm::canHoldImm(getConstantValue(), &Rotate, &Imm8);
@@ -3422,8 +3429,12 @@ void TargetARM32::lowerArithmetic(const InstArithmetic *Instr) {
   case InstArithmetic::Shl: {
     Variable *Src0R = Srcs.unswappedSrc0R(this);
     if (!isVectorType(T->getType())) {
-      Operand *Src1R = Srcs.unswappedSrc1RShAmtImm(this);
-      _lsl(T, Src0R, Src1R);
+      if (Srcs.isSrc1ImmediateZero()) {
+        _mov(T, Src0R);
+      } else {
+        Operand *Src1R = Srcs.unswappedSrc1RShAmtImm(this);
+        _lsl(T, Src0R, Src1R);
+      }
     } else {
       auto *Src1R = Srcs.unswappedSrc1R(this);
       _vshl(T, Src0R, Src1R)->setSignType(InstARM32::FS_Unsigned);
@@ -3434,11 +3445,15 @@ void TargetARM32::lowerArithmetic(const InstArithmetic *Instr) {
   case InstArithmetic::Lshr: {
     Variable *Src0R = Srcs.unswappedSrc0R(this);
     if (!isVectorType(T->getType())) {
-      Operand *Src1R = Srcs.unswappedSrc1RShAmtImm(this);
       if (DestTy != IceType_i32) {
         _uxt(Src0R, Src0R);
       }
-      _lsr(T, Src0R, Src1R);
+      if (Srcs.isSrc1ImmediateZero()) {
+        _mov(T, Src0R);
+      } else {
+        Operand *Src1R = Srcs.unswappedSrc1RShAmtImm(this);
+        _lsr(T, Src0R, Src1R);
+      }
     } else {
       auto *Src1R = Srcs.unswappedSrc1R(this);
       auto *Src1RNeg = makeReg(Src1R->getType());
@@ -3454,7 +3469,11 @@ void TargetARM32::lowerArithmetic(const InstArithmetic *Instr) {
       if (DestTy != IceType_i32) {
         _sxt(Src0R, Src0R);
       }
-      _asr(T, Src0R, Srcs.unswappedSrc1RShAmtImm(this));
+      if (Srcs.isSrc1ImmediateZero()) {
+        _mov(T, Src0R);
+      } else {
+        _asr(T, Src0R, Srcs.unswappedSrc1RShAmtImm(this));
+      }
     } else {
       auto *Src1R = Srcs.unswappedSrc1R(this);
       auto *Src1RNeg = makeReg(Src1R->getType());