9 changes: 9 additions & 0 deletions llvm/include/llvm/Transforms/Utils/LoopUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,15 @@ RecurKind getMinMaxReductionRecurKind(Intrinsic::ID RdxID);
/// Returns the comparison predicate used when expanding a min/max reduction.
CmpInst::Predicate getMinMaxReductionPredicate(RecurKind RK);

/// See RecurrenceDescriptor::isAnyOfPattern for a description of the pattern we
/// are trying to match. In this pattern, we are only ever selecting between two
/// values: 1) an initial start value \p StartVal of the reduction PHI, and 2) a
/// loop invariant value. If any of lane value in \p Left, \p Right is not equal
/// to \p StartVal, select the loop invariant value. This is done by selecting
/// \p Right iff \p Left is equal to \p StartVal.
Value *createAnyOfOp(IRBuilderBase &Builder, Value *StartVal, RecurKind RK,
Value *Left, Value *Right);

/// Returns a Min/Max operation corresponding to MinMaxRecurrenceKind.
/// The Builder's fast-math-flags must be set to propagate the expected values.
Value *createMinMaxOp(IRBuilderBase &Builder, RecurKind RK, Value *Left,
Expand Down
13 changes: 13 additions & 0 deletions llvm/lib/Analysis/ValueTracking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5032,6 +5032,19 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,

break;
}
case Intrinsic::vector_reduce_fmax:
case Intrinsic::vector_reduce_fmin:
case Intrinsic::vector_reduce_fmaximum:
case Intrinsic::vector_reduce_fminimum: {
// reduce min/max will choose an element from one of the vector elements,
// so we can infer and class information that is common to all elements.
Known = computeKnownFPClass(II->getArgOperand(0), II->getFastMathFlags(),
InterestedClasses, Depth + 1, Q);
// Can only propagate sign if output is never NaN.
if (!Known.isKnownNeverNaN())
Known.SignBit.reset();
break;
}
case Intrinsic::trunc:
case Intrinsic::floor:
case Intrinsic::ceil:
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/MC/MCPseudoProbe.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,7 @@ template <typename T> ErrorOr<T> MCPseudoProbeDecoder::readUnencodedNumber() {
if (Data + sizeof(T) > End) {
return std::error_code();
}
T Val = endian::readNext<T, llvm::endianness::little, unaligned>(Data);
T Val = endian::readNext<T, llvm::endianness::little>(Data);
return ErrorOr<T>(Val);
}

Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/ProfileData/InstrProf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1135,9 +1135,9 @@ static T swapToHostOrder(const unsigned char *&D, llvm::endianness Orig) {
using namespace support;

if (Orig == llvm::endianness::little)
return endian::readNext<T, llvm::endianness::little, unaligned>(D);
return endian::readNext<T, llvm::endianness::little>(D);
else
return endian::readNext<T, llvm::endianness::big, unaligned>(D);
return endian::readNext<T, llvm::endianness::big>(D);
}

