Index: lib/Transforms/Scalar/ConstantHoisting.cpp =================================================================== --- lib/Transforms/Scalar/ConstantHoisting.cpp +++ lib/Transforms/Scalar/ConstantHoisting.cpp @@ -585,10 +585,27 @@ for (auto CC = std::next(ConstCandVec.begin()), E = ConstCandVec.end(); CC != E; ++CC) { if (MinValItr->ConstInt->getType() == CC->ConstInt->getType()) { + Type *MemUseValTy = nullptr; + for (auto &U : CC->Uses) { + auto *UI = U.Inst; + if (LoadInst *LI = dyn_cast(UI)) { + MemUseValTy = LI->getType(); + break; + } else if (StoreInst *SI = dyn_cast(UI)) { + MemUseValTy = SI->getValueOperand()->getType(); + break; + } + } + // Check if the constant is in range of an add with immediate. APInt Diff = CC->ConstInt->getValue() - MinValItr->ConstInt->getValue(); if ((Diff.getBitWidth() <= 64) && - TTI->isLegalAddImmediate(Diff.getSExtValue())) + TTI->isLegalAddImmediate(Diff.getSExtValue()) && + // Check if Diff can be used as offset in addressing mode of the user + // memory instruction. + (!MemUseValTy || TTI->isLegalAddressingMode(MemUseValTy, + /*BaseGV*/nullptr, /*BaseOffset*/Diff.getSExtValue(), + /*HasBaseReg*/false, /*Scale*/0))) continue; } // We either have now a different constant type or the constant is not in Index: test/Transforms/ConstantHoisting/ARM/is-legal-addressing-imm.ll =================================================================== --- /dev/null +++ test/Transforms/ConstantHoisting/ARM/is-legal-addressing-imm.ll @@ -0,0 +1,22 @@ +; RUN: opt -consthoist -S -o - %s | FileCheck %s +target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64" +target triple = "thumbv6m-none--musleabi" + +; CHECK: foo +; CHECK-DAG: %const2 = bitcast i32 {{[0-9]+}} to i32 +; CHECK-DAG: %const1 = bitcast i32 {{[0-9]+}} to i32 +; CHECK: %const_mat{{[0-9]?}} = add i32 %const1, 4 +; CHECK: %and = and +; CHECK: %const_mat{{[0-9]?}} = add i32 %const2, 4 + +define dso_local void @foo() { +entry: + %0 = load volatile i32, i32* inttoptr (i32 805874688 to i32*), align 1024 + %1 = load volatile i32, i32* inttoptr (i32 805874692 to i32*), align 4 + %and = and i32 %1, 65535 + %2 = load volatile i32, i32* inttoptr (i32 805874824 to i32*), align 8 + %and1 = and i32 %2, 65535 + %3 = load volatile i32, i32* inttoptr (i32 805874828 to i32*), align 4 + ret void +} +