Skip to content

Commit d8fadad

Browse files
authored
[mlir][LLVMIR] Add operand bundle support for llvm.intr.assume (#112143)
This patch adds operand bundle support for `llvm.intr.assume`. This patch actually contains two parts: - `llvm.intr.assume` now accepts operand bundle related attributes and operands. `llvm.intr.assume` does not take constraint on the operand bundles, but obviously only a few set of operand bundles are meaningful. I plan to add some of those (e.g. `aligned` and `separate_storage` are what interest me but other people may be interested in other operand bundles as well) in future patches. - The definitions of `llvm.call`, `llvm.invoke`, and `llvm.call_intrinsic` actually define `op_bundle_tags` as an operation property. It turns out this approach would introduce some unnecessary burden if applied equally to the intrinsic operations because properties are not available through `Operation *` but we have to operate on `Operation *` during the import/export of intrinsics, so this PR changes it from a property to an array attribute.
1 parent 5716f83 commit d8fadad

20 files changed

+276
-77
lines changed

mlir/include/mlir/Dialect/ArmSME/IR/ArmSMEIntrinsicOps.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ class ArmSME_IntrOp<string mnemonic,
7171
/*bit requiresAccessGroup=*/0,
7272
/*bit requiresAliasAnalysis=*/0,
7373
/*bit requiresFastmath=*/0,
74+
/*bit requiresOpBundles=*/0,
7475
/*list<int> immArgPositions=*/immArgPositions,
7576
/*list<string> immArgAttrNames=*/immArgAttrNames>;
7677

mlir/include/mlir/Dialect/LLVMIR/LLVMDialect.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ def LLVM_Dialect : Dialect {
5959
static StringRef getStructRetAttrName() { return "llvm.sret"; }
6060
static StringRef getWriteOnlyAttrName() { return "llvm.writeonly"; }
6161
static StringRef getZExtAttrName() { return "llvm.zeroext"; }
62+
static StringRef getOpBundleSizesAttrName() { return "op_bundle_sizes"; }
63+
static StringRef getOpBundleTagsAttrName() { return "op_bundle_tags"; }
6264
// TODO Restrict the usage of this to parameter attributes once there is an
6365
// alternative way of modeling memory effects on FunctionOpInterface.
6466
/// Name of the attribute that will cause the creation of a readnone memory

mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,8 @@ def LLVM_Log2Op : LLVM_UnaryIntrOpF<"log2">;
120120
def LLVM_LogOp : LLVM_UnaryIntrOpF<"log">;
121121
def LLVM_Prefetch : LLVM_ZeroResultIntrOp<"prefetch", [0],
122122
/*traits=*/[], /*requiresAccessGroup=*/0, /*requiresAliasAnalysis=*/0,
123-
/*immArgPositions=*/[1, 2, 3], /*immArgAttrNames=*/["rw", "hint", "cache"]
123+
/*requiresOpBundles=*/0, /*immArgPositions=*/[1, 2, 3],
124+
/*immArgAttrNames=*/["rw", "hint", "cache"]
124125
> {
125126
let arguments = (ins LLVM_AnyPointer:$addr, I32Attr:$rw, I32Attr:$hint, I32Attr:$cache);
126127
}
@@ -176,7 +177,8 @@ class LLVM_MemcpyIntrOpBase<string name> :
176177
DeclareOpInterfaceMethods<DestructurableAccessorOpInterface>,
177178
DeclareOpInterfaceMethods<SafeMemorySlotAccessOpInterface>],
178179
/*requiresAccessGroup=*/1, /*requiresAliasAnalysis=*/1,
179-
/*immArgPositions=*/[3], /*immArgAttrNames=*/["isVolatile"]> {
180+
/*requiresOpBundles=*/0, /*immArgPositions=*/[3],
181+
/*immArgAttrNames=*/["isVolatile"]> {
180182
dag args = (ins Arg<LLVM_AnyPointer,"",[MemWrite]>:$dst,
181183
Arg<LLVM_AnyPointer,"",[MemRead]>:$src,
182184
AnySignlessInteger:$len, I1Attr:$isVolatile);
@@ -206,7 +208,8 @@ def LLVM_MemcpyInlineOp :
206208
DeclareOpInterfaceMethods<DestructurableAccessorOpInterface>,
207209
DeclareOpInterfaceMethods<SafeMemorySlotAccessOpInterface>],
208210
/*requiresAccessGroup=*/1, /*requiresAliasAnalysis=*/1,
209-
/*immArgPositions=*/[2, 3], /*immArgAttrNames=*/["len", "isVolatile"]> {
211+
/*requiresOpBundles=*/0, /*immArgPositions=*/[2, 3],
212+
/*immArgAttrNames=*/["len", "isVolatile"]> {
210213
dag args = (ins Arg<LLVM_AnyPointer,"",[MemWrite]>:$dst,
211214
Arg<LLVM_AnyPointer,"",[MemRead]>:$src,
212215
APIntAttr:$len, I1Attr:$isVolatile);
@@ -232,7 +235,8 @@ def LLVM_MemsetOp : LLVM_ZeroResultIntrOp<"memset", [0, 2],
232235
DeclareOpInterfaceMethods<DestructurableAccessorOpInterface>,
233236
DeclareOpInterfaceMethods<SafeMemorySlotAccessOpInterface>],
234237
/*requiresAccessGroup=*/1, /*requiresAliasAnalysis=*/1,
235-
/*immArgPositions=*/[3], /*immArgAttrNames=*/["isVolatile"]> {
238+
/*requiresOpBundles=*/0, /*immArgPositions=*/[3],
239+
/*immArgAttrNames=*/["isVolatile"]> {
236240
dag args = (ins Arg<LLVM_AnyPointer,"",[MemWrite]>:$dst,
237241
I8:$val, AnySignlessInteger:$len, I1Attr:$isVolatile);
238242
// Append the alias attributes defined by LLVM_IntrOpBase.
@@ -286,7 +290,8 @@ def LLVM_NoAliasScopeDeclOp
286290
class LLVM_LifetimeBaseOp<string opName> : LLVM_ZeroResultIntrOp<opName, [1],
287291
[DeclareOpInterfaceMethods<PromotableOpInterface>],
288292
/*requiresAccessGroup=*/0, /*requiresAliasAnalysis=*/0,
289-
/*immArgPositions=*/[0], /*immArgAttrNames=*/["size"]> {
293+
/*requiresOpBundles=*/0, /*immArgPositions=*/[0],
294+
/*immArgAttrNames=*/["size"]> {
290295
let arguments = (ins I64Attr:$size, LLVM_AnyPointer:$ptr);
291296
let assemblyFormat = "$size `,` $ptr attr-dict `:` qualified(type($ptr))";
292297
}
@@ -306,7 +311,8 @@ def LLVM_InvariantStartOp : LLVM_OneResultIntrOp<"invariant.start", [], [1],
306311
def LLVM_InvariantEndOp : LLVM_ZeroResultIntrOp<"invariant.end", [2],
307312
[DeclareOpInterfaceMethods<PromotableOpInterface>],
308313
/*requiresAccessGroup=*/0, /*requiresAliasAnalysis=*/0,
309-
/*immArgPositions=*/[1], /*immArgAttrNames=*/["size"]> {
314+
/*requiresOpBundles=*/0, /*immArgPositions=*/[1],
315+
/*immArgAttrNames=*/["size"]> {
310316
let arguments = (ins LLVM_DefaultPointer:$start,
311317
I64Attr:$size,
312318
LLVM_AnyPointer:$ptr);
@@ -368,7 +374,7 @@ class LLVM_ConstrainedIntr<string mnem, int numArgs,
368374
SmallVector<Value> mlirOperands;
369375
SmallVector<NamedAttribute> mlirAttrs;
370376
if (failed(moduleImport.convertIntrinsicArguments(
371-
llvmOperands.take_front( }] # numArgs # [{),
377+
llvmOperands.take_front( }] # numArgs # [{), {}, false,
372378
{}, {}, mlirOperands, mlirAttrs))) {
373379
return failure();
374380
}
@@ -429,7 +435,26 @@ def LLVM_USHLSat : LLVM_BinarySameArgsIntrOpI<"ushl.sat">;
429435
//
430436

431437
def LLVM_AssumeOp
432-
: LLVM_ZeroResultIntrOp<"assume", []>, Arguments<(ins I1:$cond)>;
438+
: LLVM_ZeroResultIntrOp<"assume", /*overloadedOperands=*/[], /*traits=*/[],
439+
/*requiresAccessGroup=*/0,
440+
/*requiresAliasAnalysis=*/0,
441+
/*requiresOpBundles=*/1> {
442+
dag args = (ins I1:$cond);
443+
let arguments = !con(args, opBundleArgs);
444+
445+
let assemblyFormat = [{
446+
$cond
447+
( custom<OpBundles>($op_bundle_operands, type($op_bundle_operands),
448+
$op_bundle_tags)^ )?
449+
`:` type($cond) attr-dict
450+
}];
451+
452+
let builders = [
453+
OpBuilder<(ins "Value":$cond)>
454+
];
455+
456+
let hasVerifier = 1;
457+
}
433458

434459
def LLVM_SSACopyOp : LLVM_OneResultIntrOp<"ssa.copy", [], [0],
435460
[Pure, SameOperandsAndResultType]> {
@@ -992,7 +1017,8 @@ def LLVM_DebugTrap : LLVM_ZeroResultIntrOp<"debugtrap">;
9921017
def LLVM_UBSanTrap : LLVM_ZeroResultIntrOp<"ubsantrap",
9931018
/*overloadedOperands=*/[], /*traits=*/[],
9941019
/*requiresAccessGroup=*/0, /*requiresAliasAnalysis=*/0,
995-
/*immArgPositions=*/[0], /*immArgAttrNames=*/["failureKind"]> {
1020+
/*requiresOpBundles=*/0, /*immArgPositions=*/[0],
1021+
/*immArgAttrNames=*/["failureKind"]> {
9961022
let arguments = (ins I8Attr:$failureKind);
9971023
}
9981024

mlir/include/mlir/Dialect/LLVMIR/LLVMOpBase.td

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ class LLVM_IntrOpBase<Dialect dialect, string opName, string enumName,
291291
list<int> overloadedResults, list<int> overloadedOperands,
292292
list<Trait> traits, int numResults,
293293
bit requiresAccessGroup = 0, bit requiresAliasAnalysis = 0,
294-
bit requiresFastmath = 0,
294+
bit requiresFastmath = 0, bit requiresOpBundles = 0,
295295
list<int> immArgPositions = [],
296296
list<string> immArgAttrNames = []>
297297
: LLVM_OpBase<dialect, opName, !listconcat(
@@ -313,6 +313,12 @@ class LLVM_IntrOpBase<Dialect dialect, string opName, string enumName,
313313
OptionalAttr<LLVM_AliasScopeArrayAttr>:$noalias_scopes,
314314
OptionalAttr<LLVM_TBAATagArrayAttr>:$tbaa),
315315
(ins )));
316+
dag opBundleArgs = !if(!gt(requiresOpBundles, 0),
317+
(ins VariadicOfVariadic<LLVM_Type,
318+
"op_bundle_sizes">:$op_bundle_operands,
319+
DenseI32ArrayAttr:$op_bundle_sizes,
320+
OptionalAttr<ArrayAttr>:$op_bundle_tags),
321+
(ins ));
316322
string llvmEnumName = enumName;
317323
string overloadedResultsCpp = "{" # !interleave(overloadedResults, ", ") # "}";
318324
string overloadedOperandsCpp = "{" # !interleave(overloadedOperands, ", ") # "}";
@@ -336,6 +342,8 @@ class LLVM_IntrOpBase<Dialect dialect, string opName, string enumName,
336342
SmallVector<NamedAttribute> mlirAttrs;
337343
if (failed(moduleImport.convertIntrinsicArguments(
338344
llvmOperands,
345+
llvmOpBundles,
346+
}] # !if(!gt(requiresOpBundles, 0), "true", "false") # [{,
339347
}] # immArgPositionsCpp # [{,
340348
}] # immArgAttrNamesCpp # [{,
341349
mlirOperands,
@@ -381,12 +389,14 @@ class LLVM_IntrOp<string mnem, list<int> overloadedResults,
381389
list<int> overloadedOperands, list<Trait> traits,
382390
int numResults, bit requiresAccessGroup = 0,
383391
bit requiresAliasAnalysis = 0, bit requiresFastmath = 0,
392+
bit requiresOpBundles = 0,
384393
list<int> immArgPositions = [],
385394
list<string> immArgAttrNames = []>
386395
: LLVM_IntrOpBase<LLVM_Dialect, "intr." # mnem, !subst(".", "_", mnem),
387396
overloadedResults, overloadedOperands, traits,
388397
numResults, requiresAccessGroup, requiresAliasAnalysis,
389-
requiresFastmath, immArgPositions, immArgAttrNames>;
398+
requiresFastmath, requiresOpBundles, immArgPositions,
399+
immArgAttrNames>;
390400

391401
// Base class for LLVM intrinsic operations returning no results. Places the
392402
// intrinsic into the LLVM dialect and prefixes its name with "intr.".
@@ -406,11 +416,13 @@ class LLVM_ZeroResultIntrOp<string mnem, list<int> overloadedOperands = [],
406416
list<Trait> traits = [],
407417
bit requiresAccessGroup = 0,
408418
bit requiresAliasAnalysis = 0,
419+
bit requiresOpBundles = 0,
409420
list<int> immArgPositions = [],
410421
list<string> immArgAttrNames = []>
411422
: LLVM_IntrOp<mnem, [], overloadedOperands, traits, /*numResults=*/0,
412423
requiresAccessGroup, requiresAliasAnalysis,
413-
/*requiresFastMath=*/0, immArgPositions, immArgAttrNames>;
424+
/*requiresFastMath=*/0, requiresOpBundles, immArgPositions,
425+
immArgAttrNames>;
414426

415427
// Base class for LLVM intrinsic operations returning one result. Places the
416428
// intrinsic into the LLVM dialect and prefixes its name with "intr.". This is
@@ -422,11 +434,12 @@ class LLVM_OneResultIntrOp<string mnem, list<int> overloadedResults = [],
422434
list<int> overloadedOperands = [],
423435
list<Trait> traits = [],
424436
bit requiresFastmath = 0,
425-
list<int> immArgPositions = [],
426-
list<string> immArgAttrNames = []>
437+
list<int> immArgPositions = [],
438+
list<string> immArgAttrNames = []>
427439
: LLVM_IntrOp<mnem, overloadedResults, overloadedOperands, traits, 1,
428440
/*requiresAccessGroup=*/0, /*requiresAliasAnalysis=*/0,
429-
requiresFastmath, immArgPositions, immArgAttrNames>;
441+
requiresFastmath, /*requiresOpBundles=*/0, immArgPositions,
442+
immArgAttrNames>;
430443

431444
def LLVM_OneResultOpBuilder :
432445
OpBuilder<(ins "Type":$resultType, "ValueRange":$operands,

mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -559,11 +559,7 @@ def LLVM_InvokeOp : LLVM_Op<"invoke", [
559559
VariadicOfVariadic<LLVM_Type,
560560
"op_bundle_sizes">:$op_bundle_operands,
561561
DenseI32ArrayAttr:$op_bundle_sizes,
562-
DefaultValuedProperty<
563-
ArrayProperty<StringProperty, "operand bundle tags">,
564-
"ArrayRef<std::string>{}",
565-
"SmallVector<std::string>{}"
566-
>:$op_bundle_tags);
562+
OptionalAttr<ArrayAttr>:$op_bundle_tags);
567563
let results = (outs Optional<LLVM_Type>:$result);
568564
let successors = (successor AnySuccessor:$normalDest,
569565
AnySuccessor:$unwindDest);
@@ -678,11 +674,7 @@ def LLVM_CallOp : LLVM_MemAccessOpBase<"call",
678674
VariadicOfVariadic<LLVM_Type,
679675
"op_bundle_sizes">:$op_bundle_operands,
680676
DenseI32ArrayAttr:$op_bundle_sizes,
681-
DefaultValuedProperty<
682-
ArrayProperty<StringProperty, "operand bundle tags">,
683-
"ArrayRef<std::string>{}",
684-
"SmallVector<std::string>{}"
685-
>:$op_bundle_tags);
677+
OptionalAttr<ArrayAttr>:$op_bundle_tags);
686678
// Append the aliasing related attributes defined in LLVM_MemAccessOpBase.
687679
let arguments = !con(args, aliasAttrs);
688680
let results = (outs Optional<LLVM_Type>:$result);
@@ -1930,11 +1922,7 @@ def LLVM_CallIntrinsicOp
19301922
VariadicOfVariadic<LLVM_Type,
19311923
"op_bundle_sizes">:$op_bundle_operands,
19321924
DenseI32ArrayAttr:$op_bundle_sizes,
1933-
DefaultValuedProperty<
1934-
ArrayProperty<StringProperty, "operand bundle tags">,
1935-
"ArrayRef<std::string>{}",
1936-
"SmallVector<std::string>{}"
1937-
>:$op_bundle_tags);
1925+
OptionalAttr<ArrayAttr>:$op_bundle_tags);
19381926
let results = (outs Optional<LLVM_Type>:$results);
19391927
let llvmBuilder = [{
19401928
return convertCallLLVMIntrinsicOp(op, builder, moduleTranslation);

mlir/include/mlir/Dialect/LLVMIR/ROCDLOps.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ class ROCDL_IntrOp<string mnemonic, list<int> overloadedResults,
9898
LLVM_IntrOpBase<ROCDL_Dialect, mnemonic,
9999
"amdgcn_" # !subst(".", "_", mnemonic), overloadedResults,
100100
overloadedOperands, traits, numResults, requiresAccessGroup,
101-
requiresAliasAnalysis, 0, immArgPositions, immArgAttrNames>;
101+
requiresAliasAnalysis, 0, 0, immArgPositions, immArgAttrNames>;
102102

103103
//===----------------------------------------------------------------------===//
104104
// ROCDL special register op definitions

mlir/include/mlir/Target/LLVMIR/ModuleImport.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,8 @@ class ModuleImport {
243243
/// corresponding MLIR attribute names.
244244
LogicalResult
245245
convertIntrinsicArguments(ArrayRef<llvm::Value *> values,
246+
ArrayRef<llvm::OperandBundleUse> opBundles,
247+
bool requiresOpBundles,
246248
ArrayRef<unsigned> immArgPositions,
247249
ArrayRef<StringLiteral> immArgAttrNames,
248250
SmallVectorImpl<Value> &valuesOut,

0 commit comments

Comments
 (0)