static std::unique_ptr<ValueProfData> allocValueProfData(uint32_t TotalSize) {
Expand Down
53 changes: 19 additions & 34 deletions llvm/lib/ProfileData/InstrProfReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,10 +115,9 @@ readBinaryIdsInternal(const MemoryBuffer &DataBuffer,

uint64_t BILen = 0;
if (Endian == llvm::endianness::little)
BILen =
endian::readNext<uint64_t, llvm::endianness::little, unaligned>(BI);
BILen = endian::readNext<uint64_t, llvm::endianness::little>(BI);
else
BILen = endian::readNext<uint64_t, llvm::endianness::big, unaligned>(BI);
BILen = endian::readNext<uint64_t, llvm::endianness::big>(BI);

if (BILen == 0)
return make_error<InstrProfError>(instrprof_error::malformed,
Expand Down Expand Up @@ -923,17 +922,15 @@ data_type InstrProfLookupTrait::ReadData(StringRef K, const unsigned char *D,
// Read hash.
if (D + sizeof(uint64_t) >= End)
return data_type();
uint64_t Hash =
endian::readNext<uint64_t, llvm::endianness::little, unaligned>(D);
uint64_t Hash = endian::readNext<uint64_t, llvm::endianness::little>(D);

// Initialize number of counters for GET_VERSION(FormatVersion) == 1.
uint64_t CountsSize = N / sizeof(uint64_t) - 1;
// If format version is different then read the number of counters.
if (GET_VERSION(FormatVersion) != IndexedInstrProf::ProfVersion::Version1) {
if (D + sizeof(uint64_t) > End)
return data_type();
CountsSize =
endian::readNext<uint64_t, llvm::endianness::little, unaligned>(D);
CountsSize = endian::readNext<uint64_t, llvm::endianness::little>(D);
}
// Read counter values.
if (D + CountsSize * sizeof(uint64_t) > End)
Expand All @@ -943,24 +940,22 @@ data_type InstrProfLookupTrait::ReadData(StringRef K, const unsigned char *D,
CounterBuffer.reserve(CountsSize);
for (uint64_t J = 0; J < CountsSize; ++J)
CounterBuffer.push_back(
endian::readNext<uint64_t, llvm::endianness::little, unaligned>(D));
endian::readNext<uint64_t, llvm::endianness::little>(D));

// Read bitmap bytes for GET_VERSION(FormatVersion) > 10.
if (GET_VERSION(FormatVersion) > IndexedInstrProf::ProfVersion::Version10) {
uint64_t BitmapBytes = 0;
if (D + sizeof(uint64_t) > End)
return data_type();
BitmapBytes =
endian::readNext<uint64_t, llvm::endianness::little, unaligned>(D);
BitmapBytes = endian::readNext<uint64_t, llvm::endianness::little>(D);
// Read bitmap byte values.
if (D + BitmapBytes * sizeof(uint8_t) > End)
return data_type();
BitmapByteBuffer.clear();
BitmapByteBuffer.reserve(BitmapBytes);
for (uint64_t J = 0; J < BitmapBytes; ++J)
BitmapByteBuffer.push_back(static_cast<uint8_t>(
endian::readNext<uint64_t, llvm::endianness::little, unaligned>(
D)));
endian::readNext<uint64_t, llvm::endianness::little>(D)));
}

DataBuffer.emplace_back(K, Hash, std::move(CounterBuffer),
Expand Down Expand Up @@ -1256,8 +1251,7 @@ Error IndexedInstrProfReader::readHeader() {
// memprof::MemProfVersion0 or the MemProf version number in
// memprof::MemProfVersion1.
const uint64_t FirstWord =
support::endian::readNext<uint64_t, llvm::endianness::little,
unaligned>(Ptr);
support::endian::readNext<uint64_t, llvm::endianness::little>(Ptr);

memprof::IndexedVersion Version = memprof::Version0;
if (FirstWord == memprof::Version1) {
Expand All @@ -1282,17 +1276,15 @@ Error IndexedInstrProfReader::readHeader() {
const uint64_t RecordTableOffset =
Version == memprof::Version0
? FirstWord
: support::endian::readNext<uint64_t, llvm::endianness::little,
unaligned>(Ptr);
: support::endian::readNext<uint64_t, llvm::endianness::little>(
Ptr);
// The offset in the stream right before invoking
// FrameTableGenerator.Emit.
const uint64_t FramePayloadOffset =
support::endian::readNext<uint64_t, llvm::endianness::little,
unaligned>(Ptr);
support::endian::readNext<uint64_t, llvm::endianness::little>(Ptr);
// The value returned from FrameTableGenerator.Emit.
const uint64_t FrameTableOffset =
support::endian::readNext<uint64_t, llvm::endianness::little,
unaligned>(Ptr);
support::endian::readNext<uint64_t, llvm::endianness::little>(Ptr);

// Read the schema.
auto SchemaOr = memprof::readMemProfSchema(Ptr);
Expand Down Expand Up @@ -1330,8 +1322,7 @@ Error IndexedInstrProfReader::readHeader() {
const unsigned char *Ptr = Start + BinaryIdOffset;
// Read binary ids size.
BinaryIdsSize =
support::endian::readNext<uint64_t, llvm::endianness::little,
unaligned>(Ptr);
support::endian::readNext<uint64_t, llvm::endianness::little>(Ptr);
if (BinaryIdsSize % sizeof(uint64_t))
return error(instrprof_error::bad_header);
// Set the binary ids start.
Expand All @@ -1348,8 +1339,7 @@ Error IndexedInstrProfReader::readHeader() {
const unsigned char *Ptr = Start + VTableNamesOffset;

CompressedVTableNamesLen =
support::endian::readNext<uint64_t, llvm::endianness::little,
unaligned>(Ptr);
support::endian::readNext<uint64_t, llvm::endianness::little>(Ptr);

// Writer first writes the length of compressed string, and then the actual
// content.
Expand All @@ -1369,29 +1359,24 @@ Error IndexedInstrProfReader::readHeader() {
if (Ptr + 2 * sizeof(uint64_t) > PtrEnd)
return error(instrprof_error::truncated);
const uint64_t NumTraces =
support::endian::readNext<uint64_t, llvm::endianness::little,
unaligned>(Ptr);
support::endian::readNext<uint64_t, llvm::endianness::little>(Ptr);
TemporalProfTraceStreamSize =
support::endian::readNext<uint64_t, llvm::endianness::little,
unaligned>(Ptr);
support::endian::readNext<uint64_t, llvm::endianness::little>(Ptr);
for (unsigned i = 0; i < NumTraces; i++) {
// Expect at least two 64 bit fields: Weight and NumFunctions
if (Ptr + 2 * sizeof(uint64_t) > PtrEnd)
return error(instrprof_error::truncated);
TemporalProfTraceTy Trace;
Trace.Weight =
support::endian::readNext<uint64_t, llvm::endianness::little,
unaligned>(Ptr);
support::endian::readNext<uint64_t, llvm::endianness::little>(Ptr);
const uint64_t NumFunctions =
support::endian::readNext<uint64_t, llvm::endianness::little,
unaligned>(Ptr);
support::endian::readNext<uint64_t, llvm::endianness::little>(Ptr);
// Expect at least NumFunctions 64 bit fields
if (Ptr + NumFunctions * sizeof(uint64_t) > PtrEnd)
return error(instrprof_error::truncated);
for (unsigned j = 0; j < NumFunctions; j++) {
const uint64_t NameRef =
support::endian::readNext<uint64_t, llvm::endianness::little,
unaligned>(Ptr);
support::endian::readNext<uint64_t, llvm::endianness::little>(Ptr);
Trace.FunctionNameRefs.push_back(NameRef);
}
TemporalProfTraces.push_back(std::move(Trace));
Expand Down
25 changes: 12 additions & 13 deletions llvm/lib/ProfileData/MemProf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,14 +144,14 @@ static IndexedMemProfRecord deserializeV0(const MemProfSchema &Schema,

// Read the meminfo nodes.
const uint64_t NumNodes =
endian::readNext<uint64_t, llvm::endianness::little, unaligned>(Ptr);
endian::readNext<uint64_t, llvm::endianness::little>(Ptr);
for (uint64_t I = 0; I < NumNodes; I++) {
IndexedAllocationInfo Node;
const uint64_t NumFrames =
endian::readNext<uint64_t, llvm::endianness::little, unaligned>(Ptr);
endian::readNext<uint64_t, llvm::endianness::little>(Ptr);
for (uint64_t J = 0; J < NumFrames; J++) {
const FrameId Id =
endian::readNext<FrameId, llvm::endianness::little, unaligned>(Ptr);
endian::readNext<FrameId, llvm::endianness::little>(Ptr);
Node.CallStack.push_back(Id);
}
Node.CSId = hashCallStack(Node.CallStack);
Expand All @@ -162,15 +162,15 @@ static IndexedMemProfRecord deserializeV0(const MemProfSchema &Schema,

// Read the callsite information.
const uint64_t NumCtxs =
endian::readNext<uint64_t, llvm::endianness::little, unaligned>(Ptr);
endian::readNext<uint64_t, llvm::endianness::little>(Ptr);
for (uint64_t J = 0; J < NumCtxs; J++) {
const uint64_t NumFrames =
endian::readNext<uint64_t, llvm::endianness::little, unaligned>(Ptr);
endian::readNext<uint64_t, llvm::endianness::little>(Ptr);
llvm::SmallVector<FrameId> Frames;
Frames.reserve(NumFrames);
for (uint64_t K = 0; K < NumFrames; K++) {
const FrameId Id =
endian::readNext<FrameId, llvm::endianness::little, unaligned>(Ptr);
endian::readNext<FrameId, llvm::endianness::little>(Ptr);
Frames.push_back(Id);
}
Record.CallSites.push_back(Frames);
Expand All @@ -188,22 +188,21 @@ static IndexedMemProfRecord deserializeV2(const MemProfSchema &Schema,

// Read the meminfo nodes.
const uint64_t NumNodes =
endian::readNext<uint64_t, llvm::endianness::little, unaligned>(Ptr);
endian::readNext<uint64_t, llvm::endianness::little>(Ptr);
for (uint64_t I = 0; I < NumNodes; I++) {
IndexedAllocationInfo Node;
Node.CSId =
endian::readNext<CallStackId, llvm::endianness::little, unaligned>(Ptr);
Node.CSId = endian::readNext<CallStackId, llvm::endianness::little>(Ptr);
Node.Info.deserialize(Schema, Ptr);
Ptr += PortableMemInfoBlock::serializedSize();
Record.AllocSites.push_back(Node);
}

// Read the callsite information.
const uint64_t NumCtxs =
endian::readNext<uint64_t, llvm::endianness::little, unaligned>(Ptr);
endian::readNext<uint64_t, llvm::endianness::little>(Ptr);
for (uint64_t J = 0; J < NumCtxs; J++) {
CallStackId CSId =
endian::readNext<CallStackId, llvm::endianness::little, unaligned>(Ptr);
endian::readNext<CallStackId, llvm::endianness::little>(Ptr);
Record.CallSiteIds.push_back(CSId);
}

Expand Down Expand Up @@ -263,7 +262,7 @@ Expected<MemProfSchema> readMemProfSchema(const unsigned char *&Buffer) {

const unsigned char *Ptr = Buffer;
const uint64_t NumSchemaIds =
endian::readNext<uint64_t, llvm::endianness::little, unaligned>(Ptr);
endian::readNext<uint64_t, llvm::endianness::little>(Ptr);
if (NumSchemaIds > static_cast<uint64_t>(Meta::Size)) {
return make_error<InstrProfError>(instrprof_error::malformed,
"memprof schema invalid");
Expand All @@ -272,7 +271,7 @@ Expected<MemProfSchema> readMemProfSchema(const unsigned char *&Buffer) {
MemProfSchema Result;
for (size_t I = 0; I < NumSchemaIds; I++) {
const uint64_t Tag =
endian::readNext<uint64_t, llvm::endianness::little, unaligned>(Ptr);
endian::readNext<uint64_t, llvm::endianness::little>(Ptr);
if (Tag >= static_cast<uint64_t>(Meta::Size)) {
return make_error<InstrProfError>(instrprof_error::malformed,
"memprof schema invalid");
Expand Down
14 changes: 7 additions & 7 deletions llvm/lib/ProfileData/MemProfReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ llvm::SmallVector<SegmentEntry> readSegmentEntries(const char *Ptr) {
using namespace support;

const uint64_t NumItemsToRead =
endian::readNext<uint64_t, llvm::endianness::little, unaligned>(Ptr);
endian::readNext<uint64_t, llvm::endianness::little>(Ptr);
llvm::SmallVector<SegmentEntry> Items;
for (uint64_t I = 0; I < NumItemsToRead; I++) {
Items.push_back(*reinterpret_cast<const SegmentEntry *>(
Expand All @@ -100,11 +100,11 @@ readMemInfoBlocks(const char *Ptr) {
using namespace support;

const uint64_t NumItemsToRead =
endian::readNext<uint64_t, llvm::endianness::little, unaligned>(Ptr);
endian::readNext<uint64_t, llvm::endianness::little>(Ptr);
llvm::SmallVector<std::pair<uint64_t, MemInfoBlock>> Items;
for (uint64_t I = 0; I < NumItemsToRead; I++) {
const uint64_t Id =
endian::readNext<uint64_t, llvm::endianness::little, unaligned>(Ptr);
endian::readNext<uint64_t, llvm::endianness::little>(Ptr);
const MemInfoBlock MIB = *reinterpret_cast<const MemInfoBlock *>(Ptr);
Items.push_back({Id, MIB});
// Only increment by size of MIB since readNext implicitly increments.
Expand All @@ -117,20 +117,20 @@ CallStackMap readStackInfo(const char *Ptr) {
using namespace support;

const uint64_t NumItemsToRead =
endian::readNext<uint64_t, llvm::endianness::little, unaligned>(Ptr);
endian::readNext<uint64_t, llvm::endianness::little>(Ptr);
CallStackMap Items;

for (uint64_t I = 0; I < NumItemsToRead; I++) {
const uint64_t StackId =
endian::readNext<uint64_t, llvm::endianness::little, unaligned>(Ptr);
endian::readNext<uint64_t, llvm::endianness::little>(Ptr);
const uint64_t NumPCs =
endian::readNext<uint64_t, llvm::endianness::little, unaligned>(Ptr);
endian::readNext<uint64_t, llvm::endianness::little>(Ptr);

SmallVector<uint64_t> CallStack;
CallStack.reserve(NumPCs);
for (uint64_t J = 0; J < NumPCs; J++) {
CallStack.push_back(
endian::readNext<uint64_t, llvm::endianness::little, unaligned>(Ptr));
endian::readNext<uint64_t, llvm::endianness::little>(Ptr));
}

Items[StackId] = CallStack;
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/ProfileData/SampleProfReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -503,7 +503,7 @@ ErrorOr<T> SampleProfileReaderBinary::readUnencodedNumber() {
}

using namespace support;
T Val = endian::readNext<T, llvm::endianness::little, unaligned>(Data);
T Val = endian::readNext<T, llvm::endianness::little>(Data);
return Val;
}

Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/RISCV/RISCVISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13408,7 +13408,7 @@ static SDValue expandMul(SDNode *N, SelectionDAG &DAG,
if (VT != Subtarget.getXLenVT())
return SDValue();

if (!Subtarget.hasStdExtZba())
if (!Subtarget.hasStdExtZba() && !Subtarget.hasVendorXTHeadBa())
return SDValue();

ConstantSDNode *CNode = dyn_cast<ConstantSDNode>(N->getOperand(1));
Expand Down
26 changes: 20 additions & 6 deletions llvm/lib/Target/TargetMachine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ bool TargetMachine::isLargeGlobalValue(const GlobalValue *GVal) const {
if (getTargetTriple().getArch() != Triple::x86_64)
return false;

// Remaining logic below is ELF-specific. For other object file formats where
// the large code model is mostly used for JIT compilation, just look at the
// code model.
if (!getTargetTriple().isOSBinFormatELF())
return getCodeModel() == CodeModel::Large;

auto *GO = GVal->getAliaseeObject();

// Be conservative if we can't find an underlying GlobalObject.
Expand All @@ -51,9 +57,20 @@ bool TargetMachine::isLargeGlobalValue(const GlobalValue *GVal) const {

auto *GV = dyn_cast<GlobalVariable>(GO);

auto IsPrefix = [](StringRef Name, StringRef Prefix) {
return Name.consume_front(Prefix) && (Name.empty() || Name[0] == '.');
};

// Functions/GlobalIFuncs are only large under the large code model.
if (!GV)
if (!GV) {
// Handle explicit sections as we do for GlobalVariables with an explicit
// section, see comments below.
if (GO->hasSection()) {
StringRef Name = GO->getSection();
return IsPrefix(Name, ".ltext");
}
return getCodeModel() == CodeModel::Large;
}

if (GV->isThreadLocal())
return false;
Expand All @@ -73,11 +90,8 @@ bool TargetMachine::isLargeGlobalValue(const GlobalValue *GVal) const {
// data sections. The code model attribute overrides this above.
if (GV->hasSection()) {
StringRef Name = GV->getSection();
auto IsPrefix = [&](StringRef Prefix) {
StringRef S = Name;
return S.consume_front(Prefix) && (S.empty() || S[0] == '.');
};
return IsPrefix(".lbss") || IsPrefix(".ldata") || IsPrefix(".lrodata");
return IsPrefix(Name, ".lbss") || IsPrefix(Name, ".ldata") ||
IsPrefix(Name, ".lrodata");
}

// Respect large data threshold for medium and large code models.
Expand Down
18 changes: 16 additions & 2 deletions llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1977,11 +1977,25 @@ Instruction *InstCombinerImpl::visitFPToSI(FPToSIInst &FI) {
}

Instruction *InstCombinerImpl::visitUIToFP(CastInst &CI) {
return commonCastTransforms(CI);
if (Instruction *R = commonCastTransforms(CI))
return R;
if (!CI.hasNonNeg() && isKnownNonNegative(CI.getOperand(0), SQ)) {
CI.setNonNeg();
return &CI;
}
return nullptr;
}

Instruction *InstCombinerImpl::visitSIToFP(CastInst &CI) {
return commonCastTransforms(CI);
if (Instruction *R = commonCastTransforms(CI))
return R;
if (isKnownNonNegative(CI.getOperand(0), SQ)) {
auto UI =
CastInst::Create(Instruction::UIToFP, CI.getOperand(0), CI.getType());
UI->setNonNeg(true);
return UI;
}
return nullptr;
}

Instruction *InstCombinerImpl::visitIntToPtr(IntToPtrInst &CI) {
Expand Down
24 changes: 18 additions & 6 deletions llvm/lib/Transforms/Utils/LoopUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1034,6 +1034,15 @@ CmpInst::Predicate llvm::getMinMaxReductionPredicate(RecurKind RK) {
}
}

Value *llvm::createAnyOfOp(IRBuilderBase &Builder, Value *StartVal,
RecurKind RK, Value *Left, Value *Right) {
if (auto VTy = dyn_cast<VectorType>(Left->getType()))
StartVal = Builder.CreateVectorSplat(VTy->getElementCount(), StartVal);
Value *Cmp =
Builder.CreateCmp(CmpInst::ICMP_NE, Left, StartVal, "rdx.select.cmp");
return Builder.CreateSelect(Cmp, Left, Right, "rdx.select");
}

Value *llvm::createMinMaxOp(IRBuilderBase &Builder, RecurKind RK, Value *Left,
Value *Right) {
Type *Ty = Left->getType();
Expand Down Expand Up @@ -1142,13 +1151,16 @@ Value *llvm::createAnyOfTargetReduction(IRBuilderBase &Builder, Value *Src,
NewVal = SI->getTrueValue();
}

// Create a splat vector with the new value and compare this to the vector
// we want to reduce.
ElementCount EC = cast<VectorType>(Src->getType())->getElementCount();
Value *Right = Builder.CreateVectorSplat(EC, InitVal);
Value *Cmp =
Builder.CreateCmp(CmpInst::ICMP_NE, Src, Right, "rdx.select.cmp");

// If any predicate is true it means that we want to select the new value.
Value *AnyOf =
Src->getType()->isVectorTy() ? Builder.CreateOrReduce(Src) : Src;
// The compares in the loop may yield poison, which propagates through the
// bitwise ORs. Freeze it here before the condition is used.
AnyOf = Builder.CreateFreeze(AnyOf);
return Builder.CreateSelect(AnyOf, NewVal, InitVal, "rdx.select");
Cmp = Builder.CreateOrReduce(Cmp);
return Builder.CreateSelect(Cmp, NewVal, InitVal, "rdx.select");
}

Value *llvm::createSimpleTargetReduction(IRBuilderBase &Builder, Value *Src,
Expand Down
4 changes: 3 additions & 1 deletion llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,9 @@ class VPBuilder {
public:
VPBuilder() = default;
VPBuilder(VPBasicBlock *InsertBB) { setInsertPoint(InsertBB); }
VPBuilder(VPRecipeBase *InsertPt) { setInsertPoint(InsertPt); }
VPBuilder(VPRecipeBase *InsertPt) {
setInsertPoint(InsertPt->getParent(), InsertPt->getIterator());
}

/// Clear the insertion point: created instructions will not be inserted into
/// a block.
Expand Down
76 changes: 14 additions & 62 deletions llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3051,8 +3051,9 @@ PHINode *InnerLoopVectorizer::createInductionResumeValue(
}

// Create phi nodes to merge from the backedge-taken check block.
PHINode *BCResumeVal = PHINode::Create(OrigPhi->getType(), 3, "bc.resume.val",
LoopScalarPreHeader->getFirstNonPHI());
PHINode *BCResumeVal =
PHINode::Create(OrigPhi->getType(), 3, "bc.resume.val",
LoopScalarPreHeader->getTerminator()->getIterator());
// Copy original phi DL over to the new one.
BCResumeVal->setDebugLoc(OrigPhi->getDebugLoc());

Expand Down Expand Up @@ -7450,6 +7451,7 @@ static void createAndCollectMergePhiForReduction(
auto *PhiR = cast<VPReductionPHIRecipe>(RedResult->getOperand(0));
const RecurrenceDescriptor &RdxDesc = PhiR->getRecurrenceDescriptor();

TrackingVH<Value> ReductionStartValue = RdxDesc.getRecurrenceStartValue();
Value *FinalValue =
State.get(RedResult, VPIteration(State.UF - 1, VPLane::getFirstLane()));
auto *ResumePhi =
Expand All @@ -7474,7 +7476,7 @@ static void createAndCollectMergePhiForReduction(
BCBlockPhi->addIncoming(ResumePhi->getIncomingValueForBlock(Incoming),
Incoming);
else
BCBlockPhi->addIncoming(RdxDesc.getRecurrenceStartValue(), Incoming);
BCBlockPhi->addIncoming(ReductionStartValue, Incoming);
}

auto *OrigPhi = cast<PHINode>(PhiR->getUnderlyingValue());
Expand Down Expand Up @@ -7767,10 +7769,11 @@ EpilogueVectorizerEpilogueLoop::createEpilogueVectorizedLoopSkeleton(

// Now, compare the remaining count and if there aren't enough iterations to
// execute the vectorized epilogue skip to the scalar part.
LoopVectorPreHeader->setName("vec.epilog.ph");
BasicBlock *VecEpilogueIterationCountCheck =
SplitBlock(LoopVectorPreHeader, LoopVectorPreHeader->begin(), DT, LI,
nullptr, "vec.epilog.iter.check", true);
BasicBlock *VecEpilogueIterationCountCheck = LoopVectorPreHeader;
VecEpilogueIterationCountCheck->setName("vec.epilog.iter.check");
LoopVectorPreHeader =
SplitBlock(LoopVectorPreHeader, LoopVectorPreHeader->getTerminator(), DT,
LI, nullptr, "vec.epilog.ph");
emitMinimumVectorEpilogueIterCountCheck(LoopScalarPreHeader,
VecEpilogueIterationCountCheck);

Expand Down Expand Up @@ -8893,10 +8896,6 @@ VPlanPtr LoopVectorizationPlanner::buildVPlan(VFRange &Range) {
// A ComputeReductionResult recipe is added to the middle block, also for
// in-loop reductions which compute their result in-loop, because generating
// the subsequent bc.merge.rdx phi is driven by ComputeReductionResult recipes.
//
// Adjust AnyOf reductions; replace the reduction phi for the selected value
// with a boolean reduction phi node to check if the condition is true in any
// iteration. The final value is selected by the final ComputeReductionResult.
void LoopVectorizationPlanner::adjustRecipesForReductions(
VPBasicBlock *LatchVPBB, VPlanPtr &Plan, VPRecipeBuilder &RecipeBuilder,
ElementCount MinVF) {
Expand Down Expand Up @@ -9071,41 +9070,6 @@ void LoopVectorizationPlanner::adjustRecipesForReductions(
continue;

const RecurrenceDescriptor &RdxDesc = PhiR->getRecurrenceDescriptor();
// Adjust AnyOf reductions; replace the reduction phi for the selected value
// with a boolean reduction phi node to check if the condition is true in
// any iteration. The final value is selected by the final
// ComputeReductionResult.
if (RecurrenceDescriptor::isAnyOfRecurrenceKind(
RdxDesc.getRecurrenceKind())) {
auto *Select = cast<VPRecipeBase>(*find_if(PhiR->users(), [](VPUser *U) {
return isa<VPWidenSelectRecipe>(U) ||
(isa<VPReplicateRecipe>(U) &&
cast<VPReplicateRecipe>(U)->getUnderlyingInstr()->getOpcode() ==
Instruction::Select);
}));
VPValue *Cmp = Select->getOperand(0);
// If the compare is checking the reduction PHI node, adjust it to check
// the start value.
if (VPRecipeBase *CmpR = Cmp->getDefiningRecipe()) {
for (unsigned I = 0; I != CmpR->getNumOperands(); ++I)
if (CmpR->getOperand(I) == PhiR)
CmpR->setOperand(I, PhiR->getStartValue());
}
VPBuilder::InsertPointGuard Guard(Builder);
Builder.setInsertPoint(Select);

// If the true value of the select is the reduction phi, the new value is
// selected if the negated condition is true in any iteration.
if (Select->getOperand(1) == PhiR)
Cmp = Builder.createNot(Cmp);
VPValue *Or = Builder.createOr(PhiR, Cmp);
Select->getVPSingleValue()->replaceAllUsesWith(Or);

// Convert the reduction phi to operate on bools.
PhiR->setOperand(0, Plan->getOrAddLiveIn(ConstantInt::getFalse(
OrigLoop->getHeader()->getContext())));
}

// If tail is folded by masking, introduce selects between the phi
// and the live-out instruction of each reduction, at the beginning of the
// dedicated latch block.
Expand Down Expand Up @@ -9138,9 +9102,7 @@ void LoopVectorizationPlanner::adjustRecipesForReductions(
// then extend the loop exit value to enable InstCombine to evaluate the
// entire expression in the smaller type.
Type *PhiTy = PhiR->getStartValue()->getLiveInIRValue()->getType();
if (MinVF.isVector() && PhiTy != RdxDesc.getRecurrenceType() &&
!RecurrenceDescriptor::isAnyOfRecurrenceKind(
RdxDesc.getRecurrenceKind())) {
if (MinVF.isVector() && PhiTy != RdxDesc.getRecurrenceType()) {
assert(!PhiR->isInLoop() && "Unexpected truncated inloop reduction!");
Type *RdxTy = RdxDesc.getRecurrenceType();
auto *Trunc =
Expand Down Expand Up @@ -10181,19 +10143,9 @@ bool LoopVectorizePass::processLoop(Loop *L) {
Value *ResumeV = nullptr;
// TODO: Move setting of resume values to prepareToExecute.
if (auto *ReductionPhi = dyn_cast<VPReductionPHIRecipe>(&R)) {
const RecurrenceDescriptor &RdxDesc =
ReductionPhi->getRecurrenceDescriptor();
RecurKind RK = RdxDesc.getRecurrenceKind();
ResumeV = ReductionResumeValues.find(&RdxDesc)->second;
if (RecurrenceDescriptor::isAnyOfRecurrenceKind(RK)) {
// VPReductionPHIRecipes for AnyOf reductions expect a boolean as
// start value; compare the final value from the main vector loop
// to the start value.
IRBuilder<> Builder(
cast<Instruction>(ResumeV)->getParent()->getFirstNonPHI());
ResumeV = Builder.CreateICmpNE(ResumeV,
RdxDesc.getRecurrenceStartValue());
}
ResumeV = ReductionResumeValues
.find(&ReductionPhi->getRecurrenceDescriptor())
->second;
} else {
// Create induction resume values for both widened pointer and
// integer/fp inductions and update the start value of the induction
Expand Down
13 changes: 7 additions & 6 deletions llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -501,8 +501,6 @@ Value *VPInstruction::generatePerPart(VPTransformState &State, unsigned Part) {
// Reduce all of the unrolled parts into a single vector.
Value *ReducedPartRdx = RdxParts[0];
unsigned Op = RecurrenceDescriptor::getOpcode(RK);
if (RecurrenceDescriptor::isAnyOfRecurrenceKind(RK))
Op = Instruction::Or;

if (PhiR->isOrdered()) {
ReducedPartRdx = RdxParts[State.UF - 1];
Expand All @@ -515,16 +513,19 @@ Value *VPInstruction::generatePerPart(VPTransformState &State, unsigned Part) {
if (Op != Instruction::ICmp && Op != Instruction::FCmp)
ReducedPartRdx = Builder.CreateBinOp(
(Instruction::BinaryOps)Op, RdxPart, ReducedPartRdx, "bin.rdx");
else
else if (RecurrenceDescriptor::isAnyOfRecurrenceKind(RK)) {
TrackingVH<Value> ReductionStartValue =
RdxDesc.getRecurrenceStartValue();
ReducedPartRdx = createAnyOfOp(Builder, ReductionStartValue, RK,
ReducedPartRdx, RdxPart);
} else
ReducedPartRdx = createMinMaxOp(Builder, RK, ReducedPartRdx, RdxPart);
}
}

// Create the reduction after the loop. Note that inloop reductions create
// the target reduction in the loop using a Reduction recipe.
if ((State.VF.isVector() ||
RecurrenceDescriptor::isAnyOfRecurrenceKind(RK)) &&
!PhiR->isInLoop()) {
if (State.VF.isVector() && !PhiR->isInLoop()) {
ReducedPartRdx =
createTargetReduction(Builder, RdxDesc, ReducedPartRdx, OrigPhi);
// If the reduction can be performed in a smaller type, we need to extend
Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/Transforms/Vectorize/VPlanValue.h
Original file line number Diff line number Diff line change
Expand Up @@ -361,8 +361,8 @@ class VPDef {
VPWidenMemoryInstructionSC,
VPWidenSC,
VPWidenSelectSC,
// START: Phi-like recipes. Need to be kept together.
VPBlendSC,
// START: Phi-like recipes. Need to be kept together.
VPWidenPHISC,
VPPredInstPHISC,
// START: SubclassID for recipes that inherit VPHeaderPHIRecipe.
Expand All @@ -376,7 +376,7 @@ class VPDef {
VPReductionPHISC,
// END: SubclassID for recipes that inherit VPHeaderPHIRecipe
// END: Phi-like recipes
VPFirstPHISC = VPBlendSC,
VPFirstPHISC = VPWidenPHISC,
VPFirstHeaderPHISC = VPCanonicalIVPHISC,
VPLastHeaderPHISC = VPReductionPHISC,
VPLastPHISC = VPReductionPHISC,
Expand Down
17 changes: 17 additions & 0 deletions llvm/test/CodeGen/RISCV/rv64xtheadba.ll
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,23 @@ define i64 @mul96(i64 %a) {
ret i64 %c
}

define i64 @mul137(i64 %a) {
; RV64I-LABEL: mul137:
; RV64I: # %bb.0:
; RV64I-NEXT: li a1, 137
; RV64I-NEXT: mul a0, a0, a1
; RV64I-NEXT: ret
;
; RV64XTHEADBA-LABEL: mul137:
; RV64XTHEADBA: # %bb.0:
; RV64XTHEADBA-NEXT: th.addsl a1, a0, a0, 3
; RV64XTHEADBA-NEXT: slli a0, a0, 7
; RV64XTHEADBA-NEXT: add a0, a0, a1
; RV64XTHEADBA-NEXT: ret
%c = mul i64 %a, 137
ret i64 %c
}

define i64 @mul160(i64 %a) {
; RV64I-LABEL: mul160:
; RV64I: # %bb.0:
Expand Down
23 changes: 23 additions & 0 deletions llvm/test/CodeGen/X86/code-model-elf-text-sections.ll
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,36 @@
; RUN: llvm-readelf -S %t | FileCheck %s --check-prefix=LARGE-DS

; SMALL: .text {{.*}} AX {{.*}}
; SMALL: .ltext {{.*}} AXl {{.*}}
; SMALL: .ltext.2 {{.*}} AXl {{.*}}
; SMALL: .foo {{.*}} AX {{.*}}
; SMALL-DS: .text.func {{.*}} AX {{.*}}
; SMALL-DS: .ltext {{.*}} AXl {{.*}}
; SMALL-DS: .ltext.2 {{.*}} AXl {{.*}}
; SMALL-DS: .foo {{.*}} AX {{.*}}
; LARGE: .ltext {{.*}} AXl {{.*}}
; LARGE: .ltext.2 {{.*}} AXl {{.*}}
; LARGE: .foo {{.*}} AX {{.*}}
; LARGE-DS: .ltext.func {{.*}} AXl {{.*}}
; LARGE-DS: .ltext {{.*}} AXl {{.*}}
; LARGE-DS: .ltext.2 {{.*}} AXl {{.*}}
; LARGE-DS: .foo {{.*}} AX {{.*}}

target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64--linux"

define void @func() {
ret void
}

define void @ltext() section ".ltext" {
ret void
}

define void @ltext2() section ".ltext.2" {
ret void
}

define void @foo() section ".foo" {
ret void
}
20 changes: 10 additions & 10 deletions llvm/test/Transforms/InstCombine/add-sitofp.ll
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ define double @x(i32 %a, i32 %b) {
; CHECK-NEXT: [[M:%.*]] = lshr i32 [[A:%.*]], 24
; CHECK-NEXT: [[N:%.*]] = and i32 [[M]], [[B:%.*]]
; CHECK-NEXT: [[TMP1:%.*]] = add nuw nsw i32 [[N]], 1
; CHECK-NEXT: [[P:%.*]] = uitofp i32 [[TMP1]] to double
; CHECK-NEXT: [[P:%.*]] = uitofp nneg i32 [[TMP1]] to double
; CHECK-NEXT: ret double [[P]]
;
%m = lshr i32 %a, 24
Expand All @@ -20,7 +20,7 @@ define double @test(i32 %a) {
; CHECK-LABEL: @test(
; CHECK-NEXT: [[A_AND:%.*]] = and i32 [[A:%.*]], 1073741823
; CHECK-NEXT: [[TMP1:%.*]] = add nuw nsw i32 [[A_AND]], 1
; CHECK-NEXT: [[RES:%.*]] = uitofp i32 [[TMP1]] to double
; CHECK-NEXT: [[RES:%.*]] = uitofp nneg i32 [[TMP1]] to double
; CHECK-NEXT: ret double [[RES]]
;
; Drop two highest bits to guarantee that %a + 1 doesn't overflow
Expand All @@ -33,7 +33,7 @@ define double @test(i32 %a) {
define float @test_neg(i32 %a) {
; CHECK-LABEL: @test_neg(
; CHECK-NEXT: [[A_AND:%.*]] = and i32 [[A:%.*]], 1073741823
; CHECK-NEXT: [[A_AND_FP:%.*]] = sitofp i32 [[A_AND]] to float
; CHECK-NEXT: [[A_AND_FP:%.*]] = uitofp nneg i32 [[A_AND]] to float
; CHECK-NEXT: [[RES:%.*]] = fadd float [[A_AND_FP]], 1.000000e+00
; CHECK-NEXT: ret float [[RES]]
;
Expand All @@ -49,7 +49,7 @@ define double @test_2(i32 %a, i32 %b) {
; CHECK-NEXT: [[A_AND:%.*]] = and i32 [[A:%.*]], 1073741823
; CHECK-NEXT: [[B_AND:%.*]] = and i32 [[B:%.*]], 1073741823
; CHECK-NEXT: [[TMP1:%.*]] = add nuw nsw i32 [[A_AND]], [[B_AND]]
; CHECK-NEXT: [[RES:%.*]] = uitofp i32 [[TMP1]] to double
; CHECK-NEXT: [[RES:%.*]] = uitofp nneg i32 [[TMP1]] to double
; CHECK-NEXT: ret double [[RES]]
;
; Drop two highest bits to guarantee that %a + %b doesn't overflow
Expand All @@ -67,8 +67,8 @@ define float @test_2_neg(i32 %a, i32 %b) {
; CHECK-LABEL: @test_2_neg(
; CHECK-NEXT: [[A_AND:%.*]] = and i32 [[A:%.*]], 1073741823
; CHECK-NEXT: [[B_AND:%.*]] = and i32 [[B:%.*]], 1073741823
; CHECK-NEXT: [[A_AND_FP:%.*]] = sitofp i32 [[A_AND]] to float
; CHECK-NEXT: [[B_AND_FP:%.*]] = sitofp i32 [[B_AND]] to float
; CHECK-NEXT: [[A_AND_FP:%.*]] = uitofp nneg i32 [[A_AND]] to float
; CHECK-NEXT: [[B_AND_FP:%.*]] = uitofp nneg i32 [[B_AND]] to float
; CHECK-NEXT: [[RES:%.*]] = fadd float [[A_AND_FP]], [[B_AND_FP]]
; CHECK-NEXT: ret float [[RES]]
;
Expand All @@ -89,7 +89,7 @@ define float @test_3(i32 %a, i32 %b) {
; CHECK-NEXT: [[M:%.*]] = lshr i32 [[A:%.*]], 24
; CHECK-NEXT: [[N:%.*]] = and i32 [[M]], [[B:%.*]]
; CHECK-NEXT: [[TMP1:%.*]] = add nuw nsw i32 [[N]], 1
; CHECK-NEXT: [[P:%.*]] = uitofp i32 [[TMP1]] to float
; CHECK-NEXT: [[P:%.*]] = uitofp nneg i32 [[TMP1]] to float
; CHECK-NEXT: ret float [[P]]
;
%m = lshr i32 %a, 24
Expand All @@ -104,7 +104,7 @@ define <4 x double> @test_4(<4 x i32> %a, <4 x i32> %b) {
; CHECK-NEXT: [[A_AND:%.*]] = and <4 x i32> [[A:%.*]], <i32 1073741823, i32 1073741823, i32 1073741823, i32 1073741823>
; CHECK-NEXT: [[B_AND:%.*]] = and <4 x i32> [[B:%.*]], <i32 1073741823, i32 1073741823, i32 1073741823, i32 1073741823>
; CHECK-NEXT: [[TMP1:%.*]] = add nuw nsw <4 x i32> [[A_AND]], [[B_AND]]
; CHECK-NEXT: [[RES:%.*]] = uitofp <4 x i32> [[TMP1]] to <4 x double>
; CHECK-NEXT: [[RES:%.*]] = uitofp nneg <4 x i32> [[TMP1]] to <4 x double>
; CHECK-NEXT: ret <4 x double> [[RES]]
;
; Drop two highest bits to guarantee that %a + %b doesn't overflow
Expand All @@ -122,8 +122,8 @@ define <4 x float> @test_4_neg(<4 x i32> %a, <4 x i32> %b) {
; CHECK-LABEL: @test_4_neg(
; CHECK-NEXT: [[A_AND:%.*]] = and <4 x i32> [[A:%.*]], <i32 1073741823, i32 1073741823, i32 1073741823, i32 1073741823>
; CHECK-NEXT: [[B_AND:%.*]] = and <4 x i32> [[B:%.*]], <i32 1073741823, i32 1073741823, i32 1073741823, i32 1073741823>
; CHECK-NEXT: [[A_AND_FP:%.*]] = sitofp <4 x i32> [[A_AND]] to <4 x float>
; CHECK-NEXT: [[B_AND_FP:%.*]] = sitofp <4 x i32> [[B_AND]] to <4 x float>
; CHECK-NEXT: [[A_AND_FP:%.*]] = uitofp nneg <4 x i32> [[A_AND]] to <4 x float>
; CHECK-NEXT: [[B_AND_FP:%.*]] = uitofp nneg <4 x i32> [[B_AND]] to <4 x float>
; CHECK-NEXT: [[RES:%.*]] = fadd <4 x float> [[A_AND_FP]], [[B_AND_FP]]
; CHECK-NEXT: ret <4 x float> [[RES]]
;
Expand Down
66 changes: 33 additions & 33 deletions llvm/test/Transforms/InstCombine/binop-itofp.ll
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ define half @test_ui_ui_i8_add_fail_overflow(i8 noundef %x_in, i8 noundef %y_in)
; CHECK-LABEL: @test_ui_ui_i8_add_fail_overflow(
; CHECK-NEXT: [[X:%.*]] = and i8 [[X_IN:%.*]], 127
; CHECK-NEXT: [[Y:%.*]] = and i8 [[Y_IN:%.*]], -127
; CHECK-NEXT: [[XF:%.*]] = uitofp i8 [[X]] to half
; CHECK-NEXT: [[XF:%.*]] = uitofp nneg i8 [[X]] to half
; CHECK-NEXT: [[YF:%.*]] = uitofp i8 [[Y]] to half
; CHECK-NEXT: [[R:%.*]] = fadd half [[XF]], [[YF]]
; CHECK-NEXT: ret half [[R]]
Expand Down Expand Up @@ -49,7 +49,7 @@ define half @test_ui_ui_i8_add_C(i8 noundef %x_in) {
define half @test_ui_ui_i8_add_C_fail_no_repr(i8 noundef %x_in) {
; CHECK-LABEL: @test_ui_ui_i8_add_C_fail_no_repr(
; CHECK-NEXT: [[X:%.*]] = and i8 [[X_IN:%.*]], 127
; CHECK-NEXT: [[XF:%.*]] = uitofp i8 [[X]] to half
; CHECK-NEXT: [[XF:%.*]] = uitofp nneg i8 [[X]] to half
; CHECK-NEXT: [[R:%.*]] = fadd half [[XF]], 0xH57F8
; CHECK-NEXT: ret half [[R]]
;
Expand All @@ -62,7 +62,7 @@ define half @test_ui_ui_i8_add_C_fail_no_repr(i8 noundef %x_in) {
define half @test_ui_ui_i8_add_C_fail_overflow(i8 noundef %x_in) {
; CHECK-LABEL: @test_ui_ui_i8_add_C_fail_overflow(
; CHECK-NEXT: [[X:%.*]] = and i8 [[X_IN:%.*]], 127
; CHECK-NEXT: [[XF:%.*]] = uitofp i8 [[X]] to half
; CHECK-NEXT: [[XF:%.*]] = uitofp nneg i8 [[X]] to half
; CHECK-NEXT: [[R:%.*]] = fadd half [[XF]], 0xH5808
; CHECK-NEXT: ret half [[R]]
;
Expand Down Expand Up @@ -110,7 +110,7 @@ define half @test_ui_si_i8_add(i8 noundef %x_in, i8 noundef %y_in) {
; CHECK-NEXT: [[X:%.*]] = and i8 [[X_IN:%.*]], 63
; CHECK-NEXT: [[Y:%.*]] = and i8 [[Y_IN:%.*]], 63
; CHECK-NEXT: [[TMP1:%.*]] = add nuw nsw i8 [[X]], [[Y]]
; CHECK-NEXT: [[R:%.*]] = uitofp i8 [[TMP1]] to half
; CHECK-NEXT: [[R:%.*]] = uitofp nneg i8 [[TMP1]] to half
; CHECK-NEXT: ret half [[R]]
;
%x = and i8 %x_in, 63
Expand Down Expand Up @@ -140,7 +140,7 @@ define half @test_ui_si_i8_add_overflow(i8 noundef %x_in, i8 noundef %y_in) {
define half @test_ui_ui_i8_sub_C(i8 noundef %x_in) {
; CHECK-LABEL: @test_ui_ui_i8_sub_C(
; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X_IN:%.*]], 127
; CHECK-NEXT: [[R:%.*]] = uitofp i8 [[TMP1]] to half
; CHECK-NEXT: [[R:%.*]] = uitofp nneg i8 [[TMP1]] to half
; CHECK-NEXT: ret half [[R]]
;
%x = or i8 %x_in, 128
Expand All @@ -166,7 +166,7 @@ define half @test_si_si_i8_sub(i8 noundef %x_in, i8 noundef %y_in) {
; CHECK-NEXT: [[X:%.*]] = and i8 [[X_IN:%.*]], 63
; CHECK-NEXT: [[Y:%.*]] = or i8 [[Y_IN:%.*]], -64
; CHECK-NEXT: [[TMP1:%.*]] = sub nsw i8 [[X]], [[Y]]
; CHECK-NEXT: [[R:%.*]] = sitofp i8 [[TMP1]] to half
; CHECK-NEXT: [[R:%.*]] = uitofp nneg i8 [[TMP1]] to half
; CHECK-NEXT: ret half [[R]]
;
%x = and i8 %x_in, 63
Expand All @@ -181,7 +181,7 @@ define half @test_si_si_i8_sub_fail_overflow(i8 noundef %x_in, i8 noundef %y_in)
; CHECK-LABEL: @test_si_si_i8_sub_fail_overflow(
; CHECK-NEXT: [[X:%.*]] = and i8 [[X_IN:%.*]], 63
; CHECK-NEXT: [[Y:%.*]] = or i8 [[Y_IN:%.*]], -65
; CHECK-NEXT: [[XF:%.*]] = sitofp i8 [[X]] to half
; CHECK-NEXT: [[XF:%.*]] = uitofp nneg i8 [[X]] to half
; CHECK-NEXT: [[YF:%.*]] = sitofp i8 [[Y]] to half
; CHECK-NEXT: [[R:%.*]] = fsub half [[XF]], [[YF]]
; CHECK-NEXT: ret half [[R]]
Expand All @@ -198,7 +198,7 @@ define half @test_si_si_i8_sub_C(i8 noundef %x_in) {
; CHECK-LABEL: @test_si_si_i8_sub_C(
; CHECK-NEXT: [[X:%.*]] = and i8 [[X_IN:%.*]], 63
; CHECK-NEXT: [[TMP1:%.*]] = or disjoint i8 [[X]], 64
; CHECK-NEXT: [[R:%.*]] = sitofp i8 [[TMP1]] to half
; CHECK-NEXT: [[R:%.*]] = uitofp nneg i8 [[TMP1]] to half
; CHECK-NEXT: ret half [[R]]
;
%x = and i8 %x_in, 63
Expand Down Expand Up @@ -283,7 +283,7 @@ define half @test_ui_ui_i8_mul_C(i8 noundef %x_in) {
define half @test_ui_ui_i8_mul_C_fail_overlow(i8 noundef %x_in) {
; CHECK-LABEL: @test_ui_ui_i8_mul_C_fail_overlow(
; CHECK-NEXT: [[X:%.*]] = and i8 [[X_IN:%.*]], 14
; CHECK-NEXT: [[XF:%.*]] = uitofp i8 [[X]] to half
; CHECK-NEXT: [[XF:%.*]] = uitofp nneg i8 [[X]] to half
; CHECK-NEXT: [[R:%.*]] = fmul half [[XF]], 0xH4CC0
; CHECK-NEXT: ret half [[R]]
;
Expand Down Expand Up @@ -315,7 +315,7 @@ define half @test_si_si_i8_mul_fail_maybe_zero(i8 noundef %x_in, i8 noundef %y_i
; CHECK-LABEL: @test_si_si_i8_mul_fail_maybe_zero(
; CHECK-NEXT: [[X:%.*]] = and i8 [[X_IN:%.*]], 7
; CHECK-NEXT: [[Y:%.*]] = or i8 [[Y_IN:%.*]], -8
; CHECK-NEXT: [[XF:%.*]] = sitofp i8 [[X]] to half
; CHECK-NEXT: [[XF:%.*]] = uitofp nneg i8 [[X]] to half
; CHECK-NEXT: [[YF:%.*]] = sitofp i8 [[Y]] to half
; CHECK-NEXT: [[R:%.*]] = fmul half [[XF]], [[YF]]
; CHECK-NEXT: ret half [[R]]
Expand All @@ -332,7 +332,7 @@ define half @test_si_si_i8_mul_C_fail_no_repr(i8 noundef %x_in) {
; CHECK-LABEL: @test_si_si_i8_mul_C_fail_no_repr(
; CHECK-NEXT: [[XX:%.*]] = and i8 [[X_IN:%.*]], 6
; CHECK-NEXT: [[X:%.*]] = or disjoint i8 [[XX]], 1
; CHECK-NEXT: [[XF:%.*]] = sitofp i8 [[X]] to half
; CHECK-NEXT: [[XF:%.*]] = uitofp nneg i8 [[X]] to half
; CHECK-NEXT: [[R:%.*]] = fmul half [[XF]], 0xHC780
; CHECK-NEXT: ret half [[R]]
;
Expand All @@ -347,7 +347,7 @@ define half @test_si_si_i8_mul_C_fail_overflow(i8 noundef %x_in) {
; CHECK-LABEL: @test_si_si_i8_mul_C_fail_overflow(
; CHECK-NEXT: [[XX:%.*]] = and i8 [[X_IN:%.*]], 6
; CHECK-NEXT: [[X:%.*]] = or disjoint i8 [[XX]], 1
; CHECK-NEXT: [[XF:%.*]] = sitofp i8 [[X]] to half
; CHECK-NEXT: [[XF:%.*]] = uitofp nneg i8 [[X]] to half
; CHECK-NEXT: [[R:%.*]] = fmul half [[XF]], 0xHCCC0
; CHECK-NEXT: ret half [[R]]
;
Expand All @@ -365,7 +365,7 @@ define half @test_ui_si_i8_mul(i8 noundef %x_in, i8 noundef %y_in) {
; CHECK-NEXT: [[YY:%.*]] = and i8 [[Y_IN:%.*]], 7
; CHECK-NEXT: [[Y:%.*]] = add nuw nsw i8 [[YY]], 1
; CHECK-NEXT: [[TMP1:%.*]] = mul nuw nsw i8 [[X]], [[Y]]
; CHECK-NEXT: [[R:%.*]] = uitofp i8 [[TMP1]] to half
; CHECK-NEXT: [[R:%.*]] = uitofp nneg i8 [[TMP1]] to half
; CHECK-NEXT: ret half [[R]]
;
%xx = and i8 %x_in, 6
Expand All @@ -384,7 +384,7 @@ define half @test_ui_si_i8_mul_fail_maybe_zero(i8 noundef %x_in, i8 noundef %y_i
; CHECK-NEXT: [[X:%.*]] = add nuw nsw i8 [[XX]], 1
; CHECK-NEXT: [[Y:%.*]] = and i8 [[Y_IN:%.*]], 7
; CHECK-NEXT: [[TMP1:%.*]] = mul nuw nsw i8 [[X]], [[Y]]
; CHECK-NEXT: [[R:%.*]] = uitofp i8 [[TMP1]] to half
; CHECK-NEXT: [[R:%.*]] = uitofp nneg i8 [[TMP1]] to half
; CHECK-NEXT: ret half [[R]]
;
%xx = and i8 %x_in, 7
Expand All @@ -401,7 +401,7 @@ define half @test_ui_si_i8_mul_fail_signed(i8 noundef %x_in, i8 noundef %y_in) {
; CHECK-NEXT: [[XX:%.*]] = and i8 [[X_IN:%.*]], 7
; CHECK-NEXT: [[X:%.*]] = add nuw nsw i8 [[XX]], 1
; CHECK-NEXT: [[Y:%.*]] = or i8 [[Y_IN:%.*]], -4
; CHECK-NEXT: [[XF:%.*]] = sitofp i8 [[X]] to half
; CHECK-NEXT: [[XF:%.*]] = uitofp nneg i8 [[X]] to half
; CHECK-NEXT: [[YF:%.*]] = uitofp i8 [[Y]] to half
; CHECK-NEXT: [[R:%.*]] = fmul half [[XF]], [[YF]]
; CHECK-NEXT: ret half [[R]]
Expand All @@ -420,7 +420,7 @@ define half @test_ui_ui_i16_add(i16 noundef %x_in, i16 noundef %y_in) {
; CHECK-NEXT: [[X:%.*]] = and i16 [[X_IN:%.*]], 2047
; CHECK-NEXT: [[Y:%.*]] = and i16 [[Y_IN:%.*]], 2047
; CHECK-NEXT: [[TMP1:%.*]] = add nuw nsw i16 [[X]], [[Y]]
; CHECK-NEXT: [[R:%.*]] = uitofp i16 [[TMP1]] to half
; CHECK-NEXT: [[R:%.*]] = uitofp nneg i16 [[TMP1]] to half
; CHECK-NEXT: ret half [[R]]
;
%x = and i16 %x_in, 2047
Expand All @@ -435,8 +435,8 @@ define half @test_ui_ui_i16_add_fail_not_promotable(i16 noundef %x_in, i16 nound
; CHECK-LABEL: @test_ui_ui_i16_add_fail_not_promotable(
; CHECK-NEXT: [[X:%.*]] = and i16 [[X_IN:%.*]], 2049
; CHECK-NEXT: [[Y:%.*]] = and i16 [[Y_IN:%.*]], 2047
; CHECK-NEXT: [[XF:%.*]] = uitofp i16 [[X]] to half
; CHECK-NEXT: [[YF:%.*]] = uitofp i16 [[Y]] to half
; CHECK-NEXT: [[XF:%.*]] = uitofp nneg i16 [[X]] to half
; CHECK-NEXT: [[YF:%.*]] = uitofp nneg i16 [[Y]] to half
; CHECK-NEXT: [[R:%.*]] = fadd half [[XF]], [[YF]]
; CHECK-NEXT: ret half [[R]]
;
Expand All @@ -463,7 +463,7 @@ define half @test_ui_ui_i16_add_C(i16 noundef %x_in) {
define half @test_ui_ui_i16_add_C_fail_overflow(i16 noundef %x_in) {
; CHECK-LABEL: @test_ui_ui_i16_add_C_fail_overflow(
; CHECK-NEXT: [[X:%.*]] = and i16 [[X_IN:%.*]], 2047
; CHECK-NEXT: [[XF:%.*]] = uitofp i16 [[X]] to half
; CHECK-NEXT: [[XF:%.*]] = uitofp nneg i16 [[X]] to half
; CHECK-NEXT: [[R:%.*]] = fadd half [[XF]], 0xH7BD0
; CHECK-NEXT: ret half [[R]]
;
Expand Down Expand Up @@ -541,7 +541,7 @@ define half @test_si_si_i16_sub_fail_no_promotion(i16 noundef %x_in, i16 noundef
; CHECK-LABEL: @test_si_si_i16_sub_fail_no_promotion(
; CHECK-NEXT: [[X:%.*]] = and i16 [[X_IN:%.*]], 2047
; CHECK-NEXT: [[Y:%.*]] = or i16 [[Y_IN:%.*]], -2049
; CHECK-NEXT: [[XF:%.*]] = sitofp i16 [[X]] to half
; CHECK-NEXT: [[XF:%.*]] = uitofp nneg i16 [[X]] to half
; CHECK-NEXT: [[YF:%.*]] = sitofp i16 [[Y]] to half
; CHECK-NEXT: [[R:%.*]] = fsub half [[XF]], [[YF]]
; CHECK-NEXT: ret half [[R]]
Expand Down Expand Up @@ -575,7 +575,7 @@ define half @test_ui_si_i16_sub_fail_maybe_signed(i16 noundef %x_in, i16 noundef
; CHECK-NEXT: [[X:%.*]] = or i16 [[X_IN:%.*]], -2048
; CHECK-NEXT: [[Y:%.*]] = and i16 [[Y_IN:%.*]], 2047
; CHECK-NEXT: [[XF:%.*]] = uitofp i16 [[X]] to half
; CHECK-NEXT: [[YF:%.*]] = sitofp i16 [[Y]] to half
; CHECK-NEXT: [[YF:%.*]] = uitofp nneg i16 [[Y]] to half
; CHECK-NEXT: [[R:%.*]] = fsub half [[XF]], [[YF]]
; CHECK-NEXT: ret half [[R]]
;
Expand Down Expand Up @@ -607,8 +607,8 @@ define half @test_ui_ui_i16_mul_fail_no_promotion(i16 noundef %x_in, i16 noundef
; CHECK-LABEL: @test_ui_ui_i16_mul_fail_no_promotion(
; CHECK-NEXT: [[X:%.*]] = and i16 [[X_IN:%.*]], 4095
; CHECK-NEXT: [[Y:%.*]] = and i16 [[Y_IN:%.*]], 3
; CHECK-NEXT: [[XF:%.*]] = uitofp i16 [[X]] to half
; CHECK-NEXT: [[YF:%.*]] = uitofp i16 [[Y]] to half
; CHECK-NEXT: [[XF:%.*]] = uitofp nneg i16 [[X]] to half
; CHECK-NEXT: [[YF:%.*]] = uitofp nneg i16 [[Y]] to half
; CHECK-NEXT: [[R:%.*]] = fmul half [[XF]], [[YF]]
; CHECK-NEXT: ret half [[R]]
;
Expand Down Expand Up @@ -643,7 +643,7 @@ define half @test_si_si_i16_mul_fail_overflow(i16 noundef %x_in, i16 noundef %y_
; CHECK-NEXT: [[XX:%.*]] = and i16 [[X_IN:%.*]], 126
; CHECK-NEXT: [[X:%.*]] = or disjoint i16 [[XX]], 1
; CHECK-NEXT: [[Y:%.*]] = or i16 [[Y_IN:%.*]], -257
; CHECK-NEXT: [[XF:%.*]] = sitofp i16 [[X]] to half
; CHECK-NEXT: [[XF:%.*]] = uitofp nneg i16 [[X]] to half
; CHECK-NEXT: [[YF:%.*]] = sitofp i16 [[Y]] to half
; CHECK-NEXT: [[R:%.*]] = fmul half [[XF]], [[YF]]
; CHECK-NEXT: ret half [[R]]
Expand Down Expand Up @@ -690,7 +690,7 @@ define half @test_ui_si_i16_mul(i16 noundef %x_in, i16 noundef %y_in) {
; CHECK-NEXT: [[YY:%.*]] = and i16 [[Y_IN:%.*]], 126
; CHECK-NEXT: [[Y:%.*]] = or disjoint i16 [[YY]], 1
; CHECK-NEXT: [[TMP1:%.*]] = mul nuw nsw i16 [[X]], [[Y]]
; CHECK-NEXT: [[R:%.*]] = uitofp i16 [[TMP1]] to half
; CHECK-NEXT: [[R:%.*]] = uitofp nneg i16 [[TMP1]] to half
; CHECK-NEXT: ret half [[R]]
;
%xx = and i16 %x_in, 126
Expand Down Expand Up @@ -723,7 +723,7 @@ define half @test_ui_ui_i12_add_fail_overflow(i12 noundef %x_in, i12 noundef %y_
; CHECK-LABEL: @test_ui_ui_i12_add_fail_overflow(
; CHECK-NEXT: [[X:%.*]] = and i12 [[X_IN:%.*]], 2047
; CHECK-NEXT: [[Y:%.*]] = and i12 [[Y_IN:%.*]], -2047
; CHECK-NEXT: [[XF:%.*]] = uitofp i12 [[X]] to half
; CHECK-NEXT: [[XF:%.*]] = uitofp nneg i12 [[X]] to half
; CHECK-NEXT: [[YF:%.*]] = uitofp i12 [[Y]] to half
; CHECK-NEXT: [[R:%.*]] = fadd half [[XF]], [[YF]]
; CHECK-NEXT: ret half [[R]]
Expand Down Expand Up @@ -821,7 +821,7 @@ define half @test_si_si_i12_sub(i12 noundef %x_in, i12 noundef %y_in) {
; CHECK-NEXT: [[X:%.*]] = and i12 [[X_IN:%.*]], 1023
; CHECK-NEXT: [[Y:%.*]] = or i12 [[Y_IN:%.*]], -1024
; CHECK-NEXT: [[TMP1:%.*]] = sub nsw i12 [[X]], [[Y]]
; CHECK-NEXT: [[R:%.*]] = sitofp i12 [[TMP1]] to half
; CHECK-NEXT: [[R:%.*]] = uitofp nneg i12 [[TMP1]] to half
; CHECK-NEXT: ret half [[R]]
;
%x = and i12 %x_in, 1023
Expand Down Expand Up @@ -850,7 +850,7 @@ define half @test_ui_ui_i12_mul(i12 noundef %x_in, i12 noundef %y_in) {
; CHECK-NEXT: [[X:%.*]] = and i12 [[X_IN:%.*]], 31
; CHECK-NEXT: [[Y:%.*]] = and i12 [[Y_IN:%.*]], 63
; CHECK-NEXT: [[TMP1:%.*]] = mul nuw nsw i12 [[X]], [[Y]]
; CHECK-NEXT: [[R:%.*]] = uitofp i12 [[TMP1]] to half
; CHECK-NEXT: [[R:%.*]] = uitofp nneg i12 [[TMP1]] to half
; CHECK-NEXT: ret half [[R]]
;
%x = and i12 %x_in, 31
Expand Down Expand Up @@ -883,7 +883,7 @@ define half @test_ui_ui_i12_mul_C(i12 noundef %x_in) {
; CHECK-LABEL: @test_ui_ui_i12_mul_C(
; CHECK-NEXT: [[X:%.*]] = shl i12 [[X_IN:%.*]], 6
; CHECK-NEXT: [[TMP1:%.*]] = and i12 [[X]], 1984
; CHECK-NEXT: [[R:%.*]] = uitofp i12 [[TMP1]] to half
; CHECK-NEXT: [[R:%.*]] = uitofp nneg i12 [[TMP1]] to half
; CHECK-NEXT: ret half [[R]]
;
%x = and i12 %x_in, 31
Expand Down Expand Up @@ -915,7 +915,7 @@ define half @test_si_si_i12_mul_fail_overflow(i12 noundef %x_in, i12 noundef %y_
; CHECK-NEXT: [[XX:%.*]] = and i12 [[X_IN:%.*]], 30
; CHECK-NEXT: [[X:%.*]] = or disjoint i12 [[XX]], 1
; CHECK-NEXT: [[Y:%.*]] = or i12 [[Y_IN:%.*]], -128
; CHECK-NEXT: [[XF:%.*]] = sitofp i12 [[X]] to half
; CHECK-NEXT: [[XF:%.*]] = uitofp nneg i12 [[X]] to half
; CHECK-NEXT: [[YF:%.*]] = sitofp i12 [[Y]] to half
; CHECK-NEXT: [[R:%.*]] = fmul half [[XF]], [[YF]]
; CHECK-NEXT: ret half [[R]]
Expand All @@ -933,7 +933,7 @@ define half @test_si_si_i12_mul_fail_maybe_non_zero(i12 noundef %x_in, i12 nound
; CHECK-LABEL: @test_si_si_i12_mul_fail_maybe_non_zero(
; CHECK-NEXT: [[X:%.*]] = and i12 [[X_IN:%.*]], 30
; CHECK-NEXT: [[Y:%.*]] = or i12 [[Y_IN:%.*]], -128
; CHECK-NEXT: [[XF:%.*]] = sitofp i12 [[X]] to half
; CHECK-NEXT: [[XF:%.*]] = uitofp nneg i12 [[X]] to half
; CHECK-NEXT: [[YF:%.*]] = sitofp i12 [[Y]] to half
; CHECK-NEXT: [[R:%.*]] = fmul half [[XF]], [[YF]]
; CHECK-NEXT: ret half [[R]]
Expand All @@ -950,7 +950,7 @@ define half @test_si_si_i12_mul_C(i12 noundef %x_in) {
; CHECK-LABEL: @test_si_si_i12_mul_C(
; CHECK-NEXT: [[X:%.*]] = or i12 [[X_IN:%.*]], -64
; CHECK-NEXT: [[TMP1:%.*]] = mul nsw i12 [[X]], -16
; CHECK-NEXT: [[R:%.*]] = sitofp i12 [[TMP1]] to half
; CHECK-NEXT: [[R:%.*]] = uitofp nneg i12 [[TMP1]] to half
; CHECK-NEXT: ret half [[R]]
;
%x = or i12 %x_in, -64
Expand Down Expand Up @@ -979,7 +979,7 @@ define half @test_ui_si_i12_mul_nsw(i12 noundef %x_in, i12 noundef %y_in) {
; CHECK-NEXT: [[YY:%.*]] = and i12 [[Y_IN:%.*]], 30
; CHECK-NEXT: [[Y:%.*]] = or disjoint i12 [[YY]], 1
; CHECK-NEXT: [[TMP1:%.*]] = mul nuw nsw i12 [[X]], [[Y]]
; CHECK-NEXT: [[R:%.*]] = uitofp i12 [[TMP1]] to half
; CHECK-NEXT: [[R:%.*]] = uitofp nneg i12 [[TMP1]] to half
; CHECK-NEXT: ret half [[R]]
;
%xx = and i12 %x_in, 31
Expand Down
10 changes: 5 additions & 5 deletions llvm/test/Transforms/InstCombine/clamp-to-minmax.ll
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,7 @@ define float @ui32_clamp_and_cast_to_float(i32 %x) {
; CHECK-LABEL: @ui32_clamp_and_cast_to_float(
; CHECK-NEXT: [[LO_CMP:%.*]] = icmp eq i32 [[X:%.*]], 0
; CHECK-NEXT: [[MIN1:%.*]] = call i32 @llvm.umin.i32(i32 [[X]], i32 255)
; CHECK-NEXT: [[MIN:%.*]] = uitofp i32 [[MIN1]] to float
; CHECK-NEXT: [[MIN:%.*]] = uitofp nneg i32 [[MIN1]] to float
; CHECK-NEXT: [[R:%.*]] = select i1 [[LO_CMP]], float 1.000000e+00, float [[MIN]]
; CHECK-NEXT: ret float [[R]]
;
Expand All @@ -488,7 +488,7 @@ define float @ui64_clamp_and_cast_to_float(i64 %x) {
; CHECK-LABEL: @ui64_clamp_and_cast_to_float(
; CHECK-NEXT: [[LO_CMP:%.*]] = icmp eq i64 [[X:%.*]], 0
; CHECK-NEXT: [[MIN1:%.*]] = call i64 @llvm.umin.i64(i64 [[X]], i64 255)
; CHECK-NEXT: [[MIN:%.*]] = uitofp i64 [[MIN1]] to float
; CHECK-NEXT: [[MIN:%.*]] = uitofp nneg i64 [[MIN1]] to float
; CHECK-NEXT: [[R:%.*]] = select i1 [[LO_CMP]], float 1.000000e+00, float [[MIN]]
; CHECK-NEXT: ret float [[R]]
;
Expand All @@ -504,7 +504,7 @@ define float @mixed_clamp_to_float_1(i32 %x) {
; CHECK-LABEL: @mixed_clamp_to_float_1(
; CHECK-NEXT: [[SI_MIN:%.*]] = call i32 @llvm.smin.i32(i32 [[X:%.*]], i32 255)
; CHECK-NEXT: [[R1:%.*]] = call i32 @llvm.smax.i32(i32 [[SI_MIN]], i32 1)
; CHECK-NEXT: [[R:%.*]] = sitofp i32 [[R1]] to float
; CHECK-NEXT: [[R:%.*]] = uitofp nneg i32 [[R1]] to float
; CHECK-NEXT: ret float [[R]]
;
%si_min_cmp = icmp sgt i32 %x, 255
Expand Down Expand Up @@ -539,7 +539,7 @@ define float @mixed_clamp_to_float_2(i32 %x) {
; CHECK-LABEL: @mixed_clamp_to_float_2(
; CHECK-NEXT: [[SI_MIN:%.*]] = call i32 @llvm.smin.i32(i32 [[X:%.*]], i32 255)
; CHECK-NEXT: [[R1:%.*]] = call i32 @llvm.smax.i32(i32 [[SI_MIN]], i32 1)
; CHECK-NEXT: [[R:%.*]] = sitofp i32 [[R1]] to float
; CHECK-NEXT: [[R:%.*]] = uitofp nneg i32 [[R1]] to float
; CHECK-NEXT: ret float [[R]]
;
%si_min_cmp = icmp sgt i32 %x, 255
Expand Down Expand Up @@ -572,7 +572,7 @@ define <2 x float> @mixed_clamp_to_float_vec(<2 x i32> %x) {
; CHECK-LABEL: @mixed_clamp_to_float_vec(
; CHECK-NEXT: [[SI_MIN:%.*]] = call <2 x i32> @llvm.smin.v2i32(<2 x i32> [[X:%.*]], <2 x i32> <i32 255, i32 255>)
; CHECK-NEXT: [[R1:%.*]] = call <2 x i32> @llvm.smax.v2i32(<2 x i32> [[SI_MIN]], <2 x i32> <i32 1, i32 1>)
; CHECK-NEXT: [[R:%.*]] = sitofp <2 x i32> [[R1]] to <2 x float>
; CHECK-NEXT: [[R:%.*]] = uitofp nneg <2 x i32> [[R1]] to <2 x float>
; CHECK-NEXT: ret <2 x float> [[R]]
;
%si_min_cmp = icmp sgt <2 x i32> %x, <i32 255, i32 255>
Expand Down
24 changes: 12 additions & 12 deletions llvm/test/Transforms/InstCombine/fpcast.ll
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ define half @sint_to_fptrunc(i32 %x) {
define half @masked_sint_to_fptrunc1(i32 %x) {
; CHECK-LABEL: @masked_sint_to_fptrunc1(
; CHECK-NEXT: [[M:%.*]] = and i32 [[X:%.*]], 16777215
; CHECK-NEXT: [[R:%.*]] = sitofp i32 [[M]] to half
; CHECK-NEXT: [[R:%.*]] = uitofp nneg i32 [[M]] to half
; CHECK-NEXT: ret half [[R]]
;
%m = and i32 %x, 16777215
Expand All @@ -182,7 +182,7 @@ define half @masked_sint_to_fptrunc1(i32 %x) {
define half @masked_sint_to_fptrunc2(i32 %x) {
; CHECK-LABEL: @masked_sint_to_fptrunc2(
; CHECK-NEXT: [[M:%.*]] = lshr i32 [[X:%.*]], 8
; CHECK-NEXT: [[R:%.*]] = sitofp i32 [[M]] to half
; CHECK-NEXT: [[R:%.*]] = uitofp nneg i32 [[M]] to half
; CHECK-NEXT: ret half [[R]]
;
%m = lshr i32 %x, 8
Expand All @@ -194,7 +194,7 @@ define half @masked_sint_to_fptrunc2(i32 %x) {
define half @masked_sint_to_fptrunc3(i32 %x) {
; CHECK-LABEL: @masked_sint_to_fptrunc3(
; CHECK-NEXT: [[M:%.*]] = lshr i32 [[X:%.*]], 7
; CHECK-NEXT: [[F:%.*]] = sitofp i32 [[M]] to float
; CHECK-NEXT: [[F:%.*]] = uitofp nneg i32 [[M]] to float
; CHECK-NEXT: [[R:%.*]] = fptrunc float [[F]] to half
; CHECK-NEXT: ret half [[R]]
;
Expand All @@ -218,7 +218,7 @@ define double @sint_to_fpext(i32 %x) {
define double @masked_sint_to_fpext1(i32 %x) {
; CHECK-LABEL: @masked_sint_to_fpext1(
; CHECK-NEXT: [[M:%.*]] = and i32 [[X:%.*]], 16777215
; CHECK-NEXT: [[R:%.*]] = sitofp i32 [[M]] to double
; CHECK-NEXT: [[R:%.*]] = uitofp nneg i32 [[M]] to double
; CHECK-NEXT: ret double [[R]]
;
%m = and i32 %x, 16777215
Expand All @@ -230,7 +230,7 @@ define double @masked_sint_to_fpext1(i32 %x) {
define double @masked_sint_to_fpext2(i32 %x) {
; CHECK-LABEL: @masked_sint_to_fpext2(
; CHECK-NEXT: [[M:%.*]] = lshr i32 [[X:%.*]], 8
; CHECK-NEXT: [[R:%.*]] = sitofp i32 [[M]] to double
; CHECK-NEXT: [[R:%.*]] = uitofp nneg i32 [[M]] to double
; CHECK-NEXT: ret double [[R]]
;
%m = lshr i32 %x, 8
Expand All @@ -242,7 +242,7 @@ define double @masked_sint_to_fpext2(i32 %x) {
define double @masked_sint_to_fpext3(i32 %x) {
; CHECK-LABEL: @masked_sint_to_fpext3(
; CHECK-NEXT: [[M:%.*]] = lshr i32 [[X:%.*]], 7
; CHECK-NEXT: [[F:%.*]] = sitofp i32 [[M]] to float
; CHECK-NEXT: [[F:%.*]] = uitofp nneg i32 [[M]] to float
; CHECK-NEXT: [[R:%.*]] = fpext float [[F]] to double
; CHECK-NEXT: ret double [[R]]
;
Expand All @@ -266,7 +266,7 @@ define half @uint_to_fptrunc(i32 %x) {
define half @masked_uint_to_fptrunc1(i32 %x) {
; CHECK-LABEL: @masked_uint_to_fptrunc1(
; CHECK-NEXT: [[M:%.*]] = and i32 [[X:%.*]], 16777215
; CHECK-NEXT: [[R:%.*]] = uitofp i32 [[M]] to half
; CHECK-NEXT: [[R:%.*]] = uitofp nneg i32 [[M]] to half
; CHECK-NEXT: ret half [[R]]
;
%m = and i32 %x, 16777215
Expand All @@ -278,7 +278,7 @@ define half @masked_uint_to_fptrunc1(i32 %x) {
define half @masked_uint_to_fptrunc2(i32 %x) {
; CHECK-LABEL: @masked_uint_to_fptrunc2(
; CHECK-NEXT: [[M:%.*]] = lshr i32 [[X:%.*]], 8
; CHECK-NEXT: [[R:%.*]] = uitofp i32 [[M]] to half
; CHECK-NEXT: [[R:%.*]] = uitofp nneg i32 [[M]] to half
; CHECK-NEXT: ret half [[R]]
;
%m = lshr i32 %x, 8
Expand All @@ -290,7 +290,7 @@ define half @masked_uint_to_fptrunc2(i32 %x) {
define half @masked_uint_to_fptrunc3(i32 %x) {
; CHECK-LABEL: @masked_uint_to_fptrunc3(
; CHECK-NEXT: [[M:%.*]] = lshr i32 [[X:%.*]], 7
; CHECK-NEXT: [[F:%.*]] = uitofp i32 [[M]] to float
; CHECK-NEXT: [[F:%.*]] = uitofp nneg i32 [[M]] to float
; CHECK-NEXT: [[R:%.*]] = fptrunc float [[F]] to half
; CHECK-NEXT: ret half [[R]]
;
Expand All @@ -314,7 +314,7 @@ define double @uint_to_fpext(i32 %x) {
define double @masked_uint_to_fpext1(i32 %x) {
; CHECK-LABEL: @masked_uint_to_fpext1(
; CHECK-NEXT: [[M:%.*]] = and i32 [[X:%.*]], 16777215
; CHECK-NEXT: [[R:%.*]] = uitofp i32 [[M]] to double
; CHECK-NEXT: [[R:%.*]] = uitofp nneg i32 [[M]] to double
; CHECK-NEXT: ret double [[R]]
;
%m = and i32 %x, 16777215
Expand All @@ -326,7 +326,7 @@ define double @masked_uint_to_fpext1(i32 %x) {
define double @masked_uint_to_fpext2(i32 %x) {
; CHECK-LABEL: @masked_uint_to_fpext2(
; CHECK-NEXT: [[M:%.*]] = lshr i32 [[X:%.*]], 8
; CHECK-NEXT: [[R:%.*]] = uitofp i32 [[M]] to double
; CHECK-NEXT: [[R:%.*]] = uitofp nneg i32 [[M]] to double
; CHECK-NEXT: ret double [[R]]
;
%m = lshr i32 %x, 8
Expand All @@ -338,7 +338,7 @@ define double @masked_uint_to_fpext2(i32 %x) {
define double @masked_uint_to_fpext3(i32 %x) {
; CHECK-LABEL: @masked_uint_to_fpext3(
; CHECK-NEXT: [[M:%.*]] = lshr i32 [[X:%.*]], 7
; CHECK-NEXT: [[F:%.*]] = uitofp i32 [[M]] to float
; CHECK-NEXT: [[F:%.*]] = uitofp nneg i32 [[M]] to float
; CHECK-NEXT: [[R:%.*]] = fpext float [[F]] to double
; CHECK-NEXT: ret double [[R]]
;
Expand Down
119 changes: 119 additions & 0 deletions llvm/test/Transforms/InstCombine/known-fpclass-reduce-signbit.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
; RUN: opt < %s -S -passes=instcombine | FileCheck %s

define i1 @vector_reduce_maximum_signbit(<4 x double> nofpclass(nan nzero) %x) {
; CHECK-LABEL: define i1 @vector_reduce_maximum_signbit
; CHECK-SAME: (<4 x double> nofpclass(nan nzero) [[X:%.*]]) {
; CHECK-NEXT: ret i1 true
;
%x.abs = call <4 x double> @llvm.fabs.v4f64(<4 x double> %x)
%op = call double @llvm.vector.reduce.fmaximum.v4f64(<4 x double> %x.abs)
%cmp = fcmp oge double %op, 0.0
ret i1 %cmp
}

define i1 @vector_reduce_maximum_signbit_fail_maybe_nan(<4 x double> nofpclass(nzero) %x) {
; CHECK-LABEL: define i1 @vector_reduce_maximum_signbit_fail_maybe_nan
; CHECK-SAME: (<4 x double> nofpclass(nzero) [[X:%.*]]) {
; CHECK-NEXT: [[X_ABS:%.*]] = call <4 x double> @llvm.fabs.v4f64(<4 x double> [[X]])
; CHECK-NEXT: [[OP:%.*]] = call double @llvm.vector.reduce.fmaximum.v4f64(<4 x double> [[X_ABS]])
; CHECK-NEXT: [[CMP:%.*]] = fcmp oge double [[OP]], 0.000000e+00
; CHECK-NEXT: ret i1 [[CMP]]
;
%x.abs = call <4 x double> @llvm.fabs.v4f64(<4 x double> %x)
%op = call double @llvm.vector.reduce.fmaximum.v4f64(<4 x double> %x.abs)
%cmp = fcmp oge double %op, 0.0
ret i1 %cmp
}


define i1 @vector_reduce_minimum_signbit(<4 x double> nofpclass(nan nzero) %x) {
; CHECK-LABEL: define i1 @vector_reduce_minimum_signbit
; CHECK-SAME: (<4 x double> nofpclass(nan nzero) [[X:%.*]]) {
; CHECK-NEXT: ret i1 true
;
%x.abs = call <4 x double> @llvm.fabs.v4f64(<4 x double> %x)
%op = call double @llvm.vector.reduce.fminimum.v4f64(<4 x double> %x.abs)
%cmp = fcmp oge double %op, 0.0
ret i1 %cmp
}

define i1 @vector_reduce_minimum_signbit_fail_maybe_nan(<4 x double> nofpclass(nzero) %x) {
; CHECK-LABEL: define i1 @vector_reduce_minimum_signbit_fail_maybe_nan
; CHECK-SAME: (<4 x double> nofpclass(nzero) [[X:%.*]]) {
; CHECK-NEXT: [[X_ABS:%.*]] = call <4 x double> @llvm.fabs.v4f64(<4 x double> [[X]])
; CHECK-NEXT: [[OP:%.*]] = call double @llvm.vector.reduce.fminimum.v4f64(<4 x double> [[X_ABS]])
; CHECK-NEXT: [[CMP:%.*]] = fcmp oge double [[OP]], 0.000000e+00
; CHECK-NEXT: ret i1 [[CMP]]
;
%x.abs = call <4 x double> @llvm.fabs.v4f64(<4 x double> %x)
%op = call double @llvm.vector.reduce.fminimum.v4f64(<4 x double> %x.abs)
%cmp = fcmp oge double %op, 0.0
ret i1 %cmp
}

define i1 @vector_reduce_max_signbit(<4 x double> nofpclass(nan nzero) %x) {
; CHECK-LABEL: define i1 @vector_reduce_max_signbit
; CHECK-SAME: (<4 x double> nofpclass(nan nzero) [[X:%.*]]) {
; CHECK-NEXT: ret i1 true
;
%x.abs = call <4 x double> @llvm.fabs.v4f64(<4 x double> %x)
%op = call double @llvm.vector.reduce.fmax.v4f64(<4 x double> %x.abs)
%cmp = fcmp oge double %op, 0.0
ret i1 %cmp
}

define i1 @vector_reduce_max_signbit_fail_maybe_nan(<4 x double> nofpclass(nzero) %x) {
; CHECK-LABEL: define i1 @vector_reduce_max_signbit_fail_maybe_nan
; CHECK-SAME: (<4 x double> nofpclass(nzero) [[X:%.*]]) {
; CHECK-NEXT: [[X_ABS:%.*]] = call <4 x double> @llvm.fabs.v4f64(<4 x double> [[X]])
; CHECK-NEXT: [[OP:%.*]] = call double @llvm.vector.reduce.fmax.v4f64(<4 x double> [[X_ABS]])
; CHECK-NEXT: [[CMP:%.*]] = fcmp oge double [[OP]], 0.000000e+00
; CHECK-NEXT: ret i1 [[CMP]]
;
%x.abs = call <4 x double> @llvm.fabs.v4f64(<4 x double> %x)
%op = call double @llvm.vector.reduce.fmax.v4f64(<4 x double> %x.abs)
%cmp = fcmp oge double %op, 0.0
ret i1 %cmp
}


define i1 @vector_reduce_min_signbit(<4 x double> nofpclass(nan nzero) %x) {
; CHECK-LABEL: define i1 @vector_reduce_min_signbit
; CHECK-SAME: (<4 x double> nofpclass(nan nzero) [[X:%.*]]) {
; CHECK-NEXT: ret i1 true
;
%x.abs = call <4 x double> @llvm.fabs.v4f64(<4 x double> %x)
%op = call double @llvm.vector.reduce.fmin.v4f64(<4 x double> %x.abs)
%cmp = fcmp oge double %op, 0.0
ret i1 %cmp
}

define i1 @vector_reduce_min_signbit_fail_maybe_nan(<4 x double> nofpclass(nzero) %x) {
; CHECK-LABEL: define i1 @vector_reduce_min_signbit_fail_maybe_nan
; CHECK-SAME: (<4 x double> nofpclass(nzero) [[X:%.*]]) {
; CHECK-NEXT: [[X_ABS:%.*]] = call <4 x double> @llvm.fabs.v4f64(<4 x double> [[X]])
; CHECK-NEXT: [[OP:%.*]] = call double @llvm.vector.reduce.fmin.v4f64(<4 x double> [[X_ABS]])
; CHECK-NEXT: [[CMP:%.*]] = fcmp oge double [[OP]], 0.000000e+00
; CHECK-NEXT: ret i1 [[CMP]]
;
%x.abs = call <4 x double> @llvm.fabs.v4f64(<4 x double> %x)
%op = call double @llvm.vector.reduce.fmin.v4f64(<4 x double> %x.abs)
%cmp = fcmp oge double %op, 0.0
ret i1 %cmp
}



define i1 @vector_reduce_min_signbit_nnan_from_fmf(<4 x double> nofpclass(nzero) %x) {
; CHECK-LABEL: define i1 @vector_reduce_min_signbit_nnan_from_fmf
; CHECK-SAME: (<4 x double> nofpclass(nzero) [[X:%.*]]) {
; CHECK-NEXT: ret i1 true
;
%x.abs = call <4 x double> @llvm.fabs.v4f64(<4 x double> %x)
%op = call nnan double @llvm.vector.reduce.fmin.v4f64(<4 x double> %x.abs)
%cmp = fcmp oge double %op, 0.0
ret i1 %cmp
}


10 changes: 5 additions & 5 deletions llvm/test/Transforms/InstCombine/minmax-fold.ll
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ define i64 @t9(i32 %a) {
define float @t10(i32 %x) {
; CHECK-LABEL: @t10(
; CHECK-NEXT: [[R1:%.*]] = call i32 @llvm.smax.i32(i32 [[X:%.*]], i32 255)
; CHECK-NEXT: [[R:%.*]] = sitofp i32 [[R1]] to float
; CHECK-NEXT: [[R:%.*]] = uitofp nneg i32 [[R1]] to float
; CHECK-NEXT: ret float [[R]]
;
%f_x = sitofp i32 %x to float
Expand All @@ -143,7 +143,7 @@ define float @t10(i32 %x) {
define float @t11(i64 %x) {
; CHECK-LABEL: @t11(
; CHECK-NEXT: [[R1:%.*]] = call i64 @llvm.smax.i64(i64 [[X:%.*]], i64 255)
; CHECK-NEXT: [[R:%.*]] = sitofp i64 [[R1]] to float
; CHECK-NEXT: [[R:%.*]] = uitofp nneg i64 [[R1]] to float
; CHECK-NEXT: ret float [[R]]
;
%f_x = sitofp i64 %x to float
Expand Down Expand Up @@ -526,7 +526,7 @@ falselabel:
define double @PR31751_umin1(i32 %x) {
; CHECK-LABEL: @PR31751_umin1(
; CHECK-NEXT: [[SEL:%.*]] = call i32 @llvm.umin.i32(i32 [[X:%.*]], i32 2147483647)
; CHECK-NEXT: [[CONV:%.*]] = sitofp i32 [[SEL]] to double
; CHECK-NEXT: [[CONV:%.*]] = uitofp nneg i32 [[SEL]] to double
; CHECK-NEXT: ret double [[CONV]]
;
%cmp = icmp slt i32 %x, 0
Expand All @@ -538,7 +538,7 @@ define double @PR31751_umin1(i32 %x) {
define double @PR31751_umin2(i32 %x) {
; CHECK-LABEL: @PR31751_umin2(
; CHECK-NEXT: [[SEL:%.*]] = call i32 @llvm.umin.i32(i32 [[X:%.*]], i32 2147483647)
; CHECK-NEXT: [[CONV:%.*]] = sitofp i32 [[SEL]] to double
; CHECK-NEXT: [[CONV:%.*]] = uitofp nneg i32 [[SEL]] to double
; CHECK-NEXT: ret double [[CONV]]
;
%cmp = icmp ult i32 %x, 2147483647
Expand All @@ -550,7 +550,7 @@ define double @PR31751_umin2(i32 %x) {
define double @PR31751_umin3(i32 %x) {
; CHECK-LABEL: @PR31751_umin3(
; CHECK-NEXT: [[SEL:%.*]] = call i32 @llvm.umin.i32(i32 [[X:%.*]], i32 2147483647)
; CHECK-NEXT: [[CONV:%.*]] = sitofp i32 [[SEL]] to double
; CHECK-NEXT: [[CONV:%.*]] = uitofp nneg i32 [[SEL]] to double
; CHECK-NEXT: ret double [[CONV]]
;
%cmp = icmp ugt i32 %x, 2147483647
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/Transforms/InstCombine/minmax-fp.ll
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ define double @t16(i32 %x) {
define double @t17(i32 %x) {
; CHECK-LABEL: @t17(
; CHECK-NEXT: [[SEL1:%.*]] = call i32 @llvm.smax.i32(i32 [[X:%.*]], i32 2)
; CHECK-NEXT: [[SEL:%.*]] = sitofp i32 [[SEL1]] to double
; CHECK-NEXT: [[SEL:%.*]] = uitofp nneg i32 [[SEL1]] to double
; CHECK-NEXT: ret double [[SEL]]
;
%cmp = icmp sgt i32 %x, 2
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/Transforms/InstCombine/pr27236.ll
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
define float @test1(i32 %scale) {
; CHECK-LABEL: @test1(
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.smax.i32(i32 [[SCALE:%.*]], i32 1)
; CHECK-NEXT: [[TMP2:%.*]] = sitofp i32 [[TMP1]] to float
; CHECK-NEXT: [[TMP2:%.*]] = uitofp nneg i32 [[TMP1]] to float
; CHECK-NEXT: ret float [[TMP2]]
;
%1 = icmp sgt i32 1, %scale
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/Transforms/InstCombine/sitofp.ll
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ define i25 @consider_lowbits_masked_input(i25 %A) {
define i32 @overflow_masked_input(i32 %A) {
; CHECK-LABEL: @overflow_masked_input(
; CHECK-NEXT: [[M:%.*]] = and i32 [[A:%.*]], 16777217
; CHECK-NEXT: [[B:%.*]] = uitofp i32 [[M]] to float
; CHECK-NEXT: [[B:%.*]] = uitofp nneg i32 [[M]] to float
; CHECK-NEXT: [[C:%.*]] = fptoui float [[B]] to i32
; CHECK-NEXT: ret i32 [[C]]
;
Expand Down
100 changes: 100 additions & 0 deletions llvm/test/Transforms/InstSimplify/known-never-infinity.ll
Original file line number Diff line number Diff line change
Expand Up @@ -1109,6 +1109,106 @@ define float @fcmp_ult_neginf_implies_class_assert(float %arg) {
ret float %mul_by_zero
}

define i1 @isKnownNeverInfinity_vector_reduce_maximum(<4 x double> %x) {
; CHECK-LABEL: define i1 @isKnownNeverInfinity_vector_reduce_maximum
; CHECK-SAME: (<4 x double> [[X:%.*]]) {
; CHECK-NEXT: ret i1 true
;
%ninf.x = fadd ninf <4 x double> %x, <double 1.0, double 1.0, double 1.0, double 1.0>
%op = call double @llvm.vector.reduce.fmaximum.v4f64(<4 x double> %ninf.x)
%cmp = fcmp une double %op, 0x7ff0000000000000
ret i1 %cmp
}

define i1 @isKnownNeverInfinity_vector_reduce_maximum_fail(<4 x double> %x) {
; CHECK-LABEL: define i1 @isKnownNeverInfinity_vector_reduce_maximum_fail
; CHECK-SAME: (<4 x double> [[X:%.*]]) {
; CHECK-NEXT: [[NINF_X:%.*]] = fadd <4 x double> [[X]], <double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00>
; CHECK-NEXT: [[OP:%.*]] = call double @llvm.vector.reduce.fmaximum.v4f64(<4 x double> [[NINF_X]])
; CHECK-NEXT: [[CMP:%.*]] = fcmp une double [[OP]], 0x7FF0000000000000
; CHECK-NEXT: ret i1 [[CMP]]
;
%ninf.x = fadd <4 x double> %x, <double 1.0, double 1.0, double 1.0, double 1.0>
%op = call double @llvm.vector.reduce.fmaximum.v4f64(<4 x double> %ninf.x)
%cmp = fcmp une double %op, 0x7ff0000000000000
ret i1 %cmp
}

define i1 @isKnownNeverInfinity_vector_reduce_minimum(<4 x double> %x) {
; CHECK-LABEL: define i1 @isKnownNeverInfinity_vector_reduce_minimum
; CHECK-SAME: (<4 x double> [[X:%.*]]) {
; CHECK-NEXT: ret i1 true
;
%ninf.x = fadd ninf <4 x double> %x, <double 1.0, double 1.0, double 1.0, double 1.0>
%op = call double @llvm.vector.reduce.fminimum.v4f64(<4 x double> %ninf.x)
%cmp = fcmp une double %op, 0x7ff0000000000000
ret i1 %cmp
}

define i1 @isKnownNeverInfinity_vector_reduce_minimum_fail(<4 x double> %x) {
; CHECK-LABEL: define i1 @isKnownNeverInfinity_vector_reduce_minimum_fail
; CHECK-SAME: (<4 x double> [[X:%.*]]) {
; CHECK-NEXT: [[NINF_X:%.*]] = fadd <4 x double> [[X]], <double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00>
; CHECK-NEXT: [[OP:%.*]] = call double @llvm.vector.reduce.fminimum.v4f64(<4 x double> [[NINF_X]])
; CHECK-NEXT: [[CMP:%.*]] = fcmp une double [[OP]], 0x7FF0000000000000
; CHECK-NEXT: ret i1 [[CMP]]
;
%ninf.x = fadd <4 x double> %x, <double 1.0, double 1.0, double 1.0, double 1.0>
%op = call double @llvm.vector.reduce.fminimum.v4f64(<4 x double> %ninf.x)
%cmp = fcmp une double %op, 0x7ff0000000000000
ret i1 %cmp
}

define i1 @isKnownNeverInfinity_vector_reduce_fmax(<4 x double> %x) {
; CHECK-LABEL: define i1 @isKnownNeverInfinity_vector_reduce_fmax
; CHECK-SAME: (<4 x double> [[X:%.*]]) {
; CHECK-NEXT: ret i1 true
;
%ninf.x = fadd ninf <4 x double> %x, <double 1.0, double 1.0, double 1.0, double 1.0>
%op = call double @llvm.vector.reduce.fmax.v4f64(<4 x double> %ninf.x)
%cmp = fcmp une double %op, 0x7ff0000000000000
ret i1 %cmp
}

define i1 @isKnownNeverInfinity_vector_reduce_fmax_fail(<4 x double> %x) {
; CHECK-LABEL: define i1 @isKnownNeverInfinity_vector_reduce_fmax_fail
; CHECK-SAME: (<4 x double> [[X:%.*]]) {
; CHECK-NEXT: [[NINF_X:%.*]] = fadd <4 x double> [[X]], <double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00>
; CHECK-NEXT: [[OP:%.*]] = call double @llvm.vector.reduce.fmax.v4f64(<4 x double> [[NINF_X]])
; CHECK-NEXT: [[CMP:%.*]] = fcmp une double [[OP]], 0x7FF0000000000000
; CHECK-NEXT: ret i1 [[CMP]]
;
%ninf.x = fadd <4 x double> %x, <double 1.0, double 1.0, double 1.0, double 1.0>
%op = call double @llvm.vector.reduce.fmax.v4f64(<4 x double> %ninf.x)
%cmp = fcmp une double %op, 0x7ff0000000000000
ret i1 %cmp
}

define i1 @isKnownNeverInfinity_vector_reduce_fmin(<4 x double> %x) {
; CHECK-LABEL: define i1 @isKnownNeverInfinity_vector_reduce_fmin
; CHECK-SAME: (<4 x double> [[X:%.*]]) {
; CHECK-NEXT: ret i1 true
;
%ninf.x = fadd ninf <4 x double> %x, <double 1.0, double 1.0, double 1.0, double 1.0>
%op = call double @llvm.vector.reduce.fmin.v4f64(<4 x double> %ninf.x)
%cmp = fcmp une double %op, 0x7ff0000000000000
ret i1 %cmp
}

define i1 @isKnownNeverInfinity_vector_reduce_fmin_fail(<4 x double> %x) {
; CHECK-LABEL: define i1 @isKnownNeverInfinity_vector_reduce_fmin_fail
; CHECK-SAME: (<4 x double> [[X:%.*]]) {
; CHECK-NEXT: [[NINF_X:%.*]] = fadd <4 x double> [[X]], <double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00>
; CHECK-NEXT: [[OP:%.*]] = call double @llvm.vector.reduce.fmin.v4f64(<4 x double> [[NINF_X]])
; CHECK-NEXT: [[CMP:%.*]] = fcmp une double [[OP]], 0x7FF0000000000000
; CHECK-NEXT: ret i1 [[CMP]]
;
%ninf.x = fadd <4 x double> %x, <double 1.0, double 1.0, double 1.0, double 1.0>
%op = call double @llvm.vector.reduce.fmin.v4f64(<4 x double> %ninf.x)
%cmp = fcmp une double %op, 0x7ff0000000000000
ret i1 %cmp
}

declare double @llvm.arithmetic.fence.f64(double)
declare double @llvm.canonicalize.f64(double)
declare double @llvm.ceil.f64(double)
Expand Down
88 changes: 44 additions & 44 deletions llvm/test/Transforms/LoopVectorize/AArch64/sve-select-cmp.ll

Large diffs are not rendered by default.

742 changes: 559 additions & 183 deletions llvm/test/Transforms/LoopVectorize/RISCV/select-cmp-reduction.ll

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions llvm/test/Transforms/LoopVectorize/X86/float-induction-x86.ll
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ define void @fp_iv_loop1(ptr noalias nocapture %A, i32 %N) #0 {
; AUTO_VEC-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[FOR_BODY:%.*]], label [[VECTOR_PH:%.*]]
; AUTO_VEC: vector.ph:
; AUTO_VEC-NEXT: [[N_VEC:%.*]] = and i64 [[ZEXT]], 2147483616
; AUTO_VEC-NEXT: [[DOTCAST:%.*]] = sitofp i64 [[N_VEC]] to float
; AUTO_VEC-NEXT: [[DOTCAST:%.*]] = uitofp nneg i64 [[N_VEC]] to float
; AUTO_VEC-NEXT: [[TMP0:%.*]] = fmul fast float [[DOTCAST]], 5.000000e-01
; AUTO_VEC-NEXT: [[IND_END:%.*]] = fadd fast float [[TMP0]], 1.000000e+00
; AUTO_VEC-NEXT: br label [[VECTOR_BODY:%.*]]
Expand Down Expand Up @@ -201,7 +201,7 @@ define double @external_use_with_fast_math(ptr %a, i64 %n) {
; AUTO_VEC-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[FOR_BODY:%.*]], label [[VECTOR_PH:%.*]]
; AUTO_VEC: vector.ph:
; AUTO_VEC-NEXT: [[N_VEC:%.*]] = and i64 [[SMAX]], 9223372036854775792
; AUTO_VEC-NEXT: [[DOTCAST:%.*]] = sitofp i64 [[N_VEC]] to double
; AUTO_VEC-NEXT: [[DOTCAST:%.*]] = uitofp nneg i64 [[N_VEC]] to double
; AUTO_VEC-NEXT: [[TMP0:%.*]] = fmul fast double [[DOTCAST]], 3.000000e+00
; AUTO_VEC-NEXT: br label [[VECTOR_BODY:%.*]]
; AUTO_VEC: vector.body:
Expand Down Expand Up @@ -366,7 +366,7 @@ define void @fadd_reassoc_FMF(ptr nocapture %p, i32 %N) {
; AUTO_VEC-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[FOR_BODY:%.*]], label [[VECTOR_PH:%.*]]
; AUTO_VEC: vector.ph:
; AUTO_VEC-NEXT: [[N_VEC:%.*]] = and i64 [[TMP0]], 4294967264
; AUTO_VEC-NEXT: [[DOTCAST:%.*]] = sitofp i64 [[N_VEC]] to float
; AUTO_VEC-NEXT: [[DOTCAST:%.*]] = uitofp nneg i64 [[N_VEC]] to float
; AUTO_VEC-NEXT: [[TMP1:%.*]] = fmul reassoc float [[DOTCAST]], 4.200000e+01
; AUTO_VEC-NEXT: [[IND_END:%.*]] = fadd reassoc float [[TMP1]], 1.000000e+00
; AUTO_VEC-NEXT: br label [[VECTOR_BODY:%.*]]
Expand Down
233 changes: 233 additions & 0 deletions llvm/test/Transforms/LoopVectorize/blend-in-header.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,233 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
; RUN: opt -p loop-vectorize -force-vector-width=4 -force-vector-interleave=1 -S %s | FileCheck %s

target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128-ni:1-p2:32:8:8:32-ni:2"

; Test with blend recipe in header VPBB, from
; https://github.com/llvm/llvm-project/issues/88297.
define i64 @pr88297() {
; CHECK-LABEL: define i64 @pr88297() {
; CHECK-NEXT: entry:
; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
; CHECK: vector.ph:
; CHECK-NEXT: br label [[VECTOR_BODY:%.*]]
; CHECK: vector.body:
; CHECK-NEXT: [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 4
; CHECK-NEXT: [[TMP0:%.*]] = icmp eq i32 [[INDEX_NEXT]], 1000
; CHECK-NEXT: br i1 [[TMP0]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
; CHECK: middle.block:
; CHECK-NEXT: br i1 false, label [[EXIT:%.*]], label [[SCALAR_PH]]
; CHECK: scalar.ph:
; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i32 [ 1000, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
; CHECK: loop.header:
; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
; CHECK-NEXT: br i1 false, label [[LOOP_LATCH]], label [[THEN:%.*]]
; CHECK: then:
; CHECK-NEXT: br label [[LOOP_LATCH]]
; CHECK: loop.latch:
; CHECK-NEXT: [[R:%.*]] = phi i64 [ 1, [[THEN]] ], [ 0, [[LOOP_HEADER]] ]
; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1
; CHECK-NEXT: [[ICMP:%.*]] = icmp sgt i32 [[IV]], 1000
; CHECK-NEXT: br i1 [[ICMP]], label [[EXIT]], label [[LOOP_HEADER]], !llvm.loop [[LOOP3:![0-9]+]]
; CHECK: exit:
; CHECK-NEXT: [[R_LCSSA:%.*]] = phi i64 [ [[R]], [[LOOP_LATCH]] ], [ 1, [[MIDDLE_BLOCK]] ]
; CHECK-NEXT: ret i64 [[R_LCSSA]]
;
entry:
br label %loop.header

loop.header:
%iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
br i1 false, label %loop.latch, label %then

then:
br label %loop.latch

loop.latch:
%r = phi i64 [ 1, %then ], [ 0, %loop.header ]
%iv.next = add i32 %iv, 1
%icmp = icmp sgt i32 %iv, 1000
br i1 %icmp, label %exit, label %loop.header

exit:
%r.lcssa = phi i64 [ %r, %loop.latch ]
ret i64 %r.lcssa
}

define i64 @pr88297_incoming_ops_reordered() {
; CHECK-LABEL: define i64 @pr88297_incoming_ops_reordered() {
; CHECK-NEXT: entry:
; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
; CHECK: vector.ph:
; CHECK-NEXT: br label [[VECTOR_BODY:%.*]]
; CHECK: vector.body:
; CHECK-NEXT: [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 4
; CHECK-NEXT: [[TMP0:%.*]] = icmp eq i32 [[INDEX_NEXT]], 1000
; CHECK-NEXT: br i1 [[TMP0]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP4:![0-9]+]]
; CHECK: middle.block:
; CHECK-NEXT: br i1 false, label [[EXIT:%.*]], label [[SCALAR_PH]]
; CHECK: scalar.ph:
; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i32 [ 1000, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
; CHECK: loop.header:
; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
; CHECK-NEXT: br i1 false, label [[LOOP_LATCH]], label [[THEN:%.*]]
; CHECK: then:
; CHECK-NEXT: br label [[LOOP_LATCH]]
; CHECK: loop.latch:
; CHECK-NEXT: [[R:%.*]] = phi i64 [ 0, [[LOOP_HEADER]] ], [ 1, [[THEN]] ]
; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1
; CHECK-NEXT: [[ICMP:%.*]] = icmp sgt i32 [[IV]], 1000
; CHECK-NEXT: br i1 [[ICMP]], label [[EXIT]], label [[LOOP_HEADER]], !llvm.loop [[LOOP5:![0-9]+]]
; CHECK: exit:
; CHECK-NEXT: [[R_LCSSA:%.*]] = phi i64 [ [[R]], [[LOOP_LATCH]] ], [ 1, [[MIDDLE_BLOCK]] ]
; CHECK-NEXT: ret i64 [[R_LCSSA]]
;
entry:
br label %loop.header

loop.header:
%iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
br i1 false, label %loop.latch, label %then

then:
br label %loop.latch

loop.latch:
%r = phi i64 [ 0, %loop.header ], [ 1, %then ]
%iv.next = add i32 %iv, 1
%icmp = icmp sgt i32 %iv, 1000
br i1 %icmp, label %exit, label %loop.header

exit:
%r.lcssa = phi i64 [ %r, %loop.latch ]
ret i64 %r.lcssa
}

define i64 @invar_cond(i1 %c) {
; CHECK-LABEL: define i64 @invar_cond(
; CHECK-SAME: i1 [[C:%.*]]) {
; CHECK-NEXT: entry:
; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
; CHECK: vector.ph:
; CHECK-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement <4 x i1> poison, i1 [[C]], i64 0
; CHECK-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector <4 x i1> [[BROADCAST_SPLATINSERT]], <4 x i1> poison, <4 x i32> zeroinitializer
; CHECK-NEXT: br label [[VECTOR_BODY:%.*]]
; CHECK: vector.body:
; CHECK-NEXT: [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
; CHECK-NEXT: [[PREDPHI:%.*]] = select <4 x i1> [[BROADCAST_SPLAT]], <4 x i64> zeroinitializer, <4 x i64> <i64 1, i64 1, i64 1, i64 1>
; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 4
; CHECK-NEXT: [[TMP0:%.*]] = icmp eq i32 [[INDEX_NEXT]], 1000
; CHECK-NEXT: br i1 [[TMP0]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP6:![0-9]+]]
; CHECK: middle.block:
; CHECK-NEXT: [[TMP1:%.*]] = extractelement <4 x i64> [[PREDPHI]], i32 3
; CHECK-NEXT: br i1 false, label [[EXIT:%.*]], label [[SCALAR_PH]]
; CHECK: scalar.ph:
; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i32 [ 1000, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
; CHECK: loop.header:
; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
; CHECK-NEXT: br i1 [[C]], label [[LOOP_LATCH]], label [[THEN:%.*]]
; CHECK: then:
; CHECK-NEXT: br label [[LOOP_LATCH]]
; CHECK: loop.latch:
; CHECK-NEXT: [[R:%.*]] = phi i64 [ 1, [[THEN]] ], [ 0, [[LOOP_HEADER]] ]
; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1
; CHECK-NEXT: [[ICMP:%.*]] = icmp sgt i32 [[IV]], 1000
; CHECK-NEXT: br i1 [[ICMP]], label [[EXIT]], label [[LOOP_HEADER]], !llvm.loop [[LOOP7:![0-9]+]]
; CHECK: exit:
; CHECK-NEXT: [[R_LCSSA:%.*]] = phi i64 [ [[R]], [[LOOP_LATCH]] ], [ [[TMP1]], [[MIDDLE_BLOCK]] ]
; CHECK-NEXT: ret i64 [[R_LCSSA]]
;
entry:
br label %loop.header

loop.header:
%iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
br i1 %c, label %loop.latch, label %then

then:
br label %loop.latch

loop.latch:
%r = phi i64 [ 1, %then ], [ 0, %loop.header ]
%iv.next = add i32 %iv, 1
%icmp = icmp sgt i32 %iv, 1000
br i1 %icmp, label %exit, label %loop.header

exit:
%r.lcssa = phi i64 [ %r, %loop.latch ]
ret i64 %r.lcssa
}

define i64 @invar_cond_incoming_ops_reordered(i1 %c) {
; CHECK-LABEL: define i64 @invar_cond_incoming_ops_reordered(
; CHECK-SAME: i1 [[C:%.*]]) {
; CHECK-NEXT: entry:
; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
; CHECK: vector.ph:
; CHECK-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement <4 x i1> poison, i1 [[C]], i64 0
; CHECK-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector <4 x i1> [[BROADCAST_SPLATINSERT]], <4 x i1> poison, <4 x i32> zeroinitializer
; CHECK-NEXT: br label [[VECTOR_BODY:%.*]]
; CHECK: vector.body:
; CHECK-NEXT: [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
; CHECK-NEXT: [[TMP1:%.*]] = xor <4 x i1> [[BROADCAST_SPLAT]], <i1 true, i1 true, i1 true, i1 true>
; CHECK-NEXT: [[PREDPHI:%.*]] = select <4 x i1> [[TMP1]], <4 x i64> <i64 1, i64 1, i64 1, i64 1>, <4 x i64> zeroinitializer
; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 4
; CHECK-NEXT: [[TMP0:%.*]] = icmp eq i32 [[INDEX_NEXT]], 1000
; CHECK-NEXT: br i1 [[TMP0]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP8:![0-9]+]]
; CHECK: middle.block:
; CHECK-NEXT: [[TMP2:%.*]] = extractelement <4 x i64> [[PREDPHI]], i32 3
; CHECK-NEXT: br i1 false, label [[EXIT:%.*]], label [[SCALAR_PH]]
; CHECK: scalar.ph:
; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i32 [ 1000, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
; CHECK: loop.header:
; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
; CHECK-NEXT: br i1 [[C]], label [[LOOP_LATCH]], label [[THEN:%.*]]
; CHECK: then:
; CHECK-NEXT: br label [[LOOP_LATCH]]
; CHECK: loop.latch:
; CHECK-NEXT: [[R:%.*]] = phi i64 [ 0, [[LOOP_HEADER]] ], [ 1, [[THEN]] ]
; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1
; CHECK-NEXT: [[ICMP:%.*]] = icmp sgt i32 [[IV]], 1000
; CHECK-NEXT: br i1 [[ICMP]], label [[EXIT]], label [[LOOP_HEADER]], !llvm.loop [[LOOP9:![0-9]+]]
; CHECK: exit:
; CHECK-NEXT: [[R_LCSSA:%.*]] = phi i64 [ [[R]], [[LOOP_LATCH]] ], [ [[TMP2]], [[MIDDLE_BLOCK]] ]
; CHECK-NEXT: ret i64 [[R_LCSSA]]
;
entry:
br label %loop.header

loop.header:
%iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
br i1 %c, label %loop.latch, label %then

then:
br label %loop.latch

loop.latch:
%r = phi i64 [ 0, %loop.header ], [ 1, %then ]
%iv.next = add i32 %iv, 1
%icmp = icmp sgt i32 %iv, 1000
br i1 %icmp, label %exit, label %loop.header

exit:
%r.lcssa = phi i64 [ %r, %loop.latch ]
ret i64 %r.lcssa
}
;.
; CHECK: [[LOOP0]] = distinct !{[[LOOP0]], [[META1:![0-9]+]], [[META2:![0-9]+]]}
; CHECK: [[META1]] = !{!"llvm.loop.isvectorized", i32 1}
; CHECK: [[META2]] = !{!"llvm.loop.unroll.runtime.disable"}
; CHECK: [[LOOP3]] = distinct !{[[LOOP3]], [[META2]], [[META1]]}
; CHECK: [[LOOP4]] = distinct !{[[LOOP4]], [[META1]], [[META2]]}
; CHECK: [[LOOP5]] = distinct !{[[LOOP5]], [[META2]], [[META1]]}
; CHECK: [[LOOP6]] = distinct !{[[LOOP6]], [[META1]], [[META2]]}
; CHECK: [[LOOP7]] = distinct !{[[LOOP7]], [[META2]], [[META1]]}
; CHECK: [[LOOP8]] = distinct !{[[LOOP8]], [[META1]], [[META2]]}
; CHECK: [[LOOP9]] = distinct !{[[LOOP9]], [[META2]], [[META1]]}
;.

Large diffs are not rendered by default.

56 changes: 28 additions & 28 deletions llvm/test/Transforms/LoopVectorize/float-induction.ll

Large diffs are not rendered by default.

210 changes: 131 additions & 79 deletions llvm/test/Transforms/LoopVectorize/select-cmp-predicated.ll

Large diffs are not rendered by default.

146 changes: 72 additions & 74 deletions llvm/test/Transforms/LoopVectorize/select-cmp.ll

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,26 @@ define i64 @pr62565_incoming_value_known_undef(i64 %a, ptr %src) {
; CHECK-NEXT: entry:
; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
; CHECK: vector.ph:
; CHECK-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement <2 x i64> poison, i64 [[A]], i64 0
; CHECK-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector <2 x i64> [[BROADCAST_SPLATINSERT]], <2 x i64> poison, <2 x i32> zeroinitializer
; CHECK-NEXT: br label [[VECTOR_BODY:%.*]]
; CHECK: vector.body:
; CHECK-NEXT: [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
; CHECK-NEXT: [[VEC_PHI:%.*]] = phi <2 x i1> [ zeroinitializer, [[VECTOR_PH]] ], [ [[TMP4:%.*]], [[VECTOR_BODY]] ]
; CHECK-NEXT: [[VEC_PHI:%.*]] = phi <2 x i64> [ undef, [[VECTOR_PH]] ], [ [[TMP4:%.*]], [[VECTOR_BODY]] ]
; CHECK-NEXT: [[OFFSET_IDX:%.*]] = add i32 1, [[INDEX]]
; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[OFFSET_IDX]], 0
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i32 [[TMP0]]
; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i32 0
; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <2 x i32>, ptr [[TMP2]], align 4
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq <2 x i32> [[WIDE_LOAD]], <i32 1, i32 1>
; CHECK-NEXT: [[NOT:%*]] = xor <2 x i1> [[TMP3]], <i1 true, i1 true>
; CHECK-NEXT: [[TMP4]] = or <2 x i1> [[VEC_PHI]], [[NOT]]
; CHECK-NEXT: [[TMP4]] = select <2 x i1> [[TMP3]], <2 x i64> [[VEC_PHI]], <2 x i64> [[BROADCAST_SPLAT]]
; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 2
; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[INDEX_NEXT]], 32
; CHECK-NEXT: br i1 [[TMP5]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
; CHECK: middle.block:
; CHECK-NEXT: [[TMP6:%.*]] = call i1 @llvm.vector.reduce.or.v2i1(<2 x i1> [[TMP4]])
; CHECK-NEXT: [[FR_TMP6:%.*]] = freeze i1 [[TMP6]]
; CHECK-NEXT: [[RDX_SELECT:%.*]] = select i1 [[FR_TMP6]], i64 [[A]], i64 undef
; CHECK-NEXT: [[RDX_SELECT_CMP:%.*]] = icmp ne <2 x i64> [[TMP4]], undef
; CHECK-NEXT: [[TMP6:%.*]] = call i1 @llvm.vector.reduce.or.v2i1(<2 x i1> [[RDX_SELECT_CMP]])
; CHECK-NEXT: [[RDX_SELECT:%.*]] = select i1 [[TMP6]], i64 [[A]], i64 undef
; CHECK-NEXT: br i1 true, label [[EXIT:%.*]], label [[SCALAR_PH]]
; CHECK: scalar.ph:
; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i32 [ 33, [[MIDDLE_BLOCK]] ], [ 1, [[ENTRY:%.*]] ]
Expand Down Expand Up @@ -71,25 +72,26 @@ define i64 @pr62565_incoming_value_known_poison(i64 %a, ptr %src) {
; CHECK-NEXT: entry:
; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
; CHECK: vector.ph:
; CHECK-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement <2 x i64> poison, i64 [[A]], i64 0
; CHECK-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector <2 x i64> [[BROADCAST_SPLATINSERT]], <2 x i64> poison, <2 x i32> zeroinitializer
; CHECK-NEXT: br label [[VECTOR_BODY:%.*]]
; CHECK: vector.body:
; CHECK-NEXT: [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
; CHECK-NEXT: [[VEC_PHI:%.*]] = phi <2 x i1> [ zeroinitializer, [[VECTOR_PH]] ], [ [[TMP4:%.*]], [[VECTOR_BODY]] ]
; CHECK-NEXT: [[VEC_PHI:%.*]] = phi <2 x i64> [ poison, [[VECTOR_PH]] ], [ [[TMP4:%.*]], [[VECTOR_BODY]] ]
; CHECK-NEXT: [[OFFSET_IDX:%.*]] = add i32 1, [[INDEX]]
; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[OFFSET_IDX]], 0
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i32 [[TMP0]]
; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i32 0
; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <2 x i32>, ptr [[TMP2]], align 4
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq <2 x i32> [[WIDE_LOAD]], <i32 1, i32 1>
; CHECK-NEXT: [[NOT:%.*]] = xor <2 x i1> [[TMP3]], <i1 true, i1 true>
; CHECK-NEXT: [[TMP4]] = or <2 x i1> [[VEC_PHI]], [[NOT]]
; CHECK-NEXT: [[TMP4]] = select <2 x i1> [[TMP3]], <2 x i64> [[VEC_PHI]], <2 x i64> [[BROADCAST_SPLAT]]
; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 2
; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[INDEX_NEXT]], 32
; CHECK-NEXT: br i1 [[TMP5]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP4:![0-9]+]]
; CHECK: middle.block:
; CHECK-NEXT: [[TMP6:%.*]] = call i1 @llvm.vector.reduce.or.v2i1(<2 x i1> [[TMP4]])
; CHECK-NEXT: [[FR_TMP6:%.*]] = freeze i1 [[TMP6]]
; CHECK-NEXT: [[RDX_SELECT:%.*]] = select i1 [[FR_TMP6]], i64 [[A]], i64 poison
; CHECK-NEXT: [[RDX_SELECT_CMP:%.*]] = icmp ne <2 x i64> [[TMP4]], poison
; CHECK-NEXT: [[TMP6:%.*]] = call i1 @llvm.vector.reduce.or.v2i1(<2 x i1> [[RDX_SELECT_CMP]])
; CHECK-NEXT: [[RDX_SELECT:%.*]] = select i1 [[TMP6]], i64 [[A]], i64 poison
; CHECK-NEXT: br i1 true, label [[EXIT:%.*]], label [[SCALAR_PH]]
; CHECK: scalar.ph:
; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i32 [ 33, [[MIDDLE_BLOCK]] ], [ 1, [[ENTRY:%.*]] ]
Expand Down Expand Up @@ -134,25 +136,30 @@ define i64 @pr62565_incoming_value_may_be_poison(i64 %a, ptr %src, i64 %start) {
; CHECK-NEXT: entry:
; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
; CHECK: vector.ph:
; CHECK-NEXT: [[MINMAX_IDENT_SPLATINSERT:%.*]] = insertelement <2 x i64> poison, i64 [[START]], i64 0
; CHECK-NEXT: [[MINMAX_IDENT_SPLAT:%.*]] = shufflevector <2 x i64> [[MINMAX_IDENT_SPLATINSERT]], <2 x i64> poison, <2 x i32> zeroinitializer
; CHECK-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement <2 x i64> poison, i64 [[A]], i64 0
; CHECK-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector <2 x i64> [[BROADCAST_SPLATINSERT]], <2 x i64> poison, <2 x i32> zeroinitializer
; CHECK-NEXT: br label [[VECTOR_BODY:%.*]]
; CHECK: vector.body:
; CHECK-NEXT: [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
; CHECK-NEXT: [[VEC_PHI:%.*]] = phi <2 x i1> [ zeroinitializer, [[VECTOR_PH]] ], [ [[TMP4:%.*]], [[VECTOR_BODY]] ]
; CHECK-NEXT: [[VEC_PHI:%.*]] = phi <2 x i64> [ [[MINMAX_IDENT_SPLAT]], [[VECTOR_PH]] ], [ [[TMP4:%.*]], [[VECTOR_BODY]] ]
; CHECK-NEXT: [[OFFSET_IDX:%.*]] = add i32 1, [[INDEX]]
; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[OFFSET_IDX]], 0
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i32, ptr [[SRC]], i32 [[TMP0]]
; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i32 0
; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <2 x i32>, ptr [[TMP2]], align 4
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq <2 x i32> [[WIDE_LOAD]], <i32 1, i32 1>
; CHECK-NEXT: [[NOT:%.*]] = xor <2 x i1> [[TMP3]], <i1 true, i1 true>
; CHECK-NEXT: [[TMP4]] = or <2 x i1> [[VEC_PHI]], [[NOT]]
; CHECK-NEXT: [[TMP4]] = select <2 x i1> [[TMP3]], <2 x i64> [[VEC_PHI]], <2 x i64> [[BROADCAST_SPLAT]]
; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 2
; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[INDEX_NEXT]], 32
; CHECK-NEXT: br i1 [[TMP5]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP6:![0-9]+]]
; CHECK: middle.block:
; CHECK-NEXT: [[TMP6:%.*]] = call i1 @llvm.vector.reduce.or.v2i1(<2 x i1> [[TMP4]])
; CHECK-NEXT: [[FR_TMP6:%.*]] = freeze i1 [[TMP6]]
; CHECK-NEXT: [[RDX_SELECT:%.*]] = select i1 [[FR_TMP6]], i64 [[A]], i64 [[START]]
; CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <2 x i64> poison, i64 [[START]], i64 0
; CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector <2 x i64> [[DOTSPLATINSERT]], <2 x i64> poison, <2 x i32> zeroinitializer
; CHECK-NEXT: [[RDX_SELECT_CMP:%.*]] = icmp ne <2 x i64> [[TMP4]], [[DOTSPLAT]]
; CHECK-NEXT: [[TMP6:%.*]] = call i1 @llvm.vector.reduce.or.v2i1(<2 x i1> [[RDX_SELECT_CMP]])
; CHECK-NEXT: [[RDX_SELECT:%.*]] = select i1 [[TMP6]], i64 [[A]], i64 [[START]]
; CHECK-NEXT: br i1 true, label [[EXIT:%.*]], label [[SCALAR_PH]]
; CHECK: scalar.ph:
; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i32 [ 33, [[MIDDLE_BLOCK]] ], [ 1, [[ENTRY:%.*]] ]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
; RUN: opt < %s -S | FileCheck %s

define i32 @phi_after_label(i1 %cc) {
entry:
br i1 %cc, label %then, label %end

then:
br label %end

end:
%r = phi i32 [ 0, %entry ], [ 1, %then ]
ret i32 %r
}

define void @phi_before_label(i32 %bound) {
entry:
br label %loop

loop:
%ctr = phi i32 [ 0, %entry ], [ %ctr.next, %loop ]
%ctr.next = add i32 %ctr, 1
%cc = icmp ult i32 %ctr.next, %bound
br i1 %cc, label %loop, label %end

end:
ret void
}

define i32 @phi_after_label_unnamed(i1 %cc) {
0:
br i1 %cc, label %1, label %2

1:
br label %2

2:
%r = phi i32 [ 0, %0 ], [ 1, %1 ]
ret i32 %r
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
; RUN: opt < %s -S | FileCheck %s

define i32 @phi_after_label(i1 %cc) {
; CHECK-LABEL: define i32 @phi_after_label(
; CHECK-SAME: i1 [[CC:%.*]]) {
; CHECK-NEXT: entry:
; CHECK-NEXT: br i1 [[CC]], label [[THEN:%.*]], label [[END:%.*]]
; CHECK: then:
; CHECK-NEXT: br label [[END]]
; CHECK: end:
; CHECK-NEXT: [[R:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ 1, [[THEN]] ]
; CHECK-NEXT: ret i32 [[R]]
;
entry:
br i1 %cc, label %then, label %end

then:
br label %end

end:
%r = phi i32 [ 0, %entry ], [ 1, %then ]
ret i32 %r
}

define void @phi_before_label(i32 %bound) {
; CHECK-LABEL: define void @phi_before_label(
; CHECK-SAME: i32 [[BOUND:%.*]]) {
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[CTR:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[CTR_NEXT:%.*]], [[LOOP]] ]
; CHECK-NEXT: [[CTR_NEXT]] = add i32 [[CTR]], 1
; CHECK-NEXT: [[CC:%.*]] = icmp ult i32 [[CTR_NEXT]], [[BOUND]]
; CHECK-NEXT: br i1 [[CC]], label [[LOOP]], label [[END:%.*]]
; CHECK: end:
; CHECK-NEXT: ret void
;
entry:
br label %loop

loop:
%ctr = phi i32 [ 0, %entry ], [ %ctr.next, %loop ]
%ctr.next = add i32 %ctr, 1
%cc = icmp ult i32 %ctr.next, %bound
br i1 %cc, label %loop, label %end

end:
ret void
}

define i32 @phi_after_label_unnamed(i1 %cc) {
; CHECK-LABEL: define i32 @phi_after_label_unnamed(
; CHECK-SAME: i1 [[CC:%.*]]) {
; CHECK-NEXT: br i1 [[CC]], label [[TMP1:%.*]], label [[TMP2:%.*]]
; CHECK: 1:
; CHECK-NEXT: br label [[TMP2]]
; CHECK: 2:
; CHECK-NEXT: [[R:%.*]] = phi i32 [ 0, [[TMP0:%.*]] ], [ 1, [[TMP1]] ]
; CHECK-NEXT: ret i32 [[R]]
;
0:
br i1 %cc, label %1, label %2

1:
br label %2

2:
%r = phi i32 [ 0, %0 ], [ 1, %1 ]
ret i32 %r
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs --version 3
; RUN: opt < %s -S | FileCheck %s

; The assumption underlying this test is that there are pre-existing check lines
; but something has changed, and we would like to avoid needless changes of
; meta variable names so that diffs end up being easier to read, e.g. avoid
; changing X_I33 into X_I34 or renumbering the various TMP variables.

define i32 @func({i32, i32} %x, i32 %y) {
%x.i34 = extractvalue {i32, i32} %x, 0
%1 = add i32 %y, 1
%2 = add i32 %x.i34, %1
%3 = mul i32 %2, 3
ret i32 %3
}

; CHECK-LABEL: define i32 @func(
; CHECK-SAME: { i32, i32 } [[X:%.*]], i32 [[Y:%.*]]) {
; CHECK-NEXT: [[X_I33:%.*]] = extractvalue { i32, i32 } [[X]], 0
; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X_I33]], [[Y]]
; CHECK-NEXT: [[TMP2:%.*]] = mul i32 [[TMP1]], 3
; CHECK-NEXT: ret i32 [[TMP2]]
;
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs --version 3
; RUN: opt < %s -S | FileCheck %s

; The assumption underlying this test is that there are pre-existing check lines
; but something has changed, and we would like to avoid needless changes of
; meta variable names so that diffs end up being easier to read, e.g. avoid
; changing X_I33 into X_I34 or renumbering the various TMP variables.

define i32 @func({i32, i32} %x, i32 %y) {
%x.i34 = extractvalue {i32, i32} %x, 0
%1 = add i32 %y, 1
%2 = add i32 %x.i34, %1
%3 = mul i32 %2, 3
ret i32 %3
}

; CHECK-LABEL: define i32 @func(
; CHECK-SAME: { i32, i32 } [[X:%.*]], i32 [[Y:%.*]]) {
; CHECK-NEXT: [[X_I34:%.*]] = extractvalue { i32, i32 } [[X]], 0
; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[Y]], 1
; CHECK-NEXT: [[TMP2:%.*]] = add i32 [[X_I34]], [[TMP1]]
; CHECK-NEXT: [[TMP3:%.*]] = mul i32 [[TMP2]], 3
; CHECK-NEXT: ret i32 [[TMP3]]
;
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# RUN: cp -f %S/Inputs/phi-labels.ll %t.ll && %update_test_checks --version 4 %t.ll
# RUN: diff -u %t.ll %S/Inputs/phi-labels.ll.expected
## Check that running the script again does not change the result:
# RUN: %update_test_checks %t.ll
# RUN: diff -u %t.ll %S/Inputs/phi-labels.ll.expected
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# RUN: cp -f %S/Inputs/stable_ir_values_funcs.ll %t.ll && %update_test_checks %t.ll
# RUN: diff -u %t.ll %S/Inputs/stable_ir_values_funcs.ll.expected
4 changes: 0 additions & 4 deletions llvm/utils/UpdateTestChecks/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -980,10 +980,6 @@ def __init__(
def is_local_def_ir_value(self):
return self.ir_prefix == "%"

# Return true if this kind of IR value is "global", basically if it matches '#{{.*}}'.
def is_global_scope_ir_value_match(self, match):
return self.global_ir_rhs_regexp is not None

# Return the IR prefix and check prefix we use for this kind or IR value,
# e.g., (%, TMP) for locals. If the IR prefix is a regex, return the prefix
# used in the IR output
Expand Down