diff --git a/llvm/lib/CodeGen/ExpandReductions.cpp b/llvm/lib/CodeGen/ExpandReductions.cpp --- a/llvm/lib/CodeGen/ExpandReductions.cpp +++ b/llvm/lib/CodeGen/ExpandReductions.cpp @@ -105,6 +105,9 @@ if (!FMF.allowReassoc()) Rdx = getOrderedReduction(Builder, Acc, Vec, getOpcode(ID), MRK); else { + if (!isPowerOf2_32(Vec->getType()->getVectorNumElements())) + continue; + Rdx = getShuffleReduction(Builder, Vec, getOpcode(ID), MRK); Rdx = Builder.CreateBinOp((Instruction::BinaryOps)getOpcode(ID), Acc, Rdx, "bin.rdx"); @@ -122,6 +125,9 @@ case Intrinsic::experimental_vector_reduce_fmax: case Intrinsic::experimental_vector_reduce_fmin: { Value *Vec = II->getArgOperand(0); + if (!isPowerOf2_32(Vec->getType()->getVectorNumElements())) + continue; + Rdx = getShuffleReduction(Builder, Vec, getOpcode(ID), MRK); } break; default: diff --git a/llvm/test/CodeGen/Generic/expand-experimental-reductions.ll b/llvm/test/CodeGen/Generic/expand-experimental-reductions.ll --- a/llvm/test/CodeGen/Generic/expand-experimental-reductions.ll +++ b/llvm/test/CodeGen/Generic/expand-experimental-reductions.ll @@ -18,6 +18,7 @@ declare double @llvm.experimental.vector.reduce.fmax.v2f64(<2 x double>) declare double @llvm.experimental.vector.reduce.fmin.v2f64(<2 x double>) +declare i8 @llvm.experimental.vector.reduce.and.i8.v3i8(<3 x i8>) define i64 @add_i64(<2 x i64> %vec) { ; CHECK-LABEL: @add_i64( @@ -303,3 +304,15 @@ %r = call double @llvm.experimental.vector.reduce.fmin.v2f64(<2 x double> %vec) ret double %r } + +; Test when the vector size is not power of two. +define i8 @test_v3i8(<3 x i8> %a) nounwind { +; CHECK-LABEL: @test_v3i8( +; CHECK-NEXT: entry: +; CHECK-NEXT: %b = call i8 @llvm.experimental.vector.reduce.and.v3i8(<3 x i8> %a) +; CHECK-NEXT: ret i8 %b +; +entry: + %b = call i8 @llvm.experimental.vector.reduce.and.i8.v3i8(<3 x i8> %a) + ret i8 %b +}