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 @@ -833,6 +833,12 @@ ConstantInt *CIdx = dyn_cast(Idx); if (!CIdx) return nullptr; + // Should not iterate over scalable vector, as num element is known at + // runtime. + VectorType *ValTy = cast(Val->getType()); + if (ValTy->isScalable()) + return nullptr; + unsigned NumElts = Val->getType()->getVectorNumElements(); if (CIdx->uge(NumElts)) return UndefValue::get(Val->getType()); diff --git a/llvm/test/Transforms/InstCombine/insertelement.ll b/llvm/test/Transforms/InstCombine/insertelement.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/insertelement.ll @@ -0,0 +1,73 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt < %s -instcombine -S | FileCheck %s + + +define <4 x i32> @insertelement_fixedlength_constant() { +; CHECK-LABEL: @insertelement_fixedlength_constant( +; CHECK-NEXT: ret <4 x i32> +; + %i = insertelement <4 x i32> undef, i32 1, i32 0 + ret <4 x i32> %i +} + +define <4 x i32> @insertelement_fixedlength_val1(<4 x i32> %val) { +; CHECK-LABEL: @insertelement_fixedlength_val1( +; CHECK-NEXT: [[I:%.*]] = insertelement <4 x i32> [[VAL:%.*]], i32 1, i32 0 +; CHECK-NEXT: ret <4 x i32> [[I]] +; + %i = insertelement <4 x i32> %val, i32 1, i32 0 + ret <4 x i32> %i +} + +define <4 x i32> @insertelement_fixedlength_val2(i32 %val) { +; CHECK-LABEL: @insertelement_fixedlength_val2( +; CHECK-NEXT: [[I:%.*]] = insertelement <4 x i32> undef, i32 [[VAL:%.*]], i32 0 +; CHECK-NEXT: ret <4 x i32> [[I]] +; + %i = insertelement <4 x i32> undef, i32 %val, i32 0 + ret <4 x i32> %i +} + +define <4 x i32> @insertelement_fixedlength_val3(i32 %val) { +; CHECK-LABEL: @insertelement_fixedlength_val3( +; CHECK-NEXT: [[I:%.*]] = insertelement <4 x i32> undef, i32 1, i32 [[VAL:%.*]] +; CHECK-NEXT: ret <4 x i32> [[I]] +; + %i = insertelement <4 x i32> undef, i32 1, i32 %val + ret <4 x i32> %i +} + +define @insertelement_scalable_constant() { +; CHECK-LABEL: @insertelement_scalable_constant( +; CHECK-NEXT: ret insertelement ( undef, i32 1, i32 0) +; + %i = insertelement undef, i32 1, i32 0 + ret %i +} + +define @insertelement_scalable_val1( %val) { +; CHECK-LABEL: @insertelement_scalable_val1( +; CHECK-NEXT: [[I:%.*]] = insertelement [[VAL:%.*]], i32 1, i32 0 +; CHECK-NEXT: ret [[I]] +; + %i = insertelement %val, i32 1, i32 0 + ret %i +} + +define @insertelement_scalable_val2(i32 %val) { +; CHECK-LABEL: @insertelement_scalable_val2( +; CHECK-NEXT: [[I:%.*]] = insertelement undef, i32 [[VAL:%.*]], i32 0 +; CHECK-NEXT: ret [[I]] +; + %i = insertelement undef, i32 %val, i32 0 + ret %i +} + +define @insertelement_scalable_val3(i32 %val) { +; CHECK-LABEL: @insertelement_scalable_val3( +; CHECK-NEXT: [[I:%.*]] = insertelement undef, i32 1, i32 [[VAL:%.*]] +; CHECK-NEXT: ret [[I]] +; + %i = insertelement undef, i32 1, i32 %val + ret %i +}