diff options
author | Nikita Popov <npopov@redhat.com> | 2024-05-27 16:05:17 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-05-27 16:05:17 +0200 |
commit | 8cdecd4d3aedea7bc5f27d1f69da216100cb2815 (patch) | |
tree | fb5b5a1d15766c4187abfabc4a6248c18bf7f1a3 /llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | |
parent | 49b760ff2c7da60f4308708f56688ca99874605f (diff) | |
download | llvm-8cdecd4d3aedea7bc5f27d1f69da216100cb2815.zip llvm-8cdecd4d3aedea7bc5f27d1f69da216100cb2815.tar.gz llvm-8cdecd4d3aedea7bc5f27d1f69da216100cb2815.tar.bz2 |
[IR] Add getelementptr nusw and nuw flags (#90824)
This implements the `nusw` and `nuw` flags for `getelementptr` as
proposed at
https://discourse.llvm.org/t/rfc-add-nusw-and-nuw-flags-for-getelementptr/78672.
The three possible flags are encapsulated in the new `GEPNoWrapFlags`
class. Currently this class has a ctor from bool, interpreted as the
InBounds flag. This ctor should be removed in the future, as code gets
migrated to handle all flags.
There are a few places annotated with `TODO(gep_nowrap)`, where I've had
to touch code but opted to not infer or precisely preserve the new
flags, so as to keep this as NFC as possible and make sure any changes
of that kind get test coverage when they are made.
Diffstat (limited to 'llvm/lib/Bitcode/Writer/BitcodeWriter.cpp')
-rw-r--r-- | llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 16 |
1 files changed, 11 insertions, 5 deletions
diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index c5fdd111..3d653fe 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -1668,6 +1668,13 @@ static uint64_t getOptimizationFlags(const Value *V) { Flags |= 1 << bitc::TIO_NO_SIGNED_WRAP; if (TI->hasNoUnsignedWrap()) Flags |= 1 << bitc::TIO_NO_UNSIGNED_WRAP; + } else if (const auto *GEP = dyn_cast<GEPOperator>(V)) { + if (GEP->isInBounds()) + Flags |= 1 << bitc::GEP_INBOUNDS; + if (GEP->hasNoUnsignedSignedWrap()) + Flags |= 1 << bitc::GEP_NUSW; + if (GEP->hasNoUnsignedWrap()) + Flags |= 1 << bitc::GEP_NUW; } return Flags; @@ -2779,12 +2786,11 @@ void ModuleBitcodeWriter::writeConstants(unsigned FirstVal, unsigned LastVal, Code = bitc::CST_CODE_CE_GEP; const auto *GO = cast<GEPOperator>(C); Record.push_back(VE.getTypeID(GO->getSourceElementType())); + Record.push_back(getOptimizationFlags(GO)); if (std::optional<ConstantRange> Range = GO->getInRange()) { Code = bitc::CST_CODE_CE_GEP_WITH_INRANGE; - Record.push_back(GO->isInBounds()); emitConstantRange(Record, *Range); - } else if (GO->isInBounds()) - Code = bitc::CST_CODE_CE_INBOUNDS_GEP; + } for (unsigned i = 0, e = CE->getNumOperands(); i != e; ++i) { Record.push_back(VE.getTypeID(C->getOperand(i)->getType())); Record.push_back(VE.getValueID(C->getOperand(i))); @@ -2973,7 +2979,7 @@ void ModuleBitcodeWriter::writeInstruction(const Instruction &I, Code = bitc::FUNC_CODE_INST_GEP; AbbrevToUse = FUNCTION_INST_GEP_ABBREV; auto &GEPInst = cast<GetElementPtrInst>(I); - Vals.push_back(GEPInst.isInBounds()); + Vals.push_back(getOptimizationFlags(&I)); Vals.push_back(VE.getTypeID(GEPInst.getSourceElementType())); for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) pushValueAndType(I.getOperand(i), InstID, Vals); @@ -3871,7 +3877,7 @@ void ModuleBitcodeWriter::writeBlockInfo() { { auto Abbv = std::make_shared<BitCodeAbbrev>(); Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_GEP)); - Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, // dest ty Log2_32_Ceil(VE.getTypes().size() + 1))); Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); |