@@ -351,6 +351,7 @@ def LLVM_LoadOp : LLVM_MemAccessOpBase<"load",
351351 UnitAttr:$volatile_,
352352 UnitAttr:$nontemporal,
353353 UnitAttr:$invariant,
354+ UnitAttr:$invariantGroup,
354355 DefaultValuedAttr<
355356 AtomicOrdering, "AtomicOrdering::not_atomic">:$ordering,
356357 OptionalAttr<StrAttr>:$syncscope);
@@ -386,6 +387,7 @@ def LLVM_LoadOp : LLVM_MemAccessOpBase<"load",
386387 (`volatile` $volatile_^)? $addr
387388 (`atomic` (`syncscope` `(` $syncscope^ `)`)? $ordering^)?
388389 (`invariant` $invariant^)?
390+ (`invariant_group` $invariantGroup^)?
389391 attr-dict `:` qualified(type($addr)) `->` type($res)
390392 }];
391393 string llvmBuilder = [{
@@ -395,6 +397,10 @@ def LLVM_LoadOp : LLVM_MemAccessOpBase<"load",
395397 llvm::MDNode *metadata = llvm::MDNode::get(inst->getContext(), std::nullopt);
396398 inst->setMetadata(llvm::LLVMContext::MD_invariant_load, metadata);
397399 }
400+ if ($invariantGroup) {
401+ llvm::MDNode *metadata = llvm::MDNode::get(inst->getContext(), std::nullopt);
402+ inst->setMetadata(llvm::LLVMContext::MD_invariant_group, metadata);
403+ }
398404 }] # setOrderingCode
399405 # setSyncScopeCode
400406 # setAlignmentCode
@@ -408,13 +414,15 @@ def LLVM_LoadOp : LLVM_MemAccessOpBase<"load",
408414 alignment, loadInst->isVolatile(),
409415 loadInst->hasMetadata(llvm::LLVMContext::MD_nontemporal),
410416 loadInst->hasMetadata(llvm::LLVMContext::MD_invariant_load),
417+ loadInst->hasMetadata(llvm::LLVMContext::MD_invariant_group),
411418 convertAtomicOrderingFromLLVM(loadInst->getOrdering()),
412419 getLLVMSyncScope(loadInst));
413420 }];
414421 let builders = [
415422 OpBuilder<(ins "Type":$type, "Value":$addr,
416423 CArg<"unsigned", "0">:$alignment, CArg<"bool", "false">:$isVolatile,
417424 CArg<"bool", "false">:$isNonTemporal, CArg<"bool", "false">:$isInvariant,
425+ CArg<"bool", "false">:$isInvariantGroup,
418426 CArg<"AtomicOrdering", "AtomicOrdering::not_atomic">:$ordering,
419427 CArg<"StringRef", "StringRef()">:$syncscope)>
420428 ];
@@ -431,6 +439,7 @@ def LLVM_StoreOp : LLVM_MemAccessOpBase<"store",
431439 OptionalAttr<I64Attr>:$alignment,
432440 UnitAttr:$volatile_,
433441 UnitAttr:$nontemporal,
442+ UnitAttr:$invariantGroup,
434443 DefaultValuedAttr<
435444 AtomicOrdering, "AtomicOrdering::not_atomic">:$ordering,
436445 OptionalAttr<StrAttr>:$syncscope);
@@ -464,10 +473,15 @@ def LLVM_StoreOp : LLVM_MemAccessOpBase<"store",
464473 let assemblyFormat = [{
465474 (`volatile` $volatile_^)? $value `,` $addr
466475 (`atomic` (`syncscope` `(` $syncscope^ `)`)? $ordering^)?
476+ (`invariant_group` $invariantGroup^)?
467477 attr-dict `:` type($value) `,` qualified(type($addr))
468478 }];
469479 string llvmBuilder = [{
470480 auto *inst = builder.CreateStore($value, $addr, $volatile_);
481+ if ($invariantGroup) {
482+ llvm::MDNode *metadata = llvm::MDNode::get(inst->getContext(), std::nullopt);
483+ inst->setMetadata(llvm::LLVMContext::MD_invariant_group, metadata);
484+ }
471485 }] # setOrderingCode
472486 # setSyncScopeCode
473487 # setAlignmentCode
@@ -480,13 +494,15 @@ def LLVM_StoreOp : LLVM_MemAccessOpBase<"store",
480494 $_op = $_builder.create<LLVM::StoreOp>($_location, $value, $addr,
481495 alignment, storeInst->isVolatile(),
482496 storeInst->hasMetadata(llvm::LLVMContext::MD_nontemporal),
497+ storeInst->hasMetadata(llvm::LLVMContext::MD_invariant_group),
483498 convertAtomicOrderingFromLLVM(storeInst->getOrdering()),
484499 getLLVMSyncScope(storeInst));
485500 }];
486501 let builders = [
487502 OpBuilder<(ins "Value":$value, "Value":$addr,
488503 CArg<"unsigned", "0">:$alignment, CArg<"bool", "false">:$isVolatile,
489504 CArg<"bool", "false">:$isNonTemporal,
505+ CArg<"bool", "false">:$isInvariantGroup,
490506 CArg<"AtomicOrdering", "AtomicOrdering::not_atomic">:$ordering,
491507 CArg<"StringRef", "StringRef()">:$syncscope)>
492508 ];
0 commit comments