[RISCV] Disable SLP vectorization by default due to unresolved profitability issues

This change implements a TTI query with the goal of disabling slp vectorization on RISCV. The current default configuration disables SLP already, but its current tied to the ability to lower fixed length vectors. Over in D131508, I want to enable fixed length vectors for purposes of LoopVectorizer, but preliminary analysis has revealed a couple of SLP specific issues we need to resolve before enabling it by default. This change exists to allow us to enable LV without SLP.

Differential Revision: https://reviews.llvm.org/D132680
This commit is contained in:
Philip Reames 2022-08-26 14:06:40 -07:00 committed by Philip Reames
parent 0e5813b88e
commit a310637132
4 changed files with 54 additions and 4 deletions

View File

@ -24,6 +24,13 @@ static cl::opt<unsigned> RVVRegisterWidthLMUL(
"by autovectorized code. Fractional LMULs are not supported."),
cl::init(1), cl::Hidden);
static cl::opt<unsigned> SLPMaxVF(
"riscv-v-slp-max-vf",
cl::desc(
"Result used for getMaximumVF query which is used exclusively by "
"SLP vectorizer. Defaults to 1 which disables SLP."),
cl::init(1), cl::Hidden);
InstructionCost RISCVTTIImpl::getIntImmCost(const APInt &Imm, Type *Ty,
TTI::TargetCostKind CostKind) {
assert(Ty->isIntegerTy() &&
@ -999,3 +1006,12 @@ unsigned RISCVTTIImpl::getRegUsageForType(Type *Ty) {
return BaseT::getRegUsageForType(Ty);
}
unsigned RISCVTTIImpl::getMaximumVF(unsigned ElemWidth, unsigned Opcode) const {
// This interface is currently only used by SLP. Returning 1 (which is the
// default value for SLPMaxVF) disables SLP. We currently have a cost modeling
// problem w/ constant materialization which causes SLP to perform majorly
// unprofitable transformations.
// TODO: Figure out constant materialization cost modeling and remove.
return SLPMaxVF;
}

View File

@ -83,6 +83,8 @@ public:
unsigned getRegUsageForType(Type *Ty);
unsigned getMaximumVF(unsigned ElemWidth, unsigned Opcode) const;
InstructionCost getMaskedMemoryOpCost(unsigned Opcode, Type *Src,
Align Alignment, unsigned AddressSpace,
TTI::TargetCostKind CostKind);

View File

@ -1,6 +1,8 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -slp-vectorizer -mtriple=riscv64 -mattr=+v \
; RUN: -riscv-v-vector-bits-min=-1 -S | FileCheck %s --check-prefixes=CHECK
; RUN: -riscv-v-vector-bits-min=-1 -riscv-v-slp-max-vf=0 -S | FileCheck %s --check-prefixes=CHECK
; RUN: opt < %s -slp-vectorizer -mtriple=riscv64 -mattr=+v -S | FileCheck %s --check-prefixes=DEFAULT
define void @simple_copy(ptr %dest, ptr %p) {
; CHECK-LABEL: @simple_copy(
@ -9,6 +11,16 @@ define void @simple_copy(ptr %dest, ptr %p) {
; CHECK-NEXT: store <2 x i16> [[TMP0]], ptr [[DEST:%.*]], align 4
; CHECK-NEXT: ret void
;
; DEFAULT-LABEL: @simple_copy(
; DEFAULT-NEXT: entry:
; DEFAULT-NEXT: [[E0:%.*]] = load i16, ptr [[P:%.*]], align 4
; DEFAULT-NEXT: [[INC:%.*]] = getelementptr inbounds i16, ptr [[P]], i64 1
; DEFAULT-NEXT: [[E1:%.*]] = load i16, ptr [[INC]], align 2
; DEFAULT-NEXT: store i16 [[E0]], ptr [[DEST:%.*]], align 4
; DEFAULT-NEXT: [[INC2:%.*]] = getelementptr inbounds i16, ptr [[DEST]], i64 1
; DEFAULT-NEXT: store i16 [[E1]], ptr [[INC2]], align 2
; DEFAULT-NEXT: ret void
;
entry:
%e0 = load i16, ptr %p, align 4
%inc = getelementptr inbounds i16, ptr %p, i64 1
@ -28,6 +40,18 @@ define void @vec_add(ptr %dest, ptr %p) {
; CHECK-NEXT: store <2 x i16> [[TMP1]], ptr [[DEST:%.*]], align 4
; CHECK-NEXT: ret void
;
; DEFAULT-LABEL: @vec_add(
; DEFAULT-NEXT: entry:
; DEFAULT-NEXT: [[E0:%.*]] = load i16, ptr [[P:%.*]], align 4
; DEFAULT-NEXT: [[INC:%.*]] = getelementptr inbounds i16, ptr [[P]], i64 1
; DEFAULT-NEXT: [[E1:%.*]] = load i16, ptr [[INC]], align 2
; DEFAULT-NEXT: [[A0:%.*]] = add i16 [[E0]], 1
; DEFAULT-NEXT: [[A1:%.*]] = add i16 [[E1]], 1
; DEFAULT-NEXT: store i16 [[A0]], ptr [[DEST:%.*]], align 4
; DEFAULT-NEXT: [[INC2:%.*]] = getelementptr inbounds i16, ptr [[DEST]], i64 1
; DEFAULT-NEXT: store i16 [[A1]], ptr [[INC2]], align 2
; DEFAULT-NEXT: ret void
;
entry:
%e0 = load i16, ptr %p, align 4
%inc = getelementptr inbounds i16, ptr %p, i64 1
@ -52,6 +76,14 @@ define void @splat_store(ptr %dest, ptr %p) {
; CHECK-NEXT: store i16 [[E0]], ptr [[INC2]], align 2
; CHECK-NEXT: ret void
;
; DEFAULT-LABEL: @splat_store(
; DEFAULT-NEXT: entry:
; DEFAULT-NEXT: [[E0:%.*]] = load i16, ptr [[P:%.*]], align 4
; DEFAULT-NEXT: store i16 [[E0]], ptr [[DEST:%.*]], align 4
; DEFAULT-NEXT: [[INC2:%.*]] = getelementptr inbounds i16, ptr [[DEST]], i64 1
; DEFAULT-NEXT: store i16 [[E0]], ptr [[INC2]], align 2
; DEFAULT-NEXT: ret void
;
entry:
%e0 = load i16, ptr %p, align 4

View File

@ -1,10 +1,10 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -slp-vectorizer -mtriple=riscv64 -mattr=+v \
; RUN: -riscv-v-vector-bits-min=128 -S | FileCheck %s --check-prefixes=CHECK,CHECK-128
; RUN: -riscv-v-vector-bits-min=128 -riscv-v-slp-max-vf=0 -S | FileCheck %s --check-prefixes=CHECK,CHECK-128
; RUN: opt < %s -slp-vectorizer -mtriple=riscv64 -mattr=+v \
; RUN: -riscv-v-vector-bits-min=256 -S | FileCheck %s --check-prefixes=CHECK,CHECK-256
; RUN: -riscv-v-vector-bits-min=256 -riscv-v-slp-max-vf=0 -S | FileCheck %s --check-prefixes=CHECK,CHECK-256
; RUN: opt < %s -slp-vectorizer -mtriple=riscv64 -mattr=+v \
; RUN: -riscv-v-vector-bits-min=512 -S | FileCheck %s --check-prefixes=CHECK,CHECK-512
; RUN: -riscv-v-vector-bits-min=512 -riscv-v-slp-max-vf=0 -S | FileCheck %s --check-prefixes=CHECK,CHECK-512
target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n64-S128"
target triple = "riscv64"