diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -15938,9 +15938,16 @@ // by AM is legal for this target, for a load/store of the specified type. bool PPCTargetLowering::isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty, - unsigned AS, Instruction *I) const { - // PPC does not allow r+i addressing modes for vectors! - if (Ty->isVectorTy() && AM.BaseOffs != 0) + unsigned AS, + Instruction *I) const { + // Vector type r+i form is supported since power9 as DQ form. We don't check + // the offset matching DQ form requirement(off % 16 == 0), because on PowerPC, + // imm form is preferred and the offset can be adjusted to use imm form later + // in pass PPCLoopInstrFormPrep. Also in LSR, for one LSRUse, it uses min and + // max offset to check legal addressing mode, we should be a little aggressive + // to contain other offsets for that LSRUse. + if (Ty->isVectorTy() && AM.BaseOffs != 0 && + !(Subtarget.hasP9Vector() || Subtarget.hasP10Vector())) return false; // PPC allows a sign-extended 16-bit immediate field. diff --git a/llvm/test/CodeGen/PowerPC/prefer-dqform.ll b/llvm/test/CodeGen/PowerPC/prefer-dqform.ll --- a/llvm/test/CodeGen/PowerPC/prefer-dqform.ll +++ b/llvm/test/CodeGen/PowerPC/prefer-dqform.ll @@ -12,26 +12,27 @@ define void @test(i32* dereferenceable(4) %.ial, i32* noalias dereferenceable(4) %.m, i32* noalias dereferenceable(4) %.n, [0 x %_elem_type_of_a]* %.a, i32* noalias dereferenceable(4) %.lda, [0 x %_elem_type_of_x]* noalias %.x, [0 x %_elem_type_of_y]* noalias %.y) { ; CHECK-P9-LABEL: test: ; CHECK-P9: .LBB0_2: # %_loop_2_do_ -; CHECK-P9: lxvx -; CHECK-P9: lxvx -; CHECK-P9-DAG: lxvx -; CHECK-P9-DAG: lxvx -; CHECK-P9-DAG: xvmaddadp -; CHECK-P9-DAG: xvmaddadp -; CHECK-P9-DAG: stxvx -; CHECK-P9: stxvx +; CHECK-P9: lxv vs1, -16(r4) +; CHECK-P9: lxv vs2, 0(r4) +; CHECK-P9-DAG: lxv vs3, -16(r3) +; CHECK-P9-DAG: lxv vs4, 0(r3) +; CHECK-P9-DAG: xvmaddadp vs1, vs3, vs1 +; CHECK-P9-DAG: stxv vs1, -16(r4) +; CHECK-P9-DAG: xvmaddadp vs2, vs4, vs0 +; CHECK-P9: stxv vs2, 0(r4) ; CHECK-P9: bdnz .LBB0_2 ; +; FIXME: use pair load/store instructions lxvp/stxvp ; CHECK-P10-LABEL: test: ; CHECK-P10: .LBB0_2: # %_loop_2_do_ -; CHECK-P10: lxvx -; CHECK-P10: lxvx -; CHECK-P10-DAG: lxvx -; CHECK-P10-DAG: lxvx -; CHECK-P10-DAG: xvmaddadp -; CHECK-P10-DAG: xvmaddadp -; CHECK-P10-DAG: stxvx -; CHECK-P10: stxvx +; CHECK-P10: lxv vs1, -16(r4) +; CHECK-P10: lxv vs2, 0(r4) +; CHECK-P10-DAG: lxv vs3, -16(r3) +; CHECK-P10-DAG: lxv vs4, 0(r3) +; CHECK-P10-DAG: xvmaddadp vs1, vs3, vs1 +; CHECK-P10-DAG: xvmaddadp vs2, vs4, vs0 +; CHECK-P10-DAG: stxv vs1, -16(r4) +; CHECK-P10: stxv vs2, 0(r4) ; CHECK-P10: bdnz .LBB0_2 test_entry: %_conv5 = ptrtoint [0 x %_elem_type_of_a]* %.a to i64