diff --git a/llvm/lib/Transforms/Scalar/Scalarizer.cpp b/llvm/lib/Transforms/Scalar/Scalarizer.cpp --- a/llvm/lib/Transforms/Scalar/Scalarizer.cpp +++ b/llvm/lib/Transforms/Scalar/Scalarizer.cpp @@ -778,9 +778,6 @@ } bool ScalarizerVisitor::visitExtractElementInst(ExtractElementInst &EEI) { - if (!ScalarizeVariableInsertExtract) - return false; - VectorType *VT = dyn_cast(EEI.getOperand(0)->getType()); if (!VT) return false; @@ -789,7 +786,14 @@ IRBuilder<> Builder(&EEI); Scatterer Op0 = scatter(&EEI, EEI.getOperand(0)); Value *ExtIdx = EEI.getOperand(1); - if (isa(ExtIdx)) + + if (auto *CI = dyn_cast(ExtIdx)) { + Value *Res = Op0[CI->getValue().getZExtValue()]; + gather(&EEI, {Res}); + return true; + } + + if (!ScalarizeVariableInsertExtract) return false; Value *Res = UndefValue::get(VT->getElementType()); diff --git a/llvm/test/Transforms/Scalarizer/basic.ll b/llvm/test/Transforms/Scalarizer/basic.ll --- a/llvm/test/Transforms/Scalarizer/basic.ll +++ b/llvm/test/Transforms/Scalarizer/basic.ll @@ -607,6 +607,20 @@ ret i32 %val2 } +; Test that constant extracts are nicely scalarized +define i32 @f24(<4 x i32> *%src, i32 %index) { +; CHECK-LABEL: @f24( +; CHECK: %src.i0 = bitcast <4 x i32>* %src to i32* +; CHECK: %src.i3 = getelementptr i32, i32* %src.i0, i32 3 +; CHECK: %val0.i3 = load i32, i32* %src.i3, align 4 +; CHECK: %val2 = shl i32 4, %val0.i3 +; CHECK: ret i32 %val2 + %val0 = load <4 x i32> , <4 x i32> *%src + %val1 = shl <4 x i32> , %val0 + %val2 = extractelement <4 x i32> %val1, i32 3 + ret i32 %val2 +} + !0 = !{ !"root" } !1 = !{ !"set1", !0 } !2 = !{ !"set2", !0 } diff --git a/llvm/test/Transforms/Scalarizer/phi-unreachable-pred.ll b/llvm/test/Transforms/Scalarizer/phi-unreachable-pred.ll --- a/llvm/test/Transforms/Scalarizer/phi-unreachable-pred.ll +++ b/llvm/test/Transforms/Scalarizer/phi-unreachable-pred.ll @@ -15,12 +15,7 @@ ; CHECK-NEXT: [[PHI_I1:%.*]] = phi i16 [ 1, [[ENTRY]] ], [ undef, [[FOR_COND]] ] ; CHECK-NEXT: [[PHI_I2:%.*]] = phi i16 [ 1, [[ENTRY]] ], [ undef, [[FOR_COND]] ] ; CHECK-NEXT: [[PHI_I3:%.*]] = phi i16 [ 1, [[ENTRY]] ], [ undef, [[FOR_COND]] ] -; CHECK-NEXT: [[PHI_UPTO0:%.*]] = insertelement <4 x i16> undef, i16 [[PHI_I0]], i32 0 -; CHECK-NEXT: [[PHI_UPTO1:%.*]] = insertelement <4 x i16> [[PHI_UPTO0]], i16 [[PHI_I1]], i32 1 -; CHECK-NEXT: [[PHI_UPTO2:%.*]] = insertelement <4 x i16> [[PHI_UPTO1]], i16 [[PHI_I2]], i32 2 -; CHECK-NEXT: [[PHI:%.*]] = insertelement <4 x i16> [[PHI_UPTO2]], i16 [[PHI_I3]], i32 3 -; CHECK-NEXT: [[EXTRACT:%.*]] = extractelement <4 x i16> [[PHI]], i32 0 -; CHECK-NEXT: ret i16 [[EXTRACT]] +; CHECK-NEXT: ret i16 [[PHI_I0]] ; entry: br label %for.end