Subzero: Fix x86 lowering for shift-by-relocatable-constant.
Trying to shift by a ConstantRelocatable causes an assertion failure in the integrated assembler, because the shift value must be Imm8. Maybe this is possible to express via ELF relocations, but it doesn't seem worth it. Especially since ConstantRelocatables refer to addresses and it doesn't make sense to shift by an address.
BUG= https://code.google.com/p/nativeclient/issues/detail?id=4256
R=jvoung@chromium.org, kschimpf@google.com
Review URL: https://codereview.chromium.org/1262003003.
diff --git a/src/IceTargetLoweringX86BaseImpl.h b/src/IceTargetLoweringX86BaseImpl.h
index 2532217..3ec094e 100644
--- a/src/IceTargetLoweringX86BaseImpl.h
+++ b/src/IceTargetLoweringX86BaseImpl.h
@@ -1835,21 +1835,21 @@
break;
case InstArithmetic::Shl:
_mov(T, Src0);
- if (!llvm::isa<Constant>(Src1))
+ if (!llvm::isa<ConstantInteger32>(Src1))
Src1 = legalizeToReg(Src1, Traits::RegisterSet::Reg_ecx);
_shl(T, Src1);
_mov(Dest, T);
break;
case InstArithmetic::Lshr:
_mov(T, Src0);
- if (!llvm::isa<Constant>(Src1))
+ if (!llvm::isa<ConstantInteger32>(Src1))
Src1 = legalizeToReg(Src1, Traits::RegisterSet::Reg_ecx);
_shr(T, Src1);
_mov(Dest, T);
break;
case InstArithmetic::Ashr:
_mov(T, Src0);
- if (!llvm::isa<Constant>(Src1))
+ if (!llvm::isa<ConstantInteger32>(Src1))
Src1 = legalizeToReg(Src1, Traits::RegisterSet::Reg_ecx);
_sar(T, Src1);
_mov(Dest, T);
diff --git a/tests_lit/llvm2ice_tests/arith.ll b/tests_lit/llvm2ice_tests/arith.ll
index 3fbdab6..3027ee2 100644
--- a/tests_lit/llvm2ice_tests/arith.ll
+++ b/tests_lit/llvm2ice_tests/arith.ll
@@ -207,3 +207,35 @@
; ARM32HWDIV: bne
; ARM32HWDIV: udiv
; ARM32HWDIV: mls
+
+; The following tests check that shift instructions don't try to use a
+; ConstantRelocatable as an immediate operand.
+
+@G = internal global [4 x i8] zeroinitializer, align 4
+
+define i32 @ShlReloc(i32 %a) {
+entry:
+ %opnd = ptrtoint [4 x i8]* @G to i32
+ %result = shl i32 %a, %opnd
+ ret i32 %result
+}
+; CHECK-LABEL: ShlReloc
+; CHECK: shl {{.*}},cl
+
+define i32 @LshrReloc(i32 %a) {
+entry:
+ %opnd = ptrtoint [4 x i8]* @G to i32
+ %result = lshr i32 %a, %opnd
+ ret i32 %result
+}
+; CHECK-LABEL: LshrReloc
+; CHECK: shr {{.*}},cl
+
+define i32 @AshrReloc(i32 %a) {
+entry:
+ %opnd = ptrtoint [4 x i8]* @G to i32
+ %result = ashr i32 %a, %opnd
+ ret i32 %result
+}
+; CHECK-LABEL: AshrReloc
+; CHECK: sar {{.*}},cl