[llvm] [IR] Add ByteCast opcode and ByteCastInst (PR #221884)
Anshil Gandhi via llvm-commits
llvm-commits at lists.llvm.org
Mon Sep 7 23:04:41 PDT 2026
https://github.com/gandhi56 created https://github.com/llvm/llvm-project/pull/221884
## Summary
- Add a dedicated `bytecast` instruction (opcode 70) for reinterpretation involving byte types (`b8`, `b16`, `b32`, `b64`), separate from `bitcast`.
- Wire up IR support: `ByteCastInst`, verifier, constant folding, asm parser/lexer, visitor, and minimal CodeGen stubs (SelectionDAG/GlobalISel delegate to bitcast for now).
- Update llubi and IR2Vec tests for the new opcode and migrated byte-related casts.
## Test plan
- [x] `ninja check-llvm` passes on this branch
- [ ] Review IR2Vec embedding/index updates
- [ ] Confirm backward compatibility for legacy byte-related `bitcast` in text IR
Made with [Cursor](https://cursor.com)
>From be70468b11b517cfdca424acc00b50ffe4caf286 Mon Sep 17 00:00:00 2001
From: Anshil Gandhi <Anshil.Gandhi at amd.com>
Date: Mon, 7 Sep 2026 07:45:40 -0500
Subject: [PATCH] [IR] Add ByteCast opcode and ByteCastInst
Introduce a dedicated bytecast instruction for casts involving byte types.
Split byte cast validation out of bitcast, add ByteCastInst, constant folding,
and verifier support. Renumber subsequent opcodes to keep Instruction.def unique.
Add LLVMByteCast to the C API opcode enum for Core.cpp mapping tables, minimal
codegen stubs, assembler/llubi support, and bitcast-to-bytecast fallback in the
parser so existing IR text continues to assemble.
Co-authored-by: Cursor <cursoragent at cursor.com>
---
llvm/include/llvm-c/Core.h | 1 +
llvm/include/llvm/Analysis/IR2Vec.h | 4 +-
llvm/include/llvm/AsmParser/LLToken.h | 1 +
llvm/include/llvm/IR/Constants.h | 2 +
llvm/include/llvm/IR/InstVisitor.h | 1 +
llvm/include/llvm/IR/InstrTypes.h | 2 +-
llvm/include/llvm/IR/Instruction.def | 3 +
llvm/include/llvm/IR/Instruction.h | 3 +-
llvm/include/llvm/IR/Instructions.h | 28 ++++++
llvm/include/llvm/IR/Operator.h | 24 +++++
llvm/lib/AsmParser/LLLexer.cpp | 1 +
llvm/lib/AsmParser/LLParser.cpp | 3 +
llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp | 8 ++
.../SelectionDAG/SelectionDAGBuilder.cpp | 4 +
.../SelectionDAG/SelectionDAGBuilder.h | 1 +
llvm/lib/IR/ConstantFold.cpp | 2 +
llvm/lib/IR/Constants.cpp | 17 ++++
llvm/lib/IR/Instruction.cpp | 1 +
llvm/lib/IR/Instructions.cpp | 95 ++++++++++++++++---
llvm/lib/IR/Verifier.cpp | 12 +++
.../Inputs/reference_default_vocab_print.txt | 1 +
.../Inputs/reference_wtd1_vocab_print.txt | 1 +
.../Inputs/reference_wtd2_vocab_print.txt | 1 +
llvm/test/tools/llubi/bitcast_be.ll | 12 +--
llvm/test/tools/llubi/bitcast_le.ll | 12 +--
llvm/test/tools/llubi/bytes_undef.ll | 8 +-
llvm/test/tools/llubi/freeze.ll | 4 +-
llvm/test/tools/llubi/loadstore_be.ll | 12 +--
llvm/test/tools/llubi/loadstore_le.ll | 12 +--
llvm/test/tools/llvm-ir2vec/entities.ll | 89 ++++++++---------
llvm/test/tools/llvm-ir2vec/triplets.ll | 58 +++++------
llvm/tools/llubi/lib/Context.cpp | 3 +-
llvm/tools/llubi/lib/Interpreter.cpp | 13 ++-
llvm/unittests/Analysis/IR2VecTest.cpp | 28 +++---
34 files changed, 327 insertions(+), 140 deletions(-)
diff --git a/llvm/include/llvm-c/Core.h b/llvm/include/llvm-c/Core.h
index f3b98a31c5bd7..f4431536dc481 100644
--- a/llvm/include/llvm-c/Core.h
+++ b/llvm/include/llvm-c/Core.h
@@ -116,6 +116,7 @@ typedef enum {
LLVMPtrToAddr = 69,
LLVMIntToPtr = 40,
LLVMBitCast = 41,
+ LLVMByteCast = 72,
LLVMAddrSpaceCast = 60,
/* Other Operators */
diff --git a/llvm/include/llvm/Analysis/IR2Vec.h b/llvm/include/llvm/Analysis/IR2Vec.h
index b89d52a002445..7f84538f93c08 100644
--- a/llvm/include/llvm/Analysis/IR2Vec.h
+++ b/llvm/include/llvm/Analysis/IR2Vec.h
@@ -311,9 +311,7 @@ class Vocabulary {
};
/// Vocabulary layout constants
-#define LAST_OTHER_INST(NUM) static constexpr unsigned MaxOpcodes = NUM;
-#include "llvm/IR/Instruction.def"
-#undef LAST_OTHER_INST
+ static constexpr unsigned MaxOpcodes = Instruction::ByteCast;
static constexpr unsigned MaxTypeIDs = Type::TypeID::TargetExtTyID + 1;
static constexpr unsigned MaxCanonicalTypeIDs =
diff --git a/llvm/include/llvm/AsmParser/LLToken.h b/llvm/include/llvm/AsmParser/LLToken.h
index d2766a05ce9ba..9f400f5676040 100644
--- a/llvm/include/llvm/AsmParser/LLToken.h
+++ b/llvm/include/llvm/AsmParser/LLToken.h
@@ -338,6 +338,7 @@ enum Kind {
kw_ptrtoaddr,
kw_ptrtoint,
kw_bitcast,
+ kw_bytecast,
kw_addrspacecast,
kw_select,
kw_va_arg,
diff --git a/llvm/include/llvm/IR/Constants.h b/llvm/include/llvm/IR/Constants.h
index d5299aebd16fe..bd5cd93904d41 100644
--- a/llvm/include/llvm/IR/Constants.h
+++ b/llvm/include/llvm/IR/Constants.h
@@ -1362,6 +1362,8 @@ class ConstantExpr : public Constant {
bool OnlyIfReduced = false);
LLVM_ABI static Constant *getBitCast(Constant *C, Type *Ty,
bool OnlyIfReduced = false);
+ LLVM_ABI static Constant *getByteCast(Constant *C, Type *Ty,
+ bool OnlyIfReduced = false);
LLVM_ABI static Constant *getAddrSpaceCast(Constant *C, Type *Ty,
bool OnlyIfReduced = false);
diff --git a/llvm/include/llvm/IR/InstVisitor.h b/llvm/include/llvm/IR/InstVisitor.h
index ecef7f50d98ce..2176743e0b855 100644
--- a/llvm/include/llvm/IR/InstVisitor.h
+++ b/llvm/include/llvm/IR/InstVisitor.h
@@ -186,6 +186,7 @@ class InstVisitor {
RetTy visitPtrToAddrInst(PtrToAddrInst &I) { DELEGATE(CastInst);}
RetTy visitIntToPtrInst(IntToPtrInst &I) { DELEGATE(CastInst);}
RetTy visitBitCastInst(BitCastInst &I) { DELEGATE(CastInst);}
+ RetTy visitByteCastInst(ByteCastInst &I) { DELEGATE(CastInst);}
RetTy visitAddrSpaceCastInst(AddrSpaceCastInst &I) { DELEGATE(CastInst);}
RetTy visitSelectInst(SelectInst &I) { DELEGATE(Instruction);}
RetTy visitVAArgInst(VAArgInst &I) { DELEGATE(UnaryInstruction);}
diff --git a/llvm/include/llvm/IR/InstrTypes.h b/llvm/include/llvm/IR/InstrTypes.h
index 5f7df6a4eb6f8..22ca047ecb22c 100644
--- a/llvm/include/llvm/IR/InstrTypes.h
+++ b/llvm/include/llvm/IR/InstrTypes.h
@@ -89,7 +89,7 @@ class UnaryInstruction : public Instruction {
I->getOpcode() == Instruction::VAArg ||
I->getOpcode() == Instruction::ExtractValue ||
I->getOpcode() == Instruction::Freeze ||
- (I->getOpcode() >= CastOpsBegin && I->getOpcode() < CastOpsEnd);
+ I->isCast();
}
static bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
diff --git a/llvm/include/llvm/IR/Instruction.def b/llvm/include/llvm/IR/Instruction.def
index 949a9d0beecb4..b3ef4fed44d60 100644
--- a/llvm/include/llvm/IR/Instruction.def
+++ b/llvm/include/llvm/IR/Instruction.def
@@ -196,6 +196,9 @@ HANDLE_CAST_INST(49, PtrToAddr, PtrToAddrInst) // Pointer -> Address
HANDLE_CAST_INST(50, IntToPtr, IntToPtrInst) // Integer -> Pointer
HANDLE_CAST_INST(51, BitCast , BitCastInst ) // Type cast
HANDLE_CAST_INST(52, AddrSpaceCast, AddrSpaceCastInst) // addrspace cast
+// ByteCast uses the terminal opcode so existing opcodes remain stable. It is
+// handled explicitly where code relies on the contiguous cast range.
+HANDLE_CAST_INST(70, ByteCast, ByteCastInst) // Byte type cast
LAST_CAST_INST(52)
FIRST_FUNCLETPAD_INST(53)
diff --git a/llvm/include/llvm/IR/Instruction.h b/llvm/include/llvm/IR/Instruction.h
index a6ef59c85265c..37919fced86cb 100644
--- a/llvm/include/llvm/IR/Instruction.h
+++ b/llvm/include/llvm/IR/Instruction.h
@@ -374,7 +374,8 @@ class Instruction : public User,
/// Determine if the Opcode is one of the CastInst instructions.
static inline bool isCast(unsigned Opcode) {
- return Opcode >= CastOpsBegin && Opcode < CastOpsEnd;
+ return (Opcode >= CastOpsBegin && Opcode < CastOpsEnd) ||
+ Opcode == ByteCast;
}
/// Determine if the Opcode is one of the FuncletPadInst instructions.
diff --git a/llvm/include/llvm/IR/Instructions.h b/llvm/include/llvm/IR/Instructions.h
index 00d689283479f..445b682f5458b 100644
--- a/llvm/include/llvm/IR/Instructions.h
+++ b/llvm/include/llvm/IR/Instructions.h
@@ -5182,6 +5182,34 @@ class BitCastInst : public CastInst {
}
};
+//===----------------------------------------------------------------------===//
+// ByteCastInst Class
+//===----------------------------------------------------------------------===//
+
+/// This class represents a byte type cast instruction.
+class ByteCastInst : public CastInst {
+protected:
+ friend class Instruction;
+ LLVM_ABI ByteCastInst *cloneImpl() const;
+
+public:
+ LLVM_ABI
+ ByteCastInst(Value *S, ///< The value to be casted
+ Type *Ty, ///< The type to casted to
+ const Twine &NameStr = "", ///< A name for the new instruction
+ InsertPosition InsertBefore =
+ nullptr ///< Where to insert the new instruction
+ );
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static bool classof(const Instruction *I) {
+ return I->getOpcode() == ByteCast;
+ }
+ static bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
//===----------------------------------------------------------------------===//
// AddrSpaceCastInst Class
//===----------------------------------------------------------------------===//
diff --git a/llvm/include/llvm/IR/Operator.h b/llvm/include/llvm/IR/Operator.h
index c44cddca93009..32482ac0c891e 100644
--- a/llvm/include/llvm/IR/Operator.h
+++ b/llvm/include/llvm/IR/Operator.h
@@ -610,6 +610,30 @@ struct OperandTraits<BitCastOperator>
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BitCastOperator, Value)
+class ByteCastOperator
+ : public ConcreteOperator<Operator, Instruction::ByteCast> {
+ friend class ByteCastInst;
+ friend class ConstantExpr;
+
+public:
+ /// Transparently provide more efficient getOperand methods.
+ DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+ Type *getSrcTy() const {
+ return getOperand(0)->getType();
+ }
+
+ Type *getDestTy() const {
+ return getType();
+ }
+};
+
+template <>
+struct OperandTraits<ByteCastOperator>
+ : public FixedNumOperandTraits<ByteCastOperator, 1> {};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ByteCastOperator, Value)
+
class AddrSpaceCastOperator
: public ConcreteOperator<Operator, Instruction::AddrSpaceCast> {
friend class AddrSpaceCastInst;
diff --git a/llvm/lib/AsmParser/LLLexer.cpp b/llvm/lib/AsmParser/LLLexer.cpp
index 069a180056488..0f2e348cf5294 100644
--- a/llvm/lib/AsmParser/LLLexer.cpp
+++ b/llvm/lib/AsmParser/LLLexer.cpp
@@ -963,6 +963,7 @@ lltok::Kind LLLexer::LexIdentifier() {
INSTKEYWORD(ptrtoaddr, PtrToAddr);
INSTKEYWORD(ptrtoint, PtrToInt);
INSTKEYWORD(bitcast, BitCast);
+ INSTKEYWORD(bytecast, ByteCast);
INSTKEYWORD(addrspacecast, AddrSpaceCast);
INSTKEYWORD(select, Select);
INSTKEYWORD(va_arg, VAArg);
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index 477bcebccf2ad..5052bd07a7113 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -1349,6 +1349,7 @@ bool LLParser::parseAliasOrIFunc(const std::string &Name, unsigned NameID,
Constant *Aliasee;
LocTy AliaseeLoc = Lex.getLoc();
if (Lex.getKind() != lltok::kw_bitcast &&
+ Lex.getKind() != lltok::kw_bytecast &&
Lex.getKind() != lltok::kw_getelementptr &&
Lex.getKind() != lltok::kw_addrspacecast &&
Lex.getKind() != lltok::kw_inttoptr) {
@@ -4684,6 +4685,7 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS, Type *ExpectedTy) {
case lltok::kw_trunc:
case lltok::kw_bitcast:
+ case lltok::kw_bytecast:
case lltok::kw_addrspacecast:
case lltok::kw_inttoptr:
case lltok::kw_ptrtoaddr:
@@ -7880,6 +7882,7 @@ int LLParser::parseInstruction(Instruction *&Inst, BasicBlock *BB,
}
case lltok::kw_sext:
case lltok::kw_bitcast:
+ case lltok::kw_bytecast:
case lltok::kw_fptoui:
case lltok::kw_fptosi:
case lltok::kw_inttoptr:
diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
index 75f3023e479c5..534848466b643 100644
--- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
@@ -272,6 +272,9 @@ class IRTranslatorImpl {
/// emitted.
bool translateBitCast(const User &U, MachineIRBuilder &MIRBuilder);
+ /// Translate an LLVM bytecast into generic IR.
+ bool translateByteCast(const User &U, MachineIRBuilder &MIRBuilder);
+
/// Translate an LLVM load instruction into generic IR.
bool translateLoad(const User &U, MachineIRBuilder &MIRBuilder);
@@ -2368,6 +2371,11 @@ bool IRTranslatorImpl::translateBitCast(const User &U,
return translateCast(TargetOpcode::G_BITCAST, U, MIRBuilder);
}
+bool IRTranslatorImpl::translateByteCast(const User &U,
+ MachineIRBuilder &MIRBuilder) {
+ return translateBitCast(U, MIRBuilder);
+}
+
bool IRTranslatorImpl::translateCast(unsigned Opcode, const User &U,
MachineIRBuilder &MIRBuilder) {
if (!mayTranslateUserTypes(U))
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index f34f1c7e9c969..1216082cb337c 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -4167,6 +4167,10 @@ void SelectionDAGBuilder::visitBitCast(const User &I) {
setValue(&I, N); // noop cast.
}
+void SelectionDAGBuilder::visitByteCast(const User &I) {
+ visitBitCast(I);
+}
+
void SelectionDAGBuilder::visitAddrSpaceCast(const User &I) {
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
const Value *SV = I.getOperand(0);
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
index e4e958cba5ac2..3cbcafe9b0769 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
@@ -604,6 +604,7 @@ class SelectionDAGBuilder {
void visitPtrToInt(const User &I);
void visitIntToPtr(const User &I);
void visitBitCast(const User &I);
+ void visitByteCast(const User &I);
void visitAddrSpaceCast(const User &I);
void visitExtractElement(const User &I);
diff --git a/llvm/lib/IR/ConstantFold.cpp b/llvm/lib/IR/ConstantFold.cpp
index f8abd576f93c4..247284af781d4 100644
--- a/llvm/lib/IR/ConstantFold.cpp
+++ b/llvm/lib/IR/ConstantFold.cpp
@@ -284,6 +284,8 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, Constant *V,
}
case Instruction::BitCast:
return FoldBitCast(V, DestTy);
+ case Instruction::ByteCast:
+ return FoldBitCast(V, DestTy);
case Instruction::AddrSpaceCast:
case Instruction::IntToPtr:
case Instruction::PtrToAddr:
diff --git a/llvm/lib/IR/Constants.cpp b/llvm/lib/IR/Constants.cpp
index 675cdaf6f1689..c7e41cf10fc4b 100644
--- a/llvm/lib/IR/Constants.cpp
+++ b/llvm/lib/IR/Constants.cpp
@@ -1704,6 +1704,7 @@ Constant *ConstantExpr::getWithOperands(ArrayRef<Constant *> Ops, Type *Ty,
case Instruction::PtrToInt:
case Instruction::IntToPtr:
case Instruction::BitCast:
+ case Instruction::ByteCast:
case Instruction::AddrSpaceCast:
return ConstantExpr::getCast(getOpcode(), Ops[0], Ty, OnlyIfReduced);
case Instruction::InsertElement:
@@ -2388,6 +2389,8 @@ Constant *ConstantExpr::getCast(unsigned oc, Constant *C, Type *Ty,
return getIntToPtr(C, Ty, OnlyIfReduced);
case Instruction::BitCast:
return getBitCast(C, Ty, OnlyIfReduced);
+ case Instruction::ByteCast:
+ return getByteCast(C, Ty, OnlyIfReduced);
case Instruction::AddrSpaceCast:
return getAddrSpaceCast(C, Ty, OnlyIfReduced);
}
@@ -2493,6 +2496,17 @@ Constant *ConstantExpr::getBitCast(Constant *C, Type *DstTy,
return getFoldedCast(Instruction::BitCast, C, DstTy, OnlyIfReduced);
}
+Constant *ConstantExpr::getByteCast(Constant *C, Type *DstTy,
+ bool OnlyIfReduced) {
+ assert(CastInst::castIsValid(Instruction::ByteCast, C, DstTy) &&
+ "Invalid constantexpr bytecast!");
+
+ if (C->getType() == DstTy)
+ return C;
+
+ return getFoldedCast(Instruction::ByteCast, C, DstTy, OnlyIfReduced);
+}
+
Constant *ConstantExpr::getAddrSpaceCast(Constant *C, Type *DstTy,
bool OnlyIfReduced) {
assert(CastInst::castIsValid(Instruction::AddrSpaceCast, C, DstTy) &&
@@ -2612,6 +2626,7 @@ bool ConstantExpr::isDesirableCastOp(unsigned Opcode) {
case Instruction::PtrToInt:
case Instruction::IntToPtr:
case Instruction::BitCast:
+ case Instruction::ByteCast:
case Instruction::AddrSpaceCast:
return true;
default:
@@ -2635,6 +2650,7 @@ bool ConstantExpr::isSupportedCastOp(unsigned Opcode) {
case Instruction::PtrToInt:
case Instruction::IntToPtr:
case Instruction::BitCast:
+ case Instruction::ByteCast:
case Instruction::AddrSpaceCast:
return true;
default:
@@ -3687,6 +3703,7 @@ Instruction *ConstantExpr::getAsInstruction() const {
case Instruction::PtrToInt:
case Instruction::IntToPtr:
case Instruction::BitCast:
+ case Instruction::ByteCast:
case Instruction::AddrSpaceCast:
return CastInst::Create((Instruction::CastOps)getOpcode(), Ops[0],
getType(), "");
diff --git a/llvm/lib/IR/Instruction.cpp b/llvm/lib/IR/Instruction.cpp
index 2cfd9fb902886..7139f91620f00 100644
--- a/llvm/lib/IR/Instruction.cpp
+++ b/llvm/lib/IR/Instruction.cpp
@@ -883,6 +883,7 @@ const char *Instruction::getOpcodeName(unsigned OpCode) {
case PtrToAddr: return "ptrtoaddr";
case PtrToInt: return "ptrtoint";
case BitCast: return "bitcast";
+ case ByteCast: return "bytecast";
case AddrSpaceCast: return "addrspacecast";
// Other instructions...
diff --git a/llvm/lib/IR/Instructions.cpp b/llvm/lib/IR/Instructions.cpp
index 325850b0a880d..f62bee8309a21 100644
--- a/llvm/lib/IR/Instructions.cpp
+++ b/llvm/lib/IR/Instructions.cpp
@@ -2859,6 +2859,8 @@ bool CastInst::isNoopCast(Instruction::CastOps Opcode,
return false;
case Instruction::BitCast:
return true; // BitCast never modifies bits.
+ case Instruction::ByteCast:
+ return true; // ByteCast never modifies bits.
case Instruction::PtrToAddr:
case Instruction::PtrToInt:
return DL.getIntPtrType(SrcTy)->getScalarSizeInBits() ==
@@ -2918,6 +2920,26 @@ unsigned CastInst::isEliminableCastPair(Instruction::CastOps firstOp,
// same reason.
const unsigned numCastOps =
Instruction::CastOpsEnd - Instruction::CastOpsBegin;
+
+ // ByteCast deliberately has a non-contiguous opcode so introducing it does
+ // not renumber existing instructions. Handle combinations involving it
+ // conservatively before indexing the contiguous cast table.
+ if (firstOp == Instruction::ByteCast ||
+ secondOp == Instruction::ByteCast) {
+ bool FirstIsNoop = firstOp == Instruction::BitCast ||
+ firstOp == Instruction::ByteCast;
+ bool SecondIsNoop = secondOp == Instruction::BitCast ||
+ secondOp == Instruction::ByteCast;
+ if (!FirstIsNoop || !SecondIsNoop)
+ return 0;
+
+ Instruction::CastOps Result =
+ SrcTy->isByteOrByteVectorTy() || DstTy->isByteOrByteVectorTy()
+ ? Instruction::ByteCast
+ : Instruction::BitCast;
+ return castIsValid(Result, SrcTy, DstTy) ? Result : 0;
+ }
+
// clang-format off
static const uint8_t CastResults[numCastOps][numCastOps] = {
// T F F U S F F P P I B A -+
@@ -3125,6 +3147,8 @@ CastInst *CastInst::Create(Instruction::CastOps op, Value *S, Type *Ty,
case IntToPtr: return new IntToPtrInst (S, Ty, Name, InsertBefore);
case BitCast:
return new BitCastInst(S, Ty, Name, InsertBefore);
+ case ByteCast:
+ return new ByteCastInst(S, Ty, Name, InsertBefore);
case AddrSpaceCast:
return new AddrSpaceCastInst(S, Ty, Name, InsertBefore);
default:
@@ -3272,6 +3296,12 @@ bool CastInst::isBitOrNoopPointerCastable(Type *SrcTy, Type *DestTy,
return isBitCastable(SrcTy, DestTy);
}
+static Instruction::CastOps getNoopCastOpcode(Type *SrcTy, Type *DestTy) {
+ if (SrcTy->isByteOrByteVectorTy() || DestTy->isByteOrByteVectorTy())
+ return Instruction::ByteCast;
+ return Instruction::BitCast;
+}
+
// Provide a way to get a "cast" where the cast opcode is inferred from the
// types and size of the operand. This, basically, is a parallel of the
// logic in the castIsValid function below. This axiom should hold:
@@ -3308,15 +3338,30 @@ CastInst::getCastOpcode(
DestTy->getPrimitiveSizeInBits().getFixedValue(); // 0 for ptr
// Run through the possibilities ...
- if (DestTy->isByteTy()) { // Casting to byte
- if (SrcTy->isIntegerTy()) { // Casting from integral
- assert(DestBits == SrcBits && "Illegal cast from integer to byte type");
- return BitCast;
+ if (DestTy->isByteOrByteVectorTy()) { // Casting to byte
+ if (SrcTy->isIntegerTy() || SrcTy->isByteOrByteVectorTy()) {
+ assert(DestBits == SrcBits && "Illegal cast to byte type");
+ return ByteCast;
} else if (SrcTy->isPointerTy()) { // Casting from pointer
assert(DestBits == SrcBits && "Illegal cast from pointer to byte type");
- return BitCast;
+ return ByteCast;
+ } else if (SrcTy->isFloatingPointTy()) {
+ assert(DestBits == SrcBits && "Illegal cast to byte type");
+ return ByteCast;
}
llvm_unreachable("Illegal cast to byte type");
+ } else if (SrcTy->isByteOrByteVectorTy()) { // Casting from byte
+ if (DestTy->isIntegerTy() || DestTy->isFloatingPointTy()) {
+ assert(DestBits == SrcBits && "Illegal cast from byte type");
+ return ByteCast;
+ } else if (DestTy->isPointerTy()) {
+ assert(DestBits == SrcBits && "Illegal cast from byte to pointer type");
+ return ByteCast;
+ } else if (DestTy->isVectorTy()) {
+ assert(DestBits == SrcBits && "Illegal cast from byte type");
+ return ByteCast;
+ }
+ llvm_unreachable("Illegal cast from byte type");
} else if (DestTy->isIntegerTy()) { // Casting to integral
if (SrcTy->isIntegerTy()) { // Casting from integral
if (DestBits < SrcBits)
@@ -3327,7 +3372,7 @@ CastInst::getCastOpcode(
else
return ZExt; // unsigned -> ZEXT
} else {
- return BitCast; // Same size, No-op cast
+ return getNoopCastOpcode(SrcTy, DestTy); // Same size, No-op cast
}
} else if (SrcTy->isFloatingPointTy()) { // Casting from floating pt
if (DestIsSigned)
@@ -3337,7 +3382,7 @@ CastInst::getCastOpcode(
} else if (SrcTy->isVectorTy()) {
assert(DestBits == SrcBits &&
"Casting vector to integer of different width");
- return BitCast; // Same size, no-op cast
+ return getNoopCastOpcode(SrcTy, DestTy); // Same size, no-op cast
} else {
assert(SrcTy->isPointerTy() &&
"Casting from a value that is not first-class type");
@@ -3355,18 +3400,18 @@ CastInst::getCastOpcode(
} else if (DestBits > SrcBits) {
return FPExt; // FP -> larger FP
} else {
- return BitCast; // same size, no-op cast
+ return getNoopCastOpcode(SrcTy, DestTy); // same size, no-op cast
}
} else if (SrcTy->isVectorTy()) {
assert(DestBits == SrcBits &&
"Casting vector to floating point of different width");
- return BitCast; // same size, no-op cast
+ return getNoopCastOpcode(SrcTy, DestTy); // same size, no-op cast
}
llvm_unreachable("Casting pointer or non-first class to float");
} else if (DestTy->isVectorTy()) {
assert(DestBits == SrcBits &&
"Illegal cast to vector (wrong type or size)");
- return BitCast;
+ return getNoopCastOpcode(SrcTy, DestTy);
} else if (DestTy->isPointerTy()) {
if (SrcTy->isPointerTy()) {
if (DestTy->getPointerAddressSpace() != SrcTy->getPointerAddressSpace())
@@ -3448,8 +3493,8 @@ CastInst::castIsValid(Instruction::CastOps op, Type *SrcTy, Type *DstTy) {
PointerType *SrcPtrTy = dyn_cast<PointerType>(SrcTy->getScalarType());
PointerType *DstPtrTy = dyn_cast<PointerType>(DstTy->getScalarType());
- // BitCast implies a no-op cast of type only. No bits change.
- // However, you can't cast pointers to anything but pointers/bytes.
+ // Keep accepting legacy bitcasts involving byte types while producers and
+ // tests migrate to the dedicated ByteCast opcode.
if ((SrcPtrTy && DstTy->isByteOrByteVectorTy()) ||
(SrcTy->isByteOrByteVectorTy() && DstPtrTy))
return true;
@@ -3475,6 +3520,22 @@ CastInst::castIsValid(Instruction::CastOps op, Type *SrcTy, Type *DstTy) {
return true;
}
+ case Instruction::ByteCast: {
+ bool SrcHasByte = SrcTy->isByteOrByteVectorTy();
+ bool DstHasByte = DstTy->isByteOrByteVectorTy();
+ if (!SrcHasByte && !DstHasByte)
+ return false;
+
+ PointerType *SrcPtrTy = dyn_cast<PointerType>(SrcTy->getScalarType());
+ PointerType *DstPtrTy = dyn_cast<PointerType>(DstTy->getScalarType());
+
+ // As with legacy byte-related bitcasts, opaque pointers do not provide
+ // enough type information to compare widths here.
+ if ((SrcPtrTy && DstHasByte) || (SrcHasByte && DstPtrTy))
+ return true;
+
+ return SrcTy->getPrimitiveSizeInBits() == DstTy->getPrimitiveSizeInBits();
+ }
case Instruction::AddrSpaceCast: {
PointerType *SrcPtrTy = dyn_cast<PointerType>(SrcTy->getScalarType());
if (!SrcPtrTy)
@@ -3570,6 +3631,12 @@ BitCastInst::BitCastInst(Value *S, Type *Ty, const Twine &Name,
assert(castIsValid(getOpcode(), S, Ty) && "Illegal BitCast");
}
+ByteCastInst::ByteCastInst(Value *S, Type *Ty, const Twine &Name,
+ InsertPosition InsertBefore)
+ : CastInst(Ty, ByteCast, S, Name, InsertBefore) {
+ assert(castIsValid(getOpcode(), S, Ty) && "Illegal ByteCast");
+}
+
AddrSpaceCastInst::AddrSpaceCastInst(Value *S, Type *Ty, const Twine &Name,
InsertPosition InsertBefore)
: CastInst(Ty, AddrSpaceCast, S, Name, InsertBefore) {
@@ -4545,6 +4612,10 @@ BitCastInst *BitCastInst::cloneImpl() const {
return new BitCastInst(getOperand(0), getType());
}
+ByteCastInst *ByteCastInst::cloneImpl() const {
+ return new ByteCastInst(getOperand(0), getType());
+}
+
AddrSpaceCastInst *AddrSpaceCastInst::cloneImpl() const {
return new AddrSpaceCastInst(getOperand(0), getType());
}
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 20df60ed61da3..88ee0bf692e05 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -418,6 +418,7 @@ class Verifier : public InstVisitor<Verifier>, VerifierSupport {
void visitPtrToAddrInst(PtrToAddrInst &I);
void visitPtrToIntInst(PtrToIntInst &I);
void visitBitCastInst(BitCastInst &I);
+ void visitByteCastInst(ByteCastInst &I);
void visitAddrSpaceCastInst(AddrSpaceCastInst &I);
void visitPHINode(PHINode &PN);
void visitCallBase(CallBase &Call);
@@ -2879,6 +2880,10 @@ void Verifier::visitConstantExpr(const ConstantExpr *CE) {
Check(CastInst::castIsValid(Instruction::BitCast, CE->getOperand(0),
CE->getType()),
"Invalid bitcast", CE);
+ else if (CE->getOpcode() == Instruction::ByteCast)
+ Check(CastInst::castIsValid(Instruction::ByteCast, CE->getOperand(0),
+ CE->getType()),
+ "Invalid bytecast", CE);
else if (CE->getOpcode() == Instruction::PtrToAddr)
checkPtrToAddr(CE->getOperand(0)->getType(), CE->getType(), *CE);
}
@@ -3907,6 +3912,13 @@ void Verifier::visitBitCastInst(BitCastInst &I) {
visitInstruction(I);
}
+void Verifier::visitByteCastInst(ByteCastInst &I) {
+ Check(CastInst::castIsValid(Instruction::ByteCast, I.getOperand(0),
+ I.getType()),
+ "Invalid bytecast", &I);
+ visitInstruction(I);
+}
+
void Verifier::visitAddrSpaceCastInst(AddrSpaceCastInst &I) {
Type *SrcTy = I.getOperand(0)->getType();
Type *DestTy = I.getType();
diff --git a/llvm/test/Analysis/IR2Vec/Inputs/reference_default_vocab_print.txt b/llvm/test/Analysis/IR2Vec/Inputs/reference_default_vocab_print.txt
index cc36415abb00b..f8c852019e3ab 100644
--- a/llvm/test/Analysis/IR2Vec/Inputs/reference_default_vocab_print.txt
+++ b/llvm/test/Analysis/IR2Vec/Inputs/reference_default_vocab_print.txt
@@ -67,6 +67,7 @@ Key: ExtractValue: [ 127.00 128.00 ]
Key: InsertValue: [ 129.00 130.00 ]
Key: LandingPad: [ 131.00 132.00 ]
Key: Freeze: [ 133.00 134.00 ]
+Key: ByteCast: [ 0.00 0.00 ]
Key: FloatTy: [ 0.50 1.00 ]
Key: VoidTy: [ 1.50 2.00 ]
Key: LabelTy: [ 2.50 3.00 ]
diff --git a/llvm/test/Analysis/IR2Vec/Inputs/reference_wtd1_vocab_print.txt b/llvm/test/Analysis/IR2Vec/Inputs/reference_wtd1_vocab_print.txt
index 8d837e9502739..c6bbcd833e92d 100644
--- a/llvm/test/Analysis/IR2Vec/Inputs/reference_wtd1_vocab_print.txt
+++ b/llvm/test/Analysis/IR2Vec/Inputs/reference_wtd1_vocab_print.txt
@@ -67,6 +67,7 @@ Key: ExtractValue: [ 63.50 64.00 ]
Key: InsertValue: [ 64.50 65.00 ]
Key: LandingPad: [ 65.50 66.00 ]
Key: Freeze: [ 66.50 67.00 ]
+Key: ByteCast: [ 0.00 0.00 ]
Key: FloatTy: [ 0.50 1.00 ]
Key: VoidTy: [ 1.50 2.00 ]
Key: LabelTy: [ 2.50 3.00 ]
diff --git a/llvm/test/Analysis/IR2Vec/Inputs/reference_wtd2_vocab_print.txt b/llvm/test/Analysis/IR2Vec/Inputs/reference_wtd2_vocab_print.txt
index 3d31b9d9db315..6af5772992ac9 100644
--- a/llvm/test/Analysis/IR2Vec/Inputs/reference_wtd2_vocab_print.txt
+++ b/llvm/test/Analysis/IR2Vec/Inputs/reference_wtd2_vocab_print.txt
@@ -67,6 +67,7 @@ Key: ExtractValue: [ 12.70 12.80 ]
Key: InsertValue: [ 12.90 13.00 ]
Key: LandingPad: [ 13.10 13.20 ]
Key: Freeze: [ 13.30 13.40 ]
+Key: ByteCast: [ 0.00 0.00 ]
Key: FloatTy: [ 0.00 0.00 ]
Key: VoidTy: [ 0.00 0.00 ]
Key: LabelTy: [ 0.00 0.00 ]
diff --git a/llvm/test/tools/llubi/bitcast_be.ll b/llvm/test/tools/llubi/bitcast_be.ll
index d0b3163669c40..20010d095fa00 100644
--- a/llvm/test/tools/llubi/bitcast_be.ll
+++ b/llvm/test/tools/llubi/bitcast_be.ll
@@ -30,9 +30,9 @@ entry:
%bitcast_intvec2floatvec = bitcast <2 x i32> <i32 1, i32 2> to <4 x half>
%bitcast_floatvec2int = bitcast <4 x half> <half 1.0, half 2.0, half 3.0, half 4.0> to i64
- %bitcast_ptr2b64 = bitcast ptr %ptr to b64
- %bitcast_b642i64 = bitcast b64 %bitcast_ptr2b64 to i64
- %bitcast_b642ptr = bitcast b64 %bitcast_ptr2b64 to ptr
+ %bitcast_ptr2b64 = bytecast ptr %ptr to b64
+ %bitcast_b642i64 = bytecast b64 %bitcast_ptr2b64 to i64
+ %bitcast_b642ptr = bytecast b64 %bitcast_ptr2b64 to ptr
ret void
}
; CHECK: Entering function: main
@@ -58,8 +58,8 @@ entry:
; CHECK-NEXT: %bitcast_vec2vec_weird = bitcast <8 x i3> <i3 0, i3 1, i3 2, i3 3, i3 -4, i3 -3, i3 -2, i3 -1> to <3 x i8> => { i8 5, i8 57, i8 119 }
; CHECK-NEXT: %bitcast_intvec2floatvec = bitcast <2 x i32> <i32 1, i32 2> to <4 x half> => { half 0.000000e+00, half 5.960460e-08, half 0.000000e+00, half 1.192090e-07 }
; CHECK-NEXT: %bitcast_floatvec2int = bitcast <4 x half> <half 1.000000e+00, half 2.000000e+00, half 3.000000e+00, half 4.000000e+00> to i64 => i64 4323526012127167488
-; CHECK-NEXT: %bitcast_ptr2b64 = bitcast ptr %ptr to b64 => b64 ptr 0x8 [ptr]
-; CHECK-NEXT: %bitcast_b642i64 = bitcast b64 %bitcast_ptr2b64 to i64 => i64 8
-; CHECK-NEXT: %bitcast_b642ptr = bitcast b64 %bitcast_ptr2b64 to ptr => ptr 0x8 [ptr]
+; CHECK-NEXT: %bitcast_ptr2b64 = bytecast ptr %ptr to b64 => b64 ptr 0x8 [ptr]
+; CHECK-NEXT: %bitcast_b642i64 = bytecast b64 %bitcast_ptr2b64 to i64 => i64 8
+; CHECK-NEXT: %bitcast_b642ptr = bytecast b64 %bitcast_ptr2b64 to ptr => ptr 0x8 [ptr]
; CHECK-NEXT: ret void
; CHECK-NEXT: Exiting function: main
diff --git a/llvm/test/tools/llubi/bitcast_le.ll b/llvm/test/tools/llubi/bitcast_le.ll
index acb4af6dd73d9..b2888c66560d9 100644
--- a/llvm/test/tools/llubi/bitcast_le.ll
+++ b/llvm/test/tools/llubi/bitcast_le.ll
@@ -30,9 +30,9 @@ entry:
%bitcast_intvec2floatvec = bitcast <2 x i32> <i32 1, i32 2> to <4 x half>
%bitcast_floatvec2int = bitcast <4 x half> <half 1.0, half 2.0, half 3.0, half 4.0> to i64
- %bitcast_ptr2b64 = bitcast ptr %ptr to b64
- %bitcast_b642i64 = bitcast b64 %bitcast_ptr2b64 to i64
- %bitcast_b642ptr = bitcast b64 %bitcast_ptr2b64 to ptr
+ %bitcast_ptr2b64 = bytecast ptr %ptr to b64
+ %bitcast_b642i64 = bytecast b64 %bitcast_ptr2b64 to i64
+ %bitcast_b642ptr = bytecast b64 %bitcast_ptr2b64 to ptr
ret void
}
; CHECK: Entering function: main
@@ -58,8 +58,8 @@ entry:
; CHECK-NEXT: %bitcast_vec2vec_weird = bitcast <8 x i3> <i3 0, i3 1, i3 2, i3 3, i3 -4, i3 -3, i3 -2, i3 -1> to <3 x i8> => { i8 -120, i8 -58, i8 -6 }
; CHECK-NEXT: %bitcast_intvec2floatvec = bitcast <2 x i32> <i32 1, i32 2> to <4 x half> => { half 5.960460e-08, half 0.000000e+00, half 1.192090e-07, half 0.000000e+00 }
; CHECK-NEXT: %bitcast_floatvec2int = bitcast <4 x half> <half 1.000000e+00, half 2.000000e+00, half 3.000000e+00, half 4.000000e+00> to i64 => i64 4899988963420290048
-; CHECK-NEXT: %bitcast_ptr2b64 = bitcast ptr %ptr to b64 => b64 ptr 0x8 [ptr]
-; CHECK-NEXT: %bitcast_b642i64 = bitcast b64 %bitcast_ptr2b64 to i64 => i64 8
-; CHECK-NEXT: %bitcast_b642ptr = bitcast b64 %bitcast_ptr2b64 to ptr => ptr 0x8 [ptr]
+; CHECK-NEXT: %bitcast_ptr2b64 = bytecast ptr %ptr to b64 => b64 ptr 0x8 [ptr]
+; CHECK-NEXT: %bitcast_b642i64 = bytecast b64 %bitcast_ptr2b64 to i64 => i64 8
+; CHECK-NEXT: %bitcast_b642ptr = bytecast b64 %bitcast_ptr2b64 to ptr => ptr 0x8 [ptr]
; CHECK-NEXT: ret void
; CHECK-NEXT: Exiting function: main
diff --git a/llvm/test/tools/llubi/bytes_undef.ll b/llvm/test/tools/llubi/bytes_undef.ll
index bd0d07a59abc8..7ed590340a0c1 100644
--- a/llvm/test/tools/llubi/bytes_undef.ll
+++ b/llvm/test/tools/llubi/bytes_undef.ll
@@ -7,15 +7,15 @@ define void @main() {
%undef = alloca b8
%load_undef1 = load b8, ptr %undef
%load_undef2 = load b8, ptr %undef
- %bitcast_undef1 = bitcast b8 %load_undef1 to i8
- %bitcast_undef2 = bitcast b8 %load_undef1 to i8
+ %bitcast_undef1 = bytecast b8 %load_undef1 to i8
+ %bitcast_undef2 = bytecast b8 %load_undef1 to i8
ret void
}
; CHECK: Entering function: main
; CHECK-NEXT: %undef = alloca b8, align 1 => ptr 0x8 [undef]
; CHECK-NEXT: %load_undef1 = load b8, ptr %undef, align 1 => b8 0x!!
; CHECK-NEXT: %load_undef2 = load b8, ptr %undef, align 1 => b8 0x!!
-; CHECK-NEXT: %bitcast_undef1 = bitcast b8 %load_undef1 to i8 => poison
-; CHECK-NEXT: %bitcast_undef2 = bitcast b8 %load_undef1 to i8 => poison
+; CHECK-NEXT: %bitcast_undef1 = bytecast b8 %load_undef1 to i8 => poison
+; CHECK-NEXT: %bitcast_undef2 = bytecast b8 %load_undef1 to i8 => poison
; CHECK-NEXT: ret void
; CHECK-NEXT: Exiting function: main
diff --git a/llvm/test/tools/llubi/freeze.ll b/llvm/test/tools/llubi/freeze.ll
index a5b21682a32f8..d842d09282324 100644
--- a/llvm/test/tools/llubi/freeze.ll
+++ b/llvm/test/tools/llubi/freeze.ll
@@ -23,7 +23,7 @@ define void @main() {
%byte_with_provenance = load b8, ptr %alloca
%vec_bytes1 = insertelement <4 x b8> <b8 0, b8 poison, b8 poison, b8 poison>, b8 %byte_undef, i32 2
%vec_bytes2 = insertelement <4 x b8> %vec_bytes1, b8 %byte_with_provenance, i32 3
- %bytes = bitcast <4 x b8> %vec_bytes2 to b32
+ %bytes = bytecast <4 x b8> %vec_bytes2 to b32
%bytes_freeze = freeze b32 %bytes
ret void
}
@@ -45,7 +45,7 @@ define void @main() {
; CHECK-NEXT: %byte_with_provenance = load b8, ptr %alloca, align 1 => b8 00001000(00011001)
; CHECK-NEXT: %vec_bytes1 = insertelement <4 x b8> <b8 0, b8 poison, b8 poison, b8 poison>, b8 %byte_undef, i32 2 => { b8 0x00 , b8 0x!! , b8 0x!! , b8 0x!! }
; CHECK-NEXT: %vec_bytes2 = insertelement <4 x b8> %vec_bytes1, b8 %byte_with_provenance, i32 3 => { b8 0x00 , b8 0x!! , b8 0x!! , b8 00001000(00011001) }
-; CHECK-NEXT: %bytes = bitcast <4 x b8> %vec_bytes2 to b32 => b32 0x00 0x!! 0x!! 00001000(00011001)
+; CHECK-NEXT: %bytes = bytecast <4 x b8> %vec_bytes2 to b32 => b32 0x00 0x!! 0x!! 00001000(00011001)
; CHECK-NEXT: %bytes_freeze = freeze b32 %bytes => b32 0x00 0x13 0xF8 00001000(00011001)
; CHECK-NEXT: ret void
; CHECK-NEXT: Exiting function: main
diff --git a/llvm/test/tools/llubi/loadstore_be.ll b/llvm/test/tools/llubi/loadstore_be.ll
index fe2733dc8149c..be40bff06db4f 100644
--- a/llvm/test/tools/llubi/loadstore_be.ll
+++ b/llvm/test/tools/llubi/loadstore_be.ll
@@ -123,7 +123,7 @@ define void @main() {
store b64 %bytes, ptr %alloc_ptr
; It should recover the provenance.
%ptr_with_provenance2 = load ptr, ptr %alloc_ptr
- %bv64b1 = bitcast b64 %bytes to <64 x b1>
+ %bv64b1 = bytecast b64 %bytes to <64 x b1>
%bv64b1_reversed = call <64 x b1> @llvm.vector.reverse(<64 x b1> %bv64b1)
store <64 x b1> %bv64b1_reversed, ptr %alloc_ptr
; The bit order is incorrect. We cannot recover the provenance.
@@ -133,9 +133,9 @@ define void @main() {
%bytes_tainted = load b64, ptr %alloc_ptr
; The first byte is tainted. We cannot recover the provenance.
%ptr_without_provenance3 = load ptr, ptr %alloc_ptr
- %bv8b8_reversed = bitcast <64 x b1> %bv64b1_reversed to <8 x b8>
+ %bv8b8_reversed = bytecast <64 x b1> %bv64b1_reversed to <8 x b8>
%first_byte_with_provenance_reversed = extractelement <8 x b8> %bv8b8_reversed, i32 7
- %first_byte_with_provenance_reversed_v8b1 = bitcast b8 %first_byte_with_provenance_reversed to <8 x b1>
+ %first_byte_with_provenance_reversed_v8b1 = bytecast b8 %first_byte_with_provenance_reversed to <8 x b1>
%first_byte_with_provenance_v8b1 = call <8 x b1> @llvm.vector.reverse(<8 x b1> %first_byte_with_provenance_reversed_v8b1)
store <8 x b1> %first_byte_with_provenance_v8b1, ptr %alloc_ptr
%bytes_recovered = load b64, ptr %alloc_ptr
@@ -258,7 +258,7 @@ define void @main() {
; CHECK-NEXT: %ptr_without_provenance = load ptr, ptr %alloc_ptr, align 8 => ptr 0xC0 [nullary]
; CHECK-NEXT: store b64 %bytes, ptr %alloc_ptr, align 8
; CHECK-NEXT: %ptr_with_provenance2 = load ptr, ptr %alloc_ptr, align 8 => ptr 0xC0 [alloc_ptr]
-; CHECK-NEXT: %bv64b1 = bitcast b64 %bytes to <64 x b1> => { b1 0(0) , b1 0(0) , b1 0(1) , b1 0(0) , b1 0(0) , b1 0(1) , b1 0(1) , b1 0(0) , b1 0(0) , b1 0(1) , b1 0(1) , b1 0(1) , b1 0(0) , b1 0(0) , b1 0(0) , b1 0(1) , b1 0(0) , b1 0(0) , b1 0(1) , b1 0(1) , b1 0(1) , b1 0(1) , b1 0(0) , b1 0(0) , b1 0(0) , b1 0(0) , b1 0(1) , b1 0(1) , b1 0(1) , b1 0(0) , b1 0(0) , b1 0(1) , b1 0(1) , b1 0(0) , b1 0(0) , b1 0(0) , b1 0(1) , b1 0(0) , b1 0(1) , b1 0(0) , b1 0(1) , b1 0(0) , b1 0(0) , b1 0(1) , b1 0(0) , b1 0(1) , b1 0(0) , b1 0(1) , b1 0(0) , b1 0(0) , b1 0(0) , b1 0(0) , b1 0(1) , b1 0(0) , b1 0(0) , b1 0(0) , b1 1(0) , b1 1(0) , b1 0(1) , b1 0(0) , b1 0(1) , b1 0(1) , b1 0(0) , b1 0(0) }
+; CHECK-NEXT: %bv64b1 = bytecast b64 %bytes to <64 x b1> => { b1 0(0) , b1 0(0) , b1 0(1) , b1 0(0) , b1 0(0) , b1 0(1) , b1 0(1) , b1 0(0) , b1 0(0) , b1 0(1) , b1 0(1) , b1 0(1) , b1 0(0) , b1 0(0) , b1 0(0) , b1 0(1) , b1 0(0) , b1 0(0) , b1 0(1) , b1 0(1) , b1 0(1) , b1 0(1) , b1 0(0) , b1 0(0) , b1 0(0) , b1 0(0) , b1 0(1) , b1 0(1) , b1 0(1) , b1 0(0) , b1 0(0) , b1 0(1) , b1 0(1) , b1 0(0) , b1 0(0) , b1 0(0) , b1 0(1) , b1 0(0) , b1 0(1) , b1 0(0) , b1 0(1) , b1 0(0) , b1 0(0) , b1 0(1) , b1 0(0) , b1 0(1) , b1 0(0) , b1 0(1) , b1 0(0) , b1 0(0) , b1 0(0) , b1 0(0) , b1 0(1) , b1 0(0) , b1 0(0) , b1 0(0) , b1 1(0) , b1 1(0) , b1 0(1) , b1 0(0) , b1 0(1) , b1 0(1) , b1 0(0) , b1 0(0) }
; CHECK-NEXT: %bv64b1_reversed = call <64 x b1> @llvm.vector.reverse.v64b1(<64 x b1> %bv64b1) => { b1 0(0) , b1 0(0) , b1 0(1) , b1 0(1) , b1 0(0) , b1 0(1) , b1 1(0) , b1 1(0) , b1 0(0) , b1 0(0) , b1 0(0) , b1 0(1) , b1 0(0) , b1 0(0) , b1 0(0) , b1 0(0) , b1 0(1) , b1 0(0) , b1 0(1) , b1 0(0) , b1 0(1) , b1 0(0) , b1 0(0) , b1 0(1) , b1 0(0) , b1 0(1) , b1 0(0) , b1 0(1) , b1 0(0) , b1 0(0) , b1 0(0) , b1 0(1) , b1 0(1) , b1 0(0) , b1 0(0) , b1 0(1) , b1 0(1) , b1 0(1) , b1 0(0) , b1 0(0) , b1 0(0) , b1 0(0) , b1 0(1) , b1 0(1) , b1 0(1) , b1 0(1) , b1 0(0) , b1 0(0) , b1 0(1) , b1 0(0) , b1 0(0) , b1 0(0) , b1 0(1) , b1 0(1) , b1 0(1) , b1 0(0) , b1 0(0) , b1 0(1) , b1 0(1) , b1 0(0) , b1 0(0) , b1 0(1) , b1 0(0) , b1 0(0) }
; CHECK-NEXT: store <64 x b1> %bv64b1_reversed, ptr %alloc_ptr, align 8
; CHECK-NEXT: %ptr_without_provenance2 = load ptr, ptr %alloc_ptr, align 8 => ptr 0x300000000000000 [nullary]
@@ -266,9 +266,9 @@ define void @main() {
; CHECK-NEXT: store <2 x b4> <b4 0, b4 poison>, ptr %alloc_ptr, align 1
; CHECK-NEXT: %bytes_tainted = load b64, ptr %alloc_ptr, align 8 => b64 0000!!!! 00000000(01110001) 00000000(00111100) 00000000(00111001) 00000000(10001010) 00000000(10010101) 00000000(00001000) 11000000(00101100)
; CHECK-NEXT: %ptr_without_provenance3 = load ptr, ptr %alloc_ptr, align 8 => poison
-; CHECK-NEXT: %bv8b8_reversed = bitcast <64 x b1> %bv64b1_reversed to <8 x b8> => { b8 00000011(00110100) , b8 00000000(00010000) , b8 00000000(10101001) , b8 00000000(01010001) , b8 00000000(10011100) , b8 00000000(00111100) , b8 00000000(10001110) , b8 00000000(01100100) }
+; CHECK-NEXT: %bv8b8_reversed = bytecast <64 x b1> %bv64b1_reversed to <8 x b8> => { b8 00000011(00110100) , b8 00000000(00010000) , b8 00000000(10101001) , b8 00000000(01010001) , b8 00000000(10011100) , b8 00000000(00111100) , b8 00000000(10001110) , b8 00000000(01100100) }
; CHECK-NEXT: %first_byte_with_provenance_reversed = extractelement <8 x b8> %bv8b8_reversed, i32 7 => b8 00000000(01100100)
-; CHECK-NEXT: %first_byte_with_provenance_reversed_v8b1 = bitcast b8 %first_byte_with_provenance_reversed to <8 x b1> => { b1 0(0) , b1 0(1) , b1 0(1) , b1 0(0) , b1 0(0) , b1 0(1) , b1 0(0) , b1 0(0) }
+; CHECK-NEXT: %first_byte_with_provenance_reversed_v8b1 = bytecast b8 %first_byte_with_provenance_reversed to <8 x b1> => { b1 0(0) , b1 0(1) , b1 0(1) , b1 0(0) , b1 0(0) , b1 0(1) , b1 0(0) , b1 0(0) }
; CHECK-NEXT: %first_byte_with_provenance_v8b1 = call <8 x b1> @llvm.vector.reverse.v8b1(<8 x b1> %first_byte_with_provenance_reversed_v8b1) => { b1 0(0) , b1 0(0) , b1 0(1) , b1 0(0) , b1 0(0) , b1 0(1) , b1 0(1) , b1 0(0) }
; CHECK-NEXT: store <8 x b1> %first_byte_with_provenance_v8b1, ptr %alloc_ptr, align 1
; CHECK-NEXT: %bytes_recovered = load b64, ptr %alloc_ptr, align 8 => b64 ptr 0xC0 [alloc_ptr]
diff --git a/llvm/test/tools/llubi/loadstore_le.ll b/llvm/test/tools/llubi/loadstore_le.ll
index 9c434461380cc..3703a44da4fa8 100644
--- a/llvm/test/tools/llubi/loadstore_le.ll
+++ b/llvm/test/tools/llubi/loadstore_le.ll
@@ -124,7 +124,7 @@ define void @main() {
store b64 %bytes, ptr %alloc_ptr
; It should recover the provenance.
%ptr_with_provenance2 = load ptr, ptr %alloc_ptr
- %bv64b1 = bitcast b64 %bytes to <64 x b1>
+ %bv64b1 = bytecast b64 %bytes to <64 x b1>
%bv64b1_reversed = call <64 x b1> @llvm.vector.reverse(<64 x b1> %bv64b1)
store <64 x b1> %bv64b1_reversed, ptr %alloc_ptr
; The bit order is incorrect. We cannot recover the provenance.
@@ -134,9 +134,9 @@ define void @main() {
%bytes_tainted = load b64, ptr %alloc_ptr
; The first byte is tainted. We cannot recover the provenance.
%ptr_without_provenance3 = load ptr, ptr %alloc_ptr
- %bv8b8_reversed = bitcast <64 x b1> %bv64b1_reversed to <8 x b8>
+ %bv8b8_reversed = bytecast <64 x b1> %bv64b1_reversed to <8 x b8>
%first_byte_with_provenance_reversed = extractelement <8 x b8> %bv8b8_reversed, i32 7
- %first_byte_with_provenance_reversed_v8b1 = bitcast b8 %first_byte_with_provenance_reversed to <8 x b1>
+ %first_byte_with_provenance_reversed_v8b1 = bytecast b8 %first_byte_with_provenance_reversed to <8 x b1>
%first_byte_with_provenance_v8b1 = call <8 x b1> @llvm.vector.reverse(<8 x b1> %first_byte_with_provenance_reversed_v8b1)
store <8 x b1> %first_byte_with_provenance_v8b1, ptr %alloc_ptr
%bytes_recovered = load b64, ptr %alloc_ptr
@@ -260,7 +260,7 @@ define void @main() {
; CHECK-NEXT: %ptr_without_provenance = load ptr, ptr %alloc_ptr, align 8 => ptr 0xC0 [nullary]
; CHECK-NEXT: store b64 %bytes, ptr %alloc_ptr, align 8
; CHECK-NEXT: %ptr_with_provenance2 = load ptr, ptr %alloc_ptr, align 8 => ptr 0xC0 [alloc_ptr]
-; CHECK-NEXT: %bv64b1 = bitcast b64 %bytes to <64 x b1> => { b1 0(0) , b1 0(0) , b1 0(1) , b1 0(1) , b1 0(0) , b1 0(1) , b1 1(0) , b1 1(0) , b1 0(0) , b1 0(0) , b1 0(0) , b1 0(1) , b1 0(0) , b1 0(0) , b1 0(0) , b1 0(0) , b1 0(1) , b1 0(0) , b1 0(1) , b1 0(0) , b1 0(1) , b1 0(0) , b1 0(0) , b1 0(1) , b1 0(0) , b1 0(1) , b1 0(0) , b1 0(1) , b1 0(0) , b1 0(0) , b1 0(0) , b1 0(1) , b1 0(1) , b1 0(0) , b1 0(0) , b1 0(1) , b1 0(1) , b1 0(1) , b1 0(0) , b1 0(0) , b1 0(0) , b1 0(0) , b1 0(1) , b1 0(1) , b1 0(1) , b1 0(1) , b1 0(0) , b1 0(0) , b1 0(1) , b1 0(0) , b1 0(0) , b1 0(0) , b1 0(1) , b1 0(1) , b1 0(1) , b1 0(0) , b1 0(0) , b1 0(1) , b1 0(1) , b1 0(0) , b1 0(0) , b1 0(1) , b1 0(0) , b1 0(0) }
+; CHECK-NEXT: %bv64b1 = bytecast b64 %bytes to <64 x b1> => { b1 0(0) , b1 0(0) , b1 0(1) , b1 0(1) , b1 0(0) , b1 0(1) , b1 1(0) , b1 1(0) , b1 0(0) , b1 0(0) , b1 0(0) , b1 0(1) , b1 0(0) , b1 0(0) , b1 0(0) , b1 0(0) , b1 0(1) , b1 0(0) , b1 0(1) , b1 0(0) , b1 0(1) , b1 0(0) , b1 0(0) , b1 0(1) , b1 0(0) , b1 0(1) , b1 0(0) , b1 0(1) , b1 0(0) , b1 0(0) , b1 0(0) , b1 0(1) , b1 0(1) , b1 0(0) , b1 0(0) , b1 0(1) , b1 0(1) , b1 0(1) , b1 0(0) , b1 0(0) , b1 0(0) , b1 0(0) , b1 0(1) , b1 0(1) , b1 0(1) , b1 0(1) , b1 0(0) , b1 0(0) , b1 0(1) , b1 0(0) , b1 0(0) , b1 0(0) , b1 0(1) , b1 0(1) , b1 0(1) , b1 0(0) , b1 0(0) , b1 0(1) , b1 0(1) , b1 0(0) , b1 0(0) , b1 0(1) , b1 0(0) , b1 0(0) }
; CHECK-NEXT: %bv64b1_reversed = call <64 x b1> @llvm.vector.reverse.v64b1(<64 x b1> %bv64b1) => { b1 0(0) , b1 0(0) , b1 0(1) , b1 0(0) , b1 0(0) , b1 0(1) , b1 0(1) , b1 0(0) , b1 0(0) , b1 0(1) , b1 0(1) , b1 0(1) , b1 0(0) , b1 0(0) , b1 0(0) , b1 0(1) , b1 0(0) , b1 0(0) , b1 0(1) , b1 0(1) , b1 0(1) , b1 0(1) , b1 0(0) , b1 0(0) , b1 0(0) , b1 0(0) , b1 0(1) , b1 0(1) , b1 0(1) , b1 0(0) , b1 0(0) , b1 0(1) , b1 0(1) , b1 0(0) , b1 0(0) , b1 0(0) , b1 0(1) , b1 0(0) , b1 0(1) , b1 0(0) , b1 0(1) , b1 0(0) , b1 0(0) , b1 0(1) , b1 0(0) , b1 0(1) , b1 0(0) , b1 0(1) , b1 0(0) , b1 0(0) , b1 0(0) , b1 0(0) , b1 0(1) , b1 0(0) , b1 0(0) , b1 0(0) , b1 1(0) , b1 1(0) , b1 0(1) , b1 0(0) , b1 0(1) , b1 0(1) , b1 0(0) , b1 0(0) }
; CHECK-NEXT: store <64 x b1> %bv64b1_reversed, ptr %alloc_ptr, align 8
; CHECK-NEXT: %ptr_without_provenance2 = load ptr, ptr %alloc_ptr, align 8 => ptr 0x300000000000000 [nullary]
@@ -268,9 +268,9 @@ define void @main() {
; CHECK-NEXT: store <2 x b4> <b4 0, b4 poison>, ptr %alloc_ptr, align 1
; CHECK-NEXT: %bytes_tainted = load b64, ptr %alloc_ptr, align 8 => b64 !!!!0000 00000000(00001000) 00000000(10010101) 00000000(10001010) 00000000(00111001) 00000000(00111100) 00000000(01110001) 00000000(00100110)
; CHECK-NEXT: %ptr_without_provenance3 = load ptr, ptr %alloc_ptr, align 8 => poison
-; CHECK-NEXT: %bv8b8_reversed = bitcast <64 x b1> %bv64b1_reversed to <8 x b8> => { b8 00000000(01100100) , b8 00000000(10001110) , b8 00000000(00111100) , b8 00000000(10011100) , b8 00000000(01010001) , b8 00000000(10101001) , b8 00000000(00010000) , b8 00000011(00110100) }
+; CHECK-NEXT: %bv8b8_reversed = bytecast <64 x b1> %bv64b1_reversed to <8 x b8> => { b8 00000000(01100100) , b8 00000000(10001110) , b8 00000000(00111100) , b8 00000000(10011100) , b8 00000000(01010001) , b8 00000000(10101001) , b8 00000000(00010000) , b8 00000011(00110100) }
; CHECK-NEXT: %first_byte_with_provenance_reversed = extractelement <8 x b8> %bv8b8_reversed, i32 7 => b8 00000011(00110100)
-; CHECK-NEXT: %first_byte_with_provenance_reversed_v8b1 = bitcast b8 %first_byte_with_provenance_reversed to <8 x b1> => { b1 1(0) , b1 1(0) , b1 0(1) , b1 0(0) , b1 0(1) , b1 0(1) , b1 0(0) , b1 0(0) }
+; CHECK-NEXT: %first_byte_with_provenance_reversed_v8b1 = bytecast b8 %first_byte_with_provenance_reversed to <8 x b1> => { b1 1(0) , b1 1(0) , b1 0(1) , b1 0(0) , b1 0(1) , b1 0(1) , b1 0(0) , b1 0(0) }
; CHECK-NEXT: %first_byte_with_provenance_v8b1 = call <8 x b1> @llvm.vector.reverse.v8b1(<8 x b1> %first_byte_with_provenance_reversed_v8b1) => { b1 0(0) , b1 0(0) , b1 0(1) , b1 0(1) , b1 0(0) , b1 0(1) , b1 1(0) , b1 1(0) }
; CHECK-NEXT: store <8 x b1> %first_byte_with_provenance_v8b1, ptr %alloc_ptr, align 1
; CHECK-NEXT: %bytes_recovered = load b64, ptr %alloc_ptr, align 8 => b64 ptr 0xC0 [alloc_ptr]
diff --git a/llvm/test/tools/llvm-ir2vec/entities.ll b/llvm/test/tools/llvm-ir2vec/entities.ll
index 002614164c128..41615682397b1 100644
--- a/llvm/test/tools/llvm-ir2vec/entities.ll
+++ b/llvm/test/tools/llvm-ir2vec/entities.ll
@@ -1,6 +1,6 @@
; RUN: llvm-ir2vec entities | FileCheck %s
-CHECK: 112
+CHECK: 113
CHECK-NEXT: Ret 0
CHECK-NEXT: UncondBr 1
CHECK-NEXT: CondBr 2
@@ -70,46 +70,47 @@ CHECK-NEXT: ExtractValue 65
CHECK-NEXT: InsertValue 66
CHECK-NEXT: LandingPad 67
CHECK-NEXT: Freeze 68
-CHECK-NEXT: FloatTy 69
-CHECK-NEXT: VoidTy 70
-CHECK-NEXT: LabelTy 71
-CHECK-NEXT: MetadataTy 72
-CHECK-NEXT: VectorTy 73
-CHECK-NEXT: TokenTy 74
-CHECK-NEXT: IntegerTy 75
-CHECK-NEXT: ByteTy 76
-CHECK-NEXT: FunctionTy 77
-CHECK-NEXT: PointerTy 78
-CHECK-NEXT: StructTy 79
-CHECK-NEXT: ArrayTy 80
-CHECK-NEXT: UnknownTy 81
-CHECK-NEXT: Function 82
-CHECK-NEXT: Pointer 83
-CHECK-NEXT: Constant 84
-CHECK-NEXT: Variable 85
-CHECK-NEXT: FCMP_false 86
-CHECK-NEXT: FCMP_oeq 87
-CHECK-NEXT: FCMP_ogt 88
-CHECK-NEXT: FCMP_oge 89
-CHECK-NEXT: FCMP_olt 90
-CHECK-NEXT: FCMP_ole 91
-CHECK-NEXT: FCMP_one 92
-CHECK-NEXT: FCMP_ord 93
-CHECK-NEXT: FCMP_uno 94
-CHECK-NEXT: FCMP_ueq 95
-CHECK-NEXT: FCMP_ugt 96
-CHECK-NEXT: FCMP_uge 97
-CHECK-NEXT: FCMP_ult 98
-CHECK-NEXT: FCMP_ule 99
-CHECK-NEXT: FCMP_une 100
-CHECK-NEXT: FCMP_true 101
-CHECK-NEXT: ICMP_eq 102
-CHECK-NEXT: ICMP_ne 103
-CHECK-NEXT: ICMP_ugt 104
-CHECK-NEXT: ICMP_uge 105
-CHECK-NEXT: ICMP_ult 106
-CHECK-NEXT: ICMP_ule 107
-CHECK-NEXT: ICMP_sgt 108
-CHECK-NEXT: ICMP_sge 109
-CHECK-NEXT: ICMP_slt 110
-CHECK-NEXT: ICMP_sle 111
+CHECK-NEXT: ByteCast 69
+CHECK-NEXT: FloatTy 70
+CHECK-NEXT: VoidTy 71
+CHECK-NEXT: LabelTy 72
+CHECK-NEXT: MetadataTy 73
+CHECK-NEXT: VectorTy 74
+CHECK-NEXT: TokenTy 75
+CHECK-NEXT: IntegerTy 76
+CHECK-NEXT: ByteTy 77
+CHECK-NEXT: FunctionTy 78
+CHECK-NEXT: PointerTy 79
+CHECK-NEXT: StructTy 80
+CHECK-NEXT: ArrayTy 81
+CHECK-NEXT: UnknownTy 82
+CHECK-NEXT: Function 83
+CHECK-NEXT: Pointer 84
+CHECK-NEXT: Constant 85
+CHECK-NEXT: Variable 86
+CHECK-NEXT: FCMP_false 87
+CHECK-NEXT: FCMP_oeq 88
+CHECK-NEXT: FCMP_ogt 89
+CHECK-NEXT: FCMP_oge 90
+CHECK-NEXT: FCMP_olt 91
+CHECK-NEXT: FCMP_ole 92
+CHECK-NEXT: FCMP_one 93
+CHECK-NEXT: FCMP_ord 94
+CHECK-NEXT: FCMP_uno 95
+CHECK-NEXT: FCMP_ueq 96
+CHECK-NEXT: FCMP_ugt 97
+CHECK-NEXT: FCMP_uge 98
+CHECK-NEXT: FCMP_ult 99
+CHECK-NEXT: FCMP_ule 100
+CHECK-NEXT: FCMP_une 101
+CHECK-NEXT: FCMP_true 102
+CHECK-NEXT: ICMP_eq 103
+CHECK-NEXT: ICMP_ne 104
+CHECK-NEXT: ICMP_ugt 105
+CHECK-NEXT: ICMP_uge 106
+CHECK-NEXT: ICMP_ult 107
+CHECK-NEXT: ICMP_ule 108
+CHECK-NEXT: ICMP_sgt 109
+CHECK-NEXT: ICMP_sge 110
+CHECK-NEXT: ICMP_slt 111
+CHECK-NEXT: ICMP_sle 112
diff --git a/llvm/test/tools/llvm-ir2vec/triplets.ll b/llvm/test/tools/llvm-ir2vec/triplets.ll
index 45a158c926900..23366e90f129b 100644
--- a/llvm/test/tools/llvm-ir2vec/triplets.ll
+++ b/llvm/test/tools/llvm-ir2vec/triplets.ll
@@ -25,41 +25,41 @@ entry:
}
; TRIPLETS: MAX_RELATION=3
-; TRIPLETS-NEXT: 13 75 0
-; TRIPLETS-NEXT: 13 85 2
-; TRIPLETS-NEXT: 13 85 3
+; TRIPLETS-NEXT: 13 76 0
+; TRIPLETS-NEXT: 13 86 2
+; TRIPLETS-NEXT: 13 86 3
; TRIPLETS-NEXT: 13 0 1
-; TRIPLETS-NEXT: 0 70 0
-; TRIPLETS-NEXT: 0 85 2
-; TRIPLETS-NEXT: 17 75 0
-; TRIPLETS-NEXT: 17 85 2
-; TRIPLETS-NEXT: 17 85 3
+; TRIPLETS-NEXT: 0 71 0
+; TRIPLETS-NEXT: 0 86 2
+; TRIPLETS-NEXT: 17 76 0
+; TRIPLETS-NEXT: 17 86 2
+; TRIPLETS-NEXT: 17 86 3
; TRIPLETS-NEXT: 17 0 1
-; TRIPLETS-NEXT: 0 70 0
-; TRIPLETS-NEXT: 0 85 2
-; TRIPLETS-NEXT: 31 78 0
-; TRIPLETS-NEXT: 31 84 2
+; TRIPLETS-NEXT: 0 71 0
+; TRIPLETS-NEXT: 0 86 2
+; TRIPLETS-NEXT: 31 79 0
+; TRIPLETS-NEXT: 31 85 2
; TRIPLETS-NEXT: 31 31 1
-; TRIPLETS-NEXT: 31 78 0
-; TRIPLETS-NEXT: 31 84 2
+; TRIPLETS-NEXT: 31 79 0
+; TRIPLETS-NEXT: 31 85 2
; TRIPLETS-NEXT: 31 33 1
-; TRIPLETS-NEXT: 33 70 0
-; TRIPLETS-NEXT: 33 85 2
-; TRIPLETS-NEXT: 33 83 3
+; TRIPLETS-NEXT: 33 71 0
+; TRIPLETS-NEXT: 33 86 2
+; TRIPLETS-NEXT: 33 84 3
; TRIPLETS-NEXT: 33 33 1
-; TRIPLETS-NEXT: 33 70 0
-; TRIPLETS-NEXT: 33 85 2
-; TRIPLETS-NEXT: 33 83 3
+; TRIPLETS-NEXT: 33 71 0
+; TRIPLETS-NEXT: 33 86 2
+; TRIPLETS-NEXT: 33 84 3
; TRIPLETS-NEXT: 33 32 1
-; TRIPLETS-NEXT: 32 75 0
-; TRIPLETS-NEXT: 32 83 2
+; TRIPLETS-NEXT: 32 76 0
+; TRIPLETS-NEXT: 32 84 2
; TRIPLETS-NEXT: 32 32 1
-; TRIPLETS-NEXT: 32 75 0
-; TRIPLETS-NEXT: 32 83 2
+; TRIPLETS-NEXT: 32 76 0
+; TRIPLETS-NEXT: 32 84 2
; TRIPLETS-NEXT: 32 13 1
-; TRIPLETS-NEXT: 13 75 0
-; TRIPLETS-NEXT: 13 85 2
-; TRIPLETS-NEXT: 13 85 3
+; TRIPLETS-NEXT: 13 76 0
+; TRIPLETS-NEXT: 13 86 2
+; TRIPLETS-NEXT: 13 86 3
; TRIPLETS-NEXT: 13 0 1
-; TRIPLETS-NEXT: 0 70 0
-; TRIPLETS-NEXT: 0 85 2
+; TRIPLETS-NEXT: 0 71 0
+; TRIPLETS-NEXT: 0 86 2
diff --git a/llvm/tools/llubi/lib/Context.cpp b/llvm/tools/llubi/lib/Context.cpp
index 048eec8e8c52d..c4d97f10ab555 100644
--- a/llvm/tools/llubi/lib/Context.cpp
+++ b/llvm/tools/llubi/lib/Context.cpp
@@ -201,7 +201,8 @@ MaterializedConstant Context::evaluateConstantExpression(ConstantExpr *CE) {
}
return MaterializedConstant(std::move(Vec), Src->isCacheable());
}
- case Instruction::BitCast: {
+ case Instruction::BitCast:
+ case Instruction::ByteCast: {
Constant *SrcOp = CE->getOperand(0);
const auto *Src = getConstantValue(SrcOp);
if (!Src)
diff --git a/llvm/tools/llubi/lib/Interpreter.cpp b/llvm/tools/llubi/lib/Interpreter.cpp
index 77b7fae4c4ab3..b2be6dbc0db90 100644
--- a/llvm/tools/llubi/lib/Interpreter.cpp
+++ b/llvm/tools/llubi/lib/Interpreter.cpp
@@ -2799,17 +2799,20 @@ class InstExecutor : public InstVisitor<InstExecutor, void>,
setResult(SVI, std::move(Res));
}
- void visitBitCastInst(BitCastInst &BCI) {
+ void visitBitCastLike(CastInst &CI) {
// The conversion is done as if the value had been stored to memory and read
// back as the target type.
SmallVector<Byte> Bytes;
- Bytes.resize(Ctx.getEffectiveTypeStoreSize(BCI.getType()),
+ Bytes.resize(Ctx.getEffectiveTypeStoreSize(CI.getType()),
Byte::concrete(0));
- Ctx.toBytes(getValue(BCI.getOperand(0)), BCI.getOperand(0)->getType(),
- Bytes);
- setResult(BCI, Ctx.fromBytes(Bytes, BCI.getType()));
+ Ctx.toBytes(getValue(CI.getOperand(0)), CI.getOperand(0)->getType(), Bytes);
+ setResult(CI, Ctx.fromBytes(Bytes, CI.getType()));
}
+ void visitBitCastInst(BitCastInst &BCI) { visitBitCastLike(BCI); }
+
+ void visitByteCastInst(ByteCastInst &BCI) { visitBitCastLike(BCI); }
+
void visitFreezeInst(FreezeInst &FI) {
AnyValue Val = getValue(FI.getOperand(0));
Ctx.freeze(Val, FI.getType());
diff --git a/llvm/unittests/Analysis/IR2VecTest.cpp b/llvm/unittests/Analysis/IR2VecTest.cpp
index fe67442da0f90..4678c6ef25722 100644
--- a/llvm/unittests/Analysis/IR2VecTest.cpp
+++ b/llvm/unittests/Analysis/IR2VecTest.cpp
@@ -363,8 +363,8 @@ TEST_F(IR2VecTestFixture, GetInstVec_Symbolic) {
EXPECT_EQ(AddEmb.size(), 2u);
EXPECT_EQ(RetEmb.size(), 2u);
- EXPECT_TRUE(AddEmb.approximatelyEquals(Embedding(2, 26.1)));
- EXPECT_TRUE(RetEmb.approximatelyEquals(Embedding(2, 15.8)));
+ EXPECT_TRUE(AddEmb.approximatelyEquals(Embedding(2, 26.4)));
+ EXPECT_TRUE(RetEmb.approximatelyEquals(Embedding(2, 16.0)));
}
TEST_F(IR2VecTestFixture, GetInstVec_FlowAware) {
@@ -376,8 +376,8 @@ TEST_F(IR2VecTestFixture, GetInstVec_FlowAware) {
EXPECT_EQ(AddEmb.size(), 2u);
EXPECT_EQ(RetEmb.size(), 2u);
- EXPECT_TRUE(AddEmb.approximatelyEquals(Embedding(2, 26.1)));
- EXPECT_TRUE(RetEmb.approximatelyEquals(Embedding(2, 33.3)));
+ EXPECT_TRUE(AddEmb.approximatelyEquals(Embedding(2, 26.4)));
+ EXPECT_TRUE(RetEmb.approximatelyEquals(Embedding(2, 33.7)));
}
TEST_F(IR2VecTestFixture, GetBBVector_Symbolic) {
@@ -387,9 +387,9 @@ TEST_F(IR2VecTestFixture, GetBBVector_Symbolic) {
const auto &BBVec = Emb->getBBVector(*BB);
EXPECT_EQ(BBVec.size(), 2u);
- // BB vector should be sum of add and ret: {26.1, 26.1} + {15.8, 15.8} =
- // {41.9, 41.9}
- EXPECT_TRUE(BBVec.approximatelyEquals(Embedding(2, 41.9)));
+ // BB vector should be sum of add and ret: {26.4, 26.4} + {16.0, 16.0} =
+ // {42.4, 42.4}
+ EXPECT_TRUE(BBVec.approximatelyEquals(Embedding(2, 42.4)));
}
TEST_F(IR2VecTestFixture, GetBBVector_FlowAware) {
@@ -399,9 +399,9 @@ TEST_F(IR2VecTestFixture, GetBBVector_FlowAware) {
const auto &BBVec = Emb->getBBVector(*BB);
EXPECT_EQ(BBVec.size(), 2u);
- // BB vector should be sum of add and ret: {26.1, 26.1} + {33.3, 33.3} =
- // {59.4, 59.4}
- EXPECT_TRUE(BBVec.approximatelyEquals(Embedding(2, 59.4)));
+ // BB vector should be sum of add and ret: {26.4, 26.4} + {33.7, 33.7} =
+ // {60.1, 60.1}
+ EXPECT_TRUE(BBVec.approximatelyEquals(Embedding(2, 60.1)));
}
TEST_F(IR2VecTestFixture, GetFunctionVector_Symbolic) {
@@ -412,8 +412,8 @@ TEST_F(IR2VecTestFixture, GetFunctionVector_Symbolic) {
EXPECT_EQ(FuncVec.size(), 2u);
- // Function vector should match BB vector (only one BB): {41.9, 41.9}
- EXPECT_TRUE(FuncVec.approximatelyEquals(Embedding(2, 41.9)));
+ // Function vector should match BB vector (only one BB): {42.4, 42.4}
+ EXPECT_TRUE(FuncVec.approximatelyEquals(Embedding(2, 42.4)));
}
TEST_F(IR2VecTestFixture, GetFunctionVector_FlowAware) {
@@ -423,8 +423,8 @@ TEST_F(IR2VecTestFixture, GetFunctionVector_FlowAware) {
const auto &FuncVec = Emb->getFunctionVector();
EXPECT_EQ(FuncVec.size(), 2u);
- // Function vector should match BB vector (only one BB): {59.4, 59.4}
- EXPECT_TRUE(FuncVec.approximatelyEquals(Embedding(2, 59.4)));
+ // Function vector should match BB vector (only one BB): {60.1, 60.1}
+ EXPECT_TRUE(FuncVec.approximatelyEquals(Embedding(2, 60.1)));
}
TEST_F(IR2VecTestFixture, MultipleComputeEmbeddingsConsistency_Symbolic) {
More information about the llvm-commits
mailing list