diff --git a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp index 40acc2423a246e..9bb12cbd94f0b4 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp @@ -474,6 +474,11 @@ Instruction *InstCombinerImpl::visitExtractElementInst(ExtractElementInst &EI) { if (auto *I = dyn_cast(SrcVec)) { if (auto *IE = dyn_cast(I)) { + // If the possibly-variable indices are trivially known to be equal + // (because they are the same operand) then use the value that was + // inserted directly. + if (IE->getOperand(2) == Index) + return replaceInstUsesWith(EI, IE->getOperand(1)); // instsimplify already handled the case where the indices are constants // and equal by value, if both are constants, they must not be the same // value, extract from the pre-inserted value instead. diff --git a/llvm/test/Transforms/InstCombine/vector-inseltextelt.ll b/llvm/test/Transforms/InstCombine/vector-inseltextelt.ll new file mode 100644 index 00000000000000..b0a6a4e2544154 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/vector-inseltextelt.ll @@ -0,0 +1,23 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt < %s -passes=instcombine -S | FileCheck %s + +; extracting a just-inserted element should yield the original value +define float @constant_index(<4 x float> %x, float %val) { +; CHECK-LABEL: @constant_index( +; CHECK-NEXT: ret float [[VAL:%.*]] +; + %ins = insertelement <4 x float> %x, float %val, i32 1 + %ext = extractelement <4 x float> %ins, i32 1 + ret float %ext +} + +; extracting a just-inserted element should yield the original value even if +; the index is dynamic +define float @dynamic_index(<4 x float> %x, float %val, i32 %idx) { +; CHECK-LABEL: @dynamic_index( +; CHECK-NEXT: ret float [[VAL:%.*]] +; + %ins = insertelement <4 x float> %x, float %val, i32 %idx + %ext = extractelement <4 x float> %ins, i32 %idx + ret float %ext +}