diff --git a/llvm/lib/IR/ConstantFold.cpp b/llvm/lib/IR/ConstantFold.cpp --- a/llvm/lib/IR/ConstantFold.cpp +++ b/llvm/lib/IR/ConstantFold.cpp @@ -913,6 +913,8 @@ if (!CIdx->uge(ValSVTy->getMinNumElements())) { if (auto *CAZ = dyn_cast(Val)) return CAZ->getElementValue(CIdx->getZExtValue()); + if (Constant *SplatVal = Val->getSplatValue()) + return SplatVal; } return nullptr; } diff --git a/llvm/test/Transforms/InstSimplify/ConstProp/extractelement-vscale.ll b/llvm/test/Transforms/InstSimplify/ConstProp/extractelement-vscale.ll --- a/llvm/test/Transforms/InstSimplify/ConstProp/extractelement-vscale.ll +++ b/llvm/test/Transforms/InstSimplify/ConstProp/extractelement-vscale.ll @@ -1,4 +1,4 @@ -; RUN: opt -instcombine -S < %s | FileCheck %s +; RUN: opt -S -instsimplify < %s | FileCheck %s ; CHECK-LABEL: definitely_in_bounds ; CHECK: ret i8 0 @@ -11,3 +11,35 @@ define i8 @maybe_in_bounds() { ret i8 extractelement ( zeroinitializer, i64 16) } + +; Examples of extract a lane from a splat constant + +define i32 @extractconstant_shuffle_in_range(i32 %v) { +; CHECK-LABEL: @extractconstant_shuffle_in_range( +; CHECK-NEXT: ret i32 1024 +; + %in = insertelement undef, i32 1024, i32 0 + %splat = shufflevector %in, undef, zeroinitializer + %r = extractelement %splat, i32 1 + ret i32 %r +} + +define i32 @extractconstant_shuffle_maybe_out_of_range(i32 %v) { +; CHECK-LABEL: @extractconstant_shuffle_maybe_out_of_range( +; CHECK-NEXT: ret i32 extractelement ( shufflevector ( insertelement ( undef, i32 1024, i32 0), undef, zeroinitializer), i32 4) +; + %in = insertelement undef, i32 1024, i32 0 + %splat = shufflevector %in, undef, zeroinitializer + %r = extractelement %splat, i32 4 + ret i32 %r +} + +define i32 @extractconstant_shuffle_invalid_index(i32 %v) { +; CHECK-LABEL: @extractconstant_shuffle_invalid_index( +; CHECK-NEXT: ret i32 extractelement ( shufflevector ( insertelement ( undef, i32 1024, i32 0), undef, zeroinitializer), i32 -1) +; + %in = insertelement undef, i32 1024, i32 0 + %splat = shufflevector %in, undef, zeroinitializer + %r = extractelement %splat, i32 -1 + ret i32 %r +}