Subzero: address mode opt: Transform *(reg+const) into [reg+const].
Teach address mode optimization about Base=Base+Const,
Base=Const+Base, and Base=Base-Const patterns.
Change ConstantInteger::emit() to emit signed values.
BUG=none
R=jvoung@chromium.org
Review URL: https://codereview.chromium.org/459133002
diff --git a/src/IceTargetLoweringX8632.cpp b/src/IceTargetLoweringX8632.cpp
index 26d11b9..de033a5 100644
--- a/src/IceTargetLoweringX8632.cpp
+++ b/src/IceTargetLoweringX8632.cpp
@@ -3388,6 +3388,33 @@
}
}
+ // Base is Base=Var+Const || Base is Base=Const+Var ==>
+ // set Base=Var, Offset+=Const
+ // Base is Base=Var-Const ==>
+ // set Base=Var, Offset-=Const
+ const InstArithmetic *ArithInst =
+ llvm::dyn_cast_or_null<const InstArithmetic>(BaseInst);
+ if (ArithInst && (ArithInst->getOp() == InstArithmetic::Add ||
+ ArithInst->getOp() == InstArithmetic::Sub)) {
+ bool IsAdd = ArithInst->getOp() == InstArithmetic::Add;
+ Variable *Var = NULL;
+ ConstantInteger *Const = NULL;
+ if (Variable *VariableOperand =
+ llvm::dyn_cast<Variable>(ArithInst->getSrc(0))) {
+ Var = VariableOperand;
+ Const = llvm::dyn_cast<ConstantInteger>(ArithInst->getSrc(1));
+ } else if (IsAdd) {
+ Const = llvm::dyn_cast<ConstantInteger>(ArithInst->getSrc(0));
+ Var = llvm::dyn_cast<Variable>(ArithInst->getSrc(1));
+ }
+ if (!(Const && Var)) {
+ break;
+ }
+ Base = Var;
+ Offset += IsAdd ? Const->getValue() : -Const->getValue();
+ continue;
+ }
+
// Index is Index=Var<<Const && Const+Shift<=3 ==>
// Index=Var, Shift+=Const
@@ -3398,15 +3425,6 @@
// swap(Index,Base)
// Similar for Base=Const*Var and Base=Var<<Const
- // Base is Base=Var+Const ==>
- // set Base=Var, Offset+=Const
-
- // Base is Base=Const+Var ==>
- // set Base=Var, Offset+=Const
-
- // Base is Base=Var-Const ==>
- // set Base=Var, Offset-=Const
-
// Index is Index=Var+Const ==>
// set Index=Var, Offset+=(Const<<Shift)
@@ -4039,7 +4057,7 @@
template <> void ConstantInteger::emit(GlobalContext *Ctx) const {
Ostream &Str = Ctx->getStrEmit();
- Str << getValue();
+ Str << (int64_t) getValue();
}
template <> void ConstantFloat::emit(GlobalContext *Ctx) const {
diff --git a/tests_lit/llvm2ice_tests/address-mode-opt.ll b/tests_lit/llvm2ice_tests/address-mode-opt.ll
new file mode 100644
index 0000000..9890c66
--- /dev/null
+++ b/tests_lit/llvm2ice_tests/address-mode-opt.ll
@@ -0,0 +1,64 @@
+; This file checks support for address mode optimization.
+
+; RUN: %llvm2ice -O2 --verbose none %s | FileCheck %s
+; RUN: %llvm2ice -O2 --verbose none %s \
+; RUN: | llvm-mc -arch=x86 -x86-asm-syntax=intel -filetype=obj
+; RUN: %llvm2ice --verbose none %s | FileCheck --check-prefix=ERRORS %s
+
+define float @load_arg_plus_200000(float* %arg) {
+entry:
+ %arg.int = ptrtoint float* %arg to i32
+ %addr.int = add i32 %arg.int, 200000
+ %addr.ptr = inttoptr i32 %addr.int to float*
+ %addr.load = load float* %addr.ptr, align 4
+ ret float %addr.load
+; CHECK-LABEL: load_arg_plus_200000:
+; CHECK: movss xmm0, dword ptr [eax+200000]
+}
+
+define float @load_200000_plus_arg(float* %arg) {
+entry:
+ %arg.int = ptrtoint float* %arg to i32
+ %addr.int = add i32 200000, %arg.int
+ %addr.ptr = inttoptr i32 %addr.int to float*
+ %addr.load = load float* %addr.ptr, align 4
+ ret float %addr.load
+; CHECK-LABEL: load_200000_plus_arg:
+; CHECK: movss xmm0, dword ptr [eax+200000]
+}
+
+define float @load_arg_minus_200000(float* %arg) {
+entry:
+ %arg.int = ptrtoint float* %arg to i32
+ %addr.int = sub i32 %arg.int, 200000
+ %addr.ptr = inttoptr i32 %addr.int to float*
+ %addr.load = load float* %addr.ptr, align 4
+ ret float %addr.load
+; CHECK-LABEL: load_arg_minus_200000:
+; CHECK: movss xmm0, dword ptr [eax-200000]
+}
+
+define float @load_200000_minus_arg(float* %arg) {
+entry:
+ %arg.int = ptrtoint float* %arg to i32
+ %addr.int = sub i32 200000, %arg.int
+ %addr.ptr = inttoptr i32 %addr.int to float*
+ %addr.load = load float* %addr.ptr, align 4
+ ret float %addr.load
+; CHECK-LABEL: load_200000_minus_arg:
+; CHECK: movss xmm0, dword ptr [eax]
+}
+
+define float @address_mode_opt_chaining(float* %arg) {
+entry:
+ %arg.int = ptrtoint float* %arg to i32
+ %addr1.int = add i32 12, %arg.int
+ %addr2.int = sub i32 %addr1.int, 4
+ %addr2.ptr = inttoptr i32 %addr2.int to float*
+ %addr2.load = load float* %addr2.ptr, align 4
+ ret float %addr2.load
+; CHECK-LABEL: address_mode_opt_chaining:
+; CHECK: movss xmm0, dword ptr [eax+8]
+}
+
+; ERRORS-NOT: ICE translation error