diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp index 539c9227af7e3..ef8740ec2b451 100644 --- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp +++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp @@ -12248,10 +12248,10 @@ InstructionCost BoUpSLP::getSpillCost() { }; // Debug information does not impact spill cost. - // Vectorized calls, represented as vector intrinsics, do not impact spill - // cost. + // Vectorized calls, represented as vector intrinsics, may still impact + // spill cost if scalarized in codegen. if (const auto *CB = dyn_cast(&*PrevInstIt); - CB && !NoCallIntrinsic(CB) && !isVectorized(CB)) + CB && !NoCallIntrinsic(CB)) NumCalls++; ++PrevInstIt; diff --git a/llvm/test/Transforms/SLPVectorizer/RISCV/math-function.ll b/llvm/test/Transforms/SLPVectorizer/RISCV/math-function.ll index 5bfd776512711..4a2a6ace5f8b8 100644 --- a/llvm/test/Transforms/SLPVectorizer/RISCV/math-function.ll +++ b/llvm/test/Transforms/SLPVectorizer/RISCV/math-function.ll @@ -141,6 +141,52 @@ entry: ret <4 x float> %vecins.3 } +; Don't vectorize @llvm.exp because it will be scalarized in codegen. +define void @exp_v2f64(ptr %a) { +; CHECK-LABEL: define void @exp_v2f64 +; CHECK-SAME: (ptr [[A:%.*]]) #[[ATTR1]] { +; CHECK-NEXT: [[X:%.*]] = load double, ptr [[A]], align 8 +; CHECK-NEXT: [[GEP:%.*]] = getelementptr double, ptr [[A]], i64 1 +; CHECK-NEXT: [[Y:%.*]] = load double, ptr [[GEP]], align 8 +; CHECK-NEXT: [[X_ADD:%.*]] = fadd double [[X]], 1.000000e+00 +; CHECK-NEXT: [[Y_ADD:%.*]] = fadd double [[Y]], 1.000000e+00 +; CHECK-NEXT: [[X_EXP:%.*]] = call double @llvm.exp.f64(double [[X_ADD]]) +; CHECK-NEXT: [[Y_EXP:%.*]] = call double @llvm.exp.f64(double [[Y_ADD]]) +; CHECK-NEXT: [[X_ADD2:%.*]] = fadd double [[X_EXP]], 1.000000e+00 +; CHECK-NEXT: [[Y_ADD2:%.*]] = fadd double [[Y_EXP]], 1.000000e+00 +; CHECK-NEXT: store double [[X_ADD2]], ptr [[A]], align 8 +; CHECK-NEXT: store double [[Y_ADD2]], ptr [[GEP]], align 8 +; CHECK-NEXT: ret void +; +; DEFAULT-LABEL: define void @exp_v2f64 +; DEFAULT-SAME: (ptr [[A:%.*]]) #[[ATTR1]] { +; DEFAULT-NEXT: [[X:%.*]] = load double, ptr [[A]], align 8 +; DEFAULT-NEXT: [[GEP:%.*]] = getelementptr double, ptr [[A]], i64 1 +; DEFAULT-NEXT: [[Y:%.*]] = load double, ptr [[GEP]], align 8 +; DEFAULT-NEXT: [[X_ADD:%.*]] = fadd double [[X]], 1.000000e+00 +; DEFAULT-NEXT: [[Y_ADD:%.*]] = fadd double [[Y]], 1.000000e+00 +; DEFAULT-NEXT: [[X_EXP:%.*]] = call double @llvm.exp.f64(double [[X_ADD]]) +; DEFAULT-NEXT: [[Y_EXP:%.*]] = call double @llvm.exp.f64(double [[Y_ADD]]) +; DEFAULT-NEXT: [[X_ADD2:%.*]] = fadd double [[X_EXP]], 1.000000e+00 +; DEFAULT-NEXT: [[Y_ADD2:%.*]] = fadd double [[Y_EXP]], 1.000000e+00 +; DEFAULT-NEXT: store double [[X_ADD2]], ptr [[A]], align 8 +; DEFAULT-NEXT: store double [[Y_ADD2]], ptr [[GEP]], align 8 +; DEFAULT-NEXT: ret void +; + %x = load double, ptr %a + %gep = getelementptr double, ptr %a, i64 1 + %y = load double, ptr %gep + %x.add = fadd double %x, 1.0 + %y.add = fadd double %y, 1.0 + %x.exp = call double @llvm.exp(double %x.add) + %y.exp = call double @llvm.exp(double %y.add) + %x.add2 = fadd double %x.exp, 1.0 + %y.add2 = fadd double %y.exp, 1.0 + store double %x.add2, ptr %a + store double %y.add2, ptr %gep + ret void +} + declare float @expf(float) readonly nounwind willreturn ; We can not vectorized exp since RISCV has no such instruction.