[InstSimplify] Simplify to vector constants when possible

InstSimplify should do all transformations that ConstProp does, but
one thing that ConstProp does that InstSimplify wouldn't is inline
vector instructions that are constants, e.g. into a ret.

Previously vector instructions wouldn't be inlined in InstSimplify
because llvm::Simplify*Instruction() would return nullptr for specific
instructions, such as vector instructions that were actually constants,
if it couldn't simplify them.

This changes SimplifyInsertElementInst, SimplifyExtractElementInst, and
SimplifyShuffleVectorInst to return a vector constant when possible.

Reviewed By: efriedma

Differential Revision: https://reviews.llvm.org/D85946
This commit is contained in:
Arthur Eubanks 2020-08-10 12:53:30 -07:00
parent 314a3e712c
commit 4c381d496d
3 changed files with 32 additions and 7 deletions

View File

@ -4302,7 +4302,7 @@ Value *llvm::SimplifyInsertElementInst(Value *Vec, Value *Val, Value *Idx,
auto *ValC = dyn_cast<Constant>(Val);
auto *IdxC = dyn_cast<Constant>(Idx);
if (VecC && ValC && IdxC)
return ConstantFoldInsertElementInstruction(VecC, ValC, IdxC);
return ConstantExpr::getInsertElement(VecC, ValC, IdxC);
// For fixed-length vector, fold into undef if index is out of bounds.
if (auto *CI = dyn_cast<ConstantInt>(Idx)) {
@ -4367,7 +4367,7 @@ static Value *SimplifyExtractElementInst(Value *Vec, Value *Idx,
auto *VecVTy = cast<VectorType>(Vec->getType());
if (auto *CVec = dyn_cast<Constant>(Vec)) {
if (auto *CIdx = dyn_cast<Constant>(Idx))
return ConstantFoldExtractElementInstruction(CVec, CIdx);
return ConstantExpr::getExtractElement(CVec, CIdx);
// The index is not relevant if our vector is a splat.
if (auto *Splat = CVec->getSplatValue())
@ -4565,8 +4565,8 @@ static Value *SimplifyShuffleVectorInst(Value *Op0, Value *Op1,
// If all operands are constant, constant fold the shuffle. This
// transformation depends on the value of the mask which is not known at
// compile time for scalable vectors
if (!Scalable && Op0Const && Op1Const)
return ConstantFoldShuffleVectorInstruction(Op0Const, Op1Const, Mask);
if (Op0Const && Op1Const)
return ConstantExpr::getShuffleVector(Op0Const, Op1Const, Mask);
// Canonicalization: if only one input vector is constant, it shall be the
// second one. This transformation depends on the value of the mask which

View File

@ -15,9 +15,7 @@ target triple = "aarch64"
; the compiler. It happens to be the case that this will be the result.
; CHECK-LABEL: define <vscale x 8 x i1> @vscale_version()
; CHECK-NEXT: %splatter = insertelement <vscale x 8 x i1> undef, i1 true, i32 0
; CHECK-NEXT: %foo = shufflevector <vscale x 8 x i1> %splatter, <vscale x 8 x i1> undef, <vscale x 8 x i32> zeroinitializer
; CHECK-NEXT: ret <vscale x 8 x i1> %foo
; CHECK-NEXT: ret <vscale x 8 x i1> shufflevector (<vscale x 8 x i1> insertelement (<vscale x 8 x i1> undef, i1 true, i32 0), <vscale x 8 x i1> undef, <vscale x 8 x i32> zeroinitializer)
define <vscale x 8 x i1> @vscale_version() {
%splatter = insertelement <vscale x 8 x i1> undef, i1 true, i32 0

View File

@ -51,6 +51,23 @@ define <vscale x 4 x i32> @insert_extract_element_same_vec_idx_1(<vscale x 4 x i
ret <vscale x 4 x i32> %r
}
define <vscale x 4 x i32> @insertelement_inline_to_ret() {
; CHECK-LABEL: @insertelement_inline_to_ret(
; CHECK-NEXT: ret <vscale x 4 x i32> insertelement (<vscale x 4 x i32> undef, i32 1, i32 0)
;
%i = insertelement <vscale x 4 x i32> undef, i32 1, i32 0
ret <vscale x 4 x i32> %i
}
define <vscale x 4 x i32> @insertelement_shufflevector_inline_to_ret() {
; CHECK-LABEL: @insertelement_shufflevector_inline_to_ret(
; CHECK-NEXT: ret <vscale x 4 x i32> shufflevector (<vscale x 4 x i32> insertelement (<vscale x 4 x i32> undef, i32 1, i32 0), <vscale x 4 x i32> undef, <vscale x 4 x i32> zeroinitializer)
;
%i = insertelement <vscale x 4 x i32> undef, i32 1, i32 0
%i2 = shufflevector <vscale x 4 x i32> %i, <vscale x 4 x i32> undef, <vscale x 4 x i32> zeroinitializer
ret <vscale x 4 x i32> %i2
}
; extractelement
define i32 @extractelement_idx_undef(<vscale x 4 x i32> %a) {
@ -120,6 +137,16 @@ define <vscale x 2 x i1> @cmp_le_smax_always_true(<vscale x 2 x i64> %x) {
ret <vscale x 2 x i1> %cmp
}
define <vscale x 4 x float> @bitcast() {
; CHECK-LABEL: @bitcast(
; CHECK-NEXT: ret <vscale x 4 x float> bitcast (<vscale x 4 x i32> shufflevector (<vscale x 4 x i32> insertelement (<vscale x 4 x i32> undef, i32 1, i32 0), <vscale x 4 x i32> undef, <vscale x 4 x i32> zeroinitializer) to <vscale x 4 x float>)
;
%i1 = insertelement <vscale x 4 x i32> undef, i32 1, i32 0
%i2 = shufflevector <vscale x 4 x i32> %i1, <vscale x 4 x i32> undef, <vscale x 4 x i32> zeroinitializer
%i3 = bitcast <vscale x 4 x i32> %i2 to <vscale x 4 x float>
ret <vscale x 4 x float> %i3
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Memory Access and Addressing Operations
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;