From 4872ecf1cc3cb9c4939a9e6210a9b9e9a9032e9f Mon Sep 17 00:00:00 2001 From: Paul Walker Date: Thu, 21 Nov 2024 12:39:53 +0000 Subject: [PATCH] [LLVM][IR] Teach extractelement folds about constant ConstantInt/FP. (#116793) --- llvm/lib/IR/Constants.cpp | 4 ++++ llvm/lib/IR/Instructions.cpp | 12 ++++++++++-- llvm/test/Transforms/InstCombine/extractelement.ll | 5 +++++ llvm/test/Transforms/InstSimplify/extract-element.ll | 1 + 4 files changed, 20 insertions(+), 2 deletions(-) diff --git a/llvm/lib/IR/Constants.cpp b/llvm/lib/IR/Constants.cpp index 3d6c4ad780dc24..95832ed0b8951a 100644 --- a/llvm/lib/IR/Constants.cpp +++ b/llvm/lib/IR/Constants.cpp @@ -1699,6 +1699,10 @@ Constant *Constant::getSplatValue(bool AllowPoison) const { assert(this->getType()->isVectorTy() && "Only valid for vectors!"); if (isa(this)) return getNullValue(cast(getType())->getElementType()); + if (auto *CI = dyn_cast(this)) + return ConstantInt::get(getContext(), CI->getValue()); + if (auto *CFP = dyn_cast(this)) + return ConstantFP::get(getContext(), CFP->getValue()); if (const ConstantDataVector *CV = dyn_cast(this)) return CV->getSplatValue(); if (const ConstantVector *CV = dyn_cast(this)) diff --git a/llvm/lib/IR/Instructions.cpp b/llvm/lib/IR/Instructions.cpp index 7350c65b35fb71..065ce3a0172837 100644 --- a/llvm/lib/IR/Instructions.cpp +++ b/llvm/lib/IR/Instructions.cpp @@ -1752,8 +1752,17 @@ bool ShuffleVectorInst::isValidOperands(const Value *V1, const Value *V2, if (isa(Mask) || isa(Mask)) return true; + // NOTE: Through vector ConstantInt we have the potential to support more + // than just zero splat masks but that requires a LangRef change. + if (isa(MaskTy)) + return false; + + unsigned V1Size = cast(V1->getType())->getNumElements(); + + if (const auto *CI = dyn_cast(Mask)) + return !CI->uge(V1Size * 2); + if (const auto *MV = dyn_cast(Mask)) { - unsigned V1Size = cast(V1->getType())->getNumElements(); for (Value *Op : MV->operands()) { if (auto *CI = dyn_cast(Op)) { if (CI->uge(V1Size*2)) @@ -1766,7 +1775,6 @@ bool ShuffleVectorInst::isValidOperands(const Value *V1, const Value *V2, } if (const auto *CDS = dyn_cast(Mask)) { - unsigned V1Size = cast(V1->getType())->getNumElements(); for (unsigned i = 0, e = cast(MaskTy)->getNumElements(); i != e; ++i) if (CDS->getElementAsInteger(i) >= V1Size*2) diff --git a/llvm/test/Transforms/InstCombine/extractelement.ll b/llvm/test/Transforms/InstCombine/extractelement.ll index 2bd719e2361379..04a35e19fb0bb5 100644 --- a/llvm/test/Transforms/InstCombine/extractelement.ll +++ b/llvm/test/Transforms/InstCombine/extractelement.ll @@ -4,6 +4,11 @@ ; RUN: opt < %s -passes=instcombine -S -data-layout="E-n64" | FileCheck %s --check-prefixes=ANY,ANYBE,BE64 ; RUN: opt < %s -passes=instcombine -S -data-layout="E-n128" | FileCheck %s --check-prefixes=ANY,ANYBE,BE128 +; RUN: opt < %s -passes=instcombine -S -data-layout="e-n64" -use-constant-fp-for-fixed-length-splat -use-constant-int-for-fixed-length-splat | FileCheck %s --check-prefixes=ANY,ANYLE,LE64 +; RUN: opt < %s -passes=instcombine -S -data-layout="e-n128" -use-constant-fp-for-fixed-length-splat -use-constant-int-for-fixed-length-splat | FileCheck %s --check-prefixes=ANY,ANYLE,LE128 +; RUN: opt < %s -passes=instcombine -S -data-layout="E-n64" -use-constant-fp-for-fixed-length-splat -use-constant-int-for-fixed-length-splat | FileCheck %s --check-prefixes=ANY,ANYBE,BE64 +; RUN: opt < %s -passes=instcombine -S -data-layout="E-n128" -use-constant-fp-for-fixed-length-splat -use-constant-int-for-fixed-length-splat | FileCheck %s --check-prefixes=ANY,ANYBE,BE128 + define i32 @extractelement_out_of_range(<2 x i32> %x) { ; ANY-LABEL: @extractelement_out_of_range( ; ANY-NEXT: ret i32 poison diff --git a/llvm/test/Transforms/InstSimplify/extract-element.ll b/llvm/test/Transforms/InstSimplify/extract-element.ll index 3060586b25a791..7d30805f4fdc71 100644 --- a/llvm/test/Transforms/InstSimplify/extract-element.ll +++ b/llvm/test/Transforms/InstSimplify/extract-element.ll @@ -1,5 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt < %s -passes=instsimplify -S | FileCheck %s +; RUN: opt < %s -passes=instsimplify -use-constant-fp-for-fixed-length-splat -use-constant-int-for-fixed-length-splat -S | FileCheck %s ; Weird Types