Commit fb705a6d by Nicolas Capens Committed by Nicolas Capens

Fix lowering ARM shift by zero as a move.

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/491949Reviewed-by: 's avatarJim Stichnoth <stichnot@chromium.org>
parent 6c629dc3
...@@ -2513,6 +2513,13 @@ public: ...@@ -2513,6 +2513,13 @@ public:
return legalizeToReg(Target, Swapped ? Src0 : Src1); return legalizeToReg(Target, Swapped ? Src0 : Src1);
} }
bool isSrc1ImmediateZero() const {
if (!swappedOperands() && hasConstOperand()) {
return getConstantValue() == 0;
}
return false;
}
bool immediateIsFlexEncodable() const { bool immediateIsFlexEncodable() const {
uint32_t Rotate, Imm8; uint32_t Rotate, Imm8;
return OperandARM32FlexImm::canHoldImm(getConstantValue(), &Rotate, &Imm8); return OperandARM32FlexImm::canHoldImm(getConstantValue(), &Rotate, &Imm8);
...@@ -3422,8 +3429,12 @@ void TargetARM32::lowerArithmetic(const InstArithmetic *Instr) { ...@@ -3422,8 +3429,12 @@ void TargetARM32::lowerArithmetic(const InstArithmetic *Instr) {
case InstArithmetic::Shl: { case InstArithmetic::Shl: {
Variable *Src0R = Srcs.unswappedSrc0R(this); Variable *Src0R = Srcs.unswappedSrc0R(this);
if (!isVectorType(T->getType())) { if (!isVectorType(T->getType())) {
Operand *Src1R = Srcs.unswappedSrc1RShAmtImm(this); if (Srcs.isSrc1ImmediateZero()) {
_lsl(T, Src0R, Src1R); _mov(T, Src0R);
} else {
Operand *Src1R = Srcs.unswappedSrc1RShAmtImm(this);
_lsl(T, Src0R, Src1R);
}
} else { } else {
auto *Src1R = Srcs.unswappedSrc1R(this); auto *Src1R = Srcs.unswappedSrc1R(this);
_vshl(T, Src0R, Src1R)->setSignType(InstARM32::FS_Unsigned); _vshl(T, Src0R, Src1R)->setSignType(InstARM32::FS_Unsigned);
...@@ -3434,11 +3445,15 @@ void TargetARM32::lowerArithmetic(const InstArithmetic *Instr) { ...@@ -3434,11 +3445,15 @@ void TargetARM32::lowerArithmetic(const InstArithmetic *Instr) {
case InstArithmetic::Lshr: { case InstArithmetic::Lshr: {
Variable *Src0R = Srcs.unswappedSrc0R(this); Variable *Src0R = Srcs.unswappedSrc0R(this);
if (!isVectorType(T->getType())) { if (!isVectorType(T->getType())) {
Operand *Src1R = Srcs.unswappedSrc1RShAmtImm(this);
if (DestTy != IceType_i32) { if (DestTy != IceType_i32) {
_uxt(Src0R, Src0R); _uxt(Src0R, Src0R);
} }
_lsr(T, Src0R, Src1R); if (Srcs.isSrc1ImmediateZero()) {
_mov(T, Src0R);
} else {
Operand *Src1R = Srcs.unswappedSrc1RShAmtImm(this);
_lsr(T, Src0R, Src1R);
}
} else { } else {
auto *Src1R = Srcs.unswappedSrc1R(this); auto *Src1R = Srcs.unswappedSrc1R(this);
auto *Src1RNeg = makeReg(Src1R->getType()); auto *Src1RNeg = makeReg(Src1R->getType());
...@@ -3454,7 +3469,11 @@ void TargetARM32::lowerArithmetic(const InstArithmetic *Instr) { ...@@ -3454,7 +3469,11 @@ void TargetARM32::lowerArithmetic(const InstArithmetic *Instr) {
if (DestTy != IceType_i32) { if (DestTy != IceType_i32) {
_sxt(Src0R, Src0R); _sxt(Src0R, Src0R);
} }
_asr(T, Src0R, Srcs.unswappedSrc1RShAmtImm(this)); if (Srcs.isSrc1ImmediateZero()) {
_mov(T, Src0R);
} else {
_asr(T, Src0R, Srcs.unswappedSrc1RShAmtImm(this));
}
} else { } else {
auto *Src1R = Srcs.unswappedSrc1R(this); auto *Src1R = Srcs.unswappedSrc1R(this);
auto *Src1RNeg = makeReg(Src1R->getType()); auto *Src1RNeg = makeReg(Src1R->getType());
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment