diff options
| author | Nikita Popov <npopov@redhat.com> | 2023-10-30 09:04:04 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-10-30 09:04:04 +0100 |
| commit | ed3f06b9b393cd51e78e5fbc7a46bce090c1817a (patch) | |
| tree | 54b7960005e583b7cf5c65cbbcc5033a169270a1 /llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | |
| parent | 41f3b83fb066b4c3273e9abe02a8630864f22f30 (diff) | |
| download | llvm-ed3f06b9b393cd51e78e5fbc7a46bce090c1817a.zip llvm-ed3f06b9b393cd51e78e5fbc7a46bce090c1817a.tar.gz llvm-ed3f06b9b393cd51e78e5fbc7a46bce090c1817a.tar.bz2 | |
[IR] Add zext nneg flag (#67982)
Add an nneg flag to the zext instruction, which specifies that the
argument is non-negative. Otherwise, the result is a poison value.
The primary use-case for the flag is to preserve information when sext
gets replaced with zext due to range-based canonicalization. The nneg
flag allows us to convert the zext back into an sext later. This is
useful for some optimizations (e.g. a signed icmp can fold with sext but
not zext), as well as some targets (e.g. RISCV prefers sext over zext).
Discourse thread: https://discourse.llvm.org/t/rfc-add-zext-nneg-flag/73914
This patch is based on https://reviews.llvm.org/D156444 by
@Panagiotis156, with some implementation simplifications and additional
tests.
---------
Co-authored-by: Panagiotis K <karouzakispan@gmail.com>
Diffstat (limited to 'llvm/lib/Bitcode/Writer/BitcodeWriter.cpp')
| -rw-r--r-- | llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index c427459..d7ebc76 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -123,6 +123,7 @@ enum { FUNCTION_INST_BINOP_ABBREV, FUNCTION_INST_BINOP_FLAGS_ABBREV, FUNCTION_INST_CAST_ABBREV, + FUNCTION_INST_CAST_FLAGS_ABBREV, FUNCTION_INST_RET_VOID_ABBREV, FUNCTION_INST_RET_VAL_ABBREV, FUNCTION_INST_UNREACHABLE_ABBREV, @@ -1551,6 +1552,9 @@ static uint64_t getOptimizationFlags(const Value *V) { Flags |= bitc::AllowContract; if (FPMO->hasApproxFunc()) Flags |= bitc::ApproxFunc; + } else if (const auto *NNI = dyn_cast<PossiblyNonNegInst>(V)) { + if (NNI->hasNonNeg()) + Flags |= 1 << bitc::PNNI_NON_NEG; } return Flags; @@ -2827,6 +2831,12 @@ void ModuleBitcodeWriter::writeInstruction(const Instruction &I, AbbrevToUse = FUNCTION_INST_CAST_ABBREV; Vals.push_back(VE.getTypeID(I.getType())); Vals.push_back(getEncodedCastOpcode(I.getOpcode())); + uint64_t Flags = getOptimizationFlags(&I); + if (Flags != 0) { + if (AbbrevToUse == FUNCTION_INST_CAST_ABBREV) + AbbrevToUse = FUNCTION_INST_CAST_FLAGS_ABBREV; + Vals.push_back(Flags); + } } else { assert(isa<BinaryOperator>(I) && "Unknown instruction!"); Code = bitc::FUNC_CODE_INST_BINOP; @@ -3648,6 +3658,18 @@ void ModuleBitcodeWriter::writeBlockInfo() { FUNCTION_INST_CAST_ABBREV) llvm_unreachable("Unexpected abbrev ordering!"); } + { // INST_CAST_FLAGS abbrev for FUNCTION_BLOCK. + auto Abbv = std::make_shared<BitCodeAbbrev>(); + Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_CAST)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // OpVal + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, // dest ty + VE.computeBitsRequiredForTypeIndicies())); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 4)); // opc + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 8)); // flags + if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID, Abbv) != + FUNCTION_INST_CAST_FLAGS_ABBREV) + llvm_unreachable("Unexpected abbrev ordering!"); + } { // INST_RET abbrev for FUNCTION_BLOCK. auto Abbv = std::make_shared<BitCodeAbbrev>(); |
