Skip to content

Commit d12d4dd

Browse files
spavloffDanielCChen
authored andcommitted
[IR] Allow MDString in operand bundles (llvm#110805)
This change implements support of metadata strings in operand bundle values. It makes possible calls like: call void @some_func(i32 %x) [ "foo"(i32 42, metadata !"abc") ] It requires some extension of the bitcode serialization. As SSA values and metadata are stored in different tables, there must be a way to distinguish them during deserialization. It is implemented by putting a special marker before the metadata index. The marker cannot be treated as a reference to any SSA value, so it unambiguously identifies metadata. It allows extending the bitcode serialization without breaking compatibility. Metadata as operand bundle values are intended to be used in floating-point function calls. They would represent the same information as now is passed by the constrained intrinsic arguments.
1 parent 4779dac commit d12d4dd

File tree

8 files changed

+82
-7
lines changed

8 files changed

+82
-7
lines changed

llvm/docs/LangRef.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2666,16 +2666,16 @@ are grouped into a single :ref:`attribute group <attrgrp>`.
26662666
Operand Bundles
26672667
---------------
26682668

2669-
Operand bundles are tagged sets of SSA values that can be associated
2670-
with certain LLVM instructions (currently only ``call`` s and
2669+
Operand bundles are tagged sets of SSA values or metadata strings that can be
2670+
associated with certain LLVM instructions (currently only ``call`` s and
26712671
``invoke`` s). In a way they are like metadata, but dropping them is
26722672
incorrect and will change program semantics.
26732673

26742674
Syntax::
26752675

26762676
operand bundle set ::= '[' operand bundle (, operand bundle )* ']'
26772677
operand bundle ::= tag '(' [ bundle operand ] (, bundle operand )* ')'
2678-
bundle operand ::= SSA value
2678+
bundle operand ::= SSA value | metadata string
26792679
tag ::= string constant
26802680

26812681
Operand bundles are **not** part of a function's signature, and a

llvm/docs/ReleaseNotes.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ Changes to the LLVM IR
8888
* `llvm.nvvm.ptr.shared.to.gen`
8989
* `llvm.nvvm.ptr.constant.to.gen`
9090
* `llvm.nvvm.ptr.local.to.gen`
91+
92+
* Operand bundle values can now be metadata strings.
9193

9294
Changes to LLVM infrastructure
9395
------------------------------

llvm/include/llvm/Bitcode/LLVMBitCodes.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,9 @@ enum PossiblyExactOperatorOptionalFlags { PEO_EXACT = 0 };
529529
/// PossiblyDisjointInst's SubclassOptionalData contents.
530530
enum PossiblyDisjointInstOptionalFlags { PDI_DISJOINT = 0 };
531531

532+
/// Mark to distinguish metadata from value in an operator bundle.
533+
enum MetadataOperandBundleValueMarker { OB_METADATA = 0x80000000 };
534+
532535
/// GetElementPtrOptionalFlags - Flags for serializing
533536
/// GEPOperator's SubclassOptionalData contents.
534537
enum GetElementPtrOptionalFlags {

llvm/lib/AsmParser/LLParser.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3202,8 +3202,14 @@ bool LLParser::parseOptionalOperandBundles(
32023202

32033203
Type *Ty = nullptr;
32043204
Value *Input = nullptr;
3205-
if (parseType(Ty) || parseValue(Ty, Input, PFS))
3205+
if (parseType(Ty))
32063206
return true;
3207+
if (Ty->isMetadataTy()) {
3208+
if (parseMetadataAsValue(Input, PFS))
3209+
return true;
3210+
} else if (parseValue(Ty, Input, PFS)) {
3211+
return true;
3212+
}
32073213
Inputs.push_back(Input);
32083214
}
32093215

llvm/lib/Bitcode/Reader/BitcodeReader.cpp

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -792,6 +792,24 @@ class BitcodeReader : public BitcodeReaderBase, public GVMaterializer {
792792
return ResVal == nullptr;
793793
}
794794

795+
bool getValueOrMetadata(const SmallVectorImpl<uint64_t> &Record,
796+
unsigned &Slot, unsigned InstNum, Value *&ResVal,
797+
BasicBlock *ConstExprInsertBB) {
798+
if (Slot == Record.size())
799+
return true;
800+
unsigned ValID = Record[Slot++];
801+
if (ValID != bitc::OB_METADATA) {
802+
unsigned TypeId;
803+
return getValueTypePair(Record, --Slot, InstNum, ResVal, TypeId,
804+
ConstExprInsertBB);
805+
}
806+
if (Slot == Record.size())
807+
return true;
808+
unsigned ValNo = InstNum - (unsigned)Record[Slot++];
809+
ResVal = MetadataAsValue::get(Context, getFnMetadataByID(ValNo));
810+
return false;
811+
}
812+
795813
/// Read a value out of the specified record from slot 'Slot'. Increment Slot
796814
/// past the number of slots used by the value in the record. Return true if
797815
/// there is an error.
@@ -6767,8 +6785,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
67676785
unsigned OpNum = 1;
67686786
while (OpNum != Record.size()) {
67696787
Value *Op;
6770-
unsigned OpTypeID;
6771-
if (getValueTypePair(Record, OpNum, NextValueNo, Op, OpTypeID, CurBB))
6788+
if (getValueOrMetadata(Record, OpNum, NextValueNo, Op, CurBB))
67726789
return error("Invalid record");
67736790
Inputs.push_back(Op);
67746791
}

llvm/lib/Bitcode/Writer/BitcodeWriter.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,8 @@ class ModuleBitcodeWriter : public ModuleBitcodeWriterBase {
395395
void writeModuleConstants();
396396
bool pushValueAndType(const Value *V, unsigned InstID,
397397
SmallVectorImpl<unsigned> &Vals);
398+
bool pushValueOrMetadata(const Value *V, unsigned InstID,
399+
SmallVectorImpl<unsigned> &Vals);
398400
void writeOperandBundles(const CallBase &CB, unsigned InstID);
399401
void pushValue(const Value *V, unsigned InstID,
400402
SmallVectorImpl<unsigned> &Vals);
@@ -2931,6 +2933,19 @@ bool ModuleBitcodeWriter::pushValueAndType(const Value *V, unsigned InstID,
29312933
return false;
29322934
}
29332935

2936+
bool ModuleBitcodeWriter::pushValueOrMetadata(const Value *V, unsigned InstID,
2937+
SmallVectorImpl<unsigned> &Vals) {
2938+
bool IsMetadata = V->getType()->isMetadataTy();
2939+
if (IsMetadata) {
2940+
Vals.push_back(bitc::OB_METADATA);
2941+
Metadata *MD = cast<MetadataAsValue>(V)->getMetadata();
2942+
unsigned ValID = VE.getMetadataID(MD);
2943+
Vals.push_back(InstID - ValID);
2944+
return false;
2945+
}
2946+
return pushValueAndType(V, InstID, Vals);
2947+
}
2948+
29342949
void ModuleBitcodeWriter::writeOperandBundles(const CallBase &CS,
29352950
unsigned InstID) {
29362951
SmallVector<unsigned, 64> Record;
@@ -2941,7 +2956,7 @@ void ModuleBitcodeWriter::writeOperandBundles(const CallBase &CS,
29412956
Record.push_back(C.getOperandBundleTagID(Bundle.getTagName()));
29422957

29432958
for (auto &Input : Bundle.Inputs)
2944-
pushValueAndType(Input, InstID, Record);
2959+
pushValueOrMetadata(Input, InstID, Record);
29452960

29462961
Stream.EmitRecord(bitc::FUNC_CODE_OPERAND_BUNDLE, Record);
29472962
Record.clear();

llvm/test/Bitcode/compatibility.ll

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1327,6 +1327,14 @@ continue:
13271327
ret i32 0
13281328
}
13291329

1330+
declare void @instructions.bundles.callee(i32)
1331+
define void @instructions.bundles.metadata(i32 %x) {
1332+
entry:
1333+
call void @instructions.bundles.callee(i32 %x) [ "foo"(i32 42, metadata !"abc"), "bar"(metadata !"abcde", metadata !"qwerty") ]
1334+
; CHECK: call void @instructions.bundles.callee(i32 %x) [ "foo"(i32 42, metadata !"abc"), "bar"(metadata !"abcde", metadata !"qwerty") ]
1335+
ret void
1336+
}
1337+
13301338
; Instructions -- Unary Operations
13311339
define void @instructions.unops(double %op1) {
13321340
fneg double %op1

llvm/test/Bitcode/operand-bundles.ll

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,13 @@ define void @f4(i32* %ptr) {
5656
ret void
5757
}
5858

59+
define void @f5(i32 %x) {
60+
entry:
61+
call void @callee1(i32 10, i32 %x) [ "foo"(i32 42, metadata !"abc"), "bar"(metadata !"abcde", metadata !"qwerty") ]
62+
; CHECK: call void @callee1(i32 10, i32 %x) [ "foo"(i32 42, metadata !"abc"), "bar"(metadata !"abcde", metadata !"qwerty") ]
63+
ret void
64+
}
65+
5966
; Invoke versions of the above tests:
6067

6168

@@ -150,3 +157,20 @@ exception:
150157
normal:
151158
ret void
152159
}
160+
161+
define void @g5(ptr %ptr) personality i8 3 {
162+
entry:
163+
%l = load i32, ptr %ptr, align 4
164+
%x = add i32 42, 1
165+
invoke void @callee1(i32 10, i32 %x) [ "foo"(i32 42, metadata !"abc"), "bar"(metadata !"abcde", metadata !"qwerty") ]
166+
to label %normal unwind label %exception
167+
; CHECK: invoke void @callee1(i32 10, i32 %x) [ "foo"(i32 42, metadata !"abc"), "bar"(metadata !"abcde", metadata !"qwerty") ]
168+
169+
exception: ; preds = %entry
170+
%cleanup = landingpad i8
171+
cleanup
172+
br label %normal
173+
174+
normal: ; preds = %exception, %entry
175+
ret void
176+
}

0 commit comments

Comments
 (0)