@@ -364,7 +364,8 @@ def LLVM_LoadOp : LLVM_MemAccessOpBase<"load",
364364 [DeclareOpInterfaceMethods<DestructurableAccessorOpInterface>,
365365 DeclareOpInterfaceMethods<MemoryEffectsOpInterface>,
366366 DeclareOpInterfaceMethods<PromotableMemOpInterface>,
367- DeclareOpInterfaceMethods<SafeMemorySlotAccessOpInterface>]> {
367+ DeclareOpInterfaceMethods<SafeMemorySlotAccessOpInterface>,
368+ DeclareOpInterfaceMethods<DereferenceableOpInterface>]> {
368369 dag args = (ins LLVM_AnyPointer:$addr,
369370 OptionalAttr<I64Attr>:$alignment,
370371 UnitAttr:$volatile_,
@@ -373,7 +374,8 @@ def LLVM_LoadOp : LLVM_MemAccessOpBase<"load",
373374 UnitAttr:$invariantGroup,
374375 DefaultValuedAttr<
375376 AtomicOrdering, "AtomicOrdering::not_atomic">:$ordering,
376- OptionalAttr<StrAttr>:$syncscope);
377+ OptionalAttr<StrAttr>:$syncscope,
378+ OptionalAttr<LLVM_DereferenceableAttr>:$dereferenceable);
377379 // Append the aliasing related attributes defined in LLVM_MemAccessOpBase.
378380 let arguments = !con(args, aliasAttrs);
379381 let results = (outs LLVM_LoadableType:$res);
@@ -407,6 +409,7 @@ def LLVM_LoadOp : LLVM_MemAccessOpBase<"load",
407409 (`atomic` (`syncscope` `(` $syncscope^ `)`)? $ordering^)?
408410 (`invariant` $invariant^)?
409411 (`invariant_group` $invariantGroup^)?
412+ (`dereferenceable` `` $dereferenceable^)?
410413 attr-dict `:` qualified(type($addr)) `->` type($res)
411414 }];
412415 string llvmBuilder = [{
@@ -416,6 +419,8 @@ def LLVM_LoadOp : LLVM_MemAccessOpBase<"load",
416419 llvm::MDNode *metadata = llvm::MDNode::get(inst->getContext(), std::nullopt);
417420 inst->setMetadata(llvm::LLVMContext::MD_invariant_load, metadata);
418421 }
422+ if ($dereferenceable)
423+ moduleTranslation.setDereferenceableMetadata(op, inst);
419424 }] # setOrderingCode
420425 # setSyncScopeCode
421426 # setAlignmentCode
@@ -571,6 +576,29 @@ class LLVM_CastOpWithOverflowFlag<string mnemonic, string instName, Type type,
571576 }];
572577}
573578
579+ class LLVM_DereferenceableCastOp<string mnemonic, string instName, Type type,
580+ Type resultType, list<Trait> traits = []> :
581+ LLVM_Op<mnemonic, !listconcat([Pure], [DeclareOpInterfaceMethods<DereferenceableOpInterface>], traits)> {
582+ let arguments = (ins type:$arg, OptionalAttr<LLVM_DereferenceableAttr>:$dereferenceable);
583+ let results = (outs resultType:$res);
584+ let builders = [LLVM_OneResultOpBuilder];
585+ let assemblyFormat = "$arg (`dereferenceable` `` $dereferenceable^)? attr-dict `:` type($arg) `to` type($res)";
586+ string llvmInstName = instName;
587+ string llvmBuilder = [{
588+ auto *val = builder.Create}] # instName # [{($arg, $_resultType);
589+ $res = val;
590+ if ($dereferenceable) {
591+ llvm::Instruction *inst = dyn_cast<llvm::Instruction>(val);
592+ moduleTranslation.setDereferenceableMetadata(op, inst);
593+ }
594+ }];
595+ string mlirBuilder = [{
596+ auto op = $_builder.create<$_qualCppClassName>(
597+ $_location, $_resultType, $arg);
598+ $res = op;
599+ }];
600+ }
601+
574602def LLVM_BitcastOp : LLVM_CastOp<"bitcast", "BitCast", LLVM_AnyNonAggregate,
575603 LLVM_AnyNonAggregate, [DeclareOpInterfaceMethods<PromotableOpInterface>]> {
576604 let hasFolder = 1;
@@ -583,7 +611,7 @@ def LLVM_AddrSpaceCastOp : LLVM_CastOp<"addrspacecast", "AddrSpaceCast",
583611 DeclareOpInterfaceMethods<ViewLikeOpInterface>]> {
584612 let hasFolder = 1;
585613}
586- def LLVM_IntToPtrOp : LLVM_CastOp <"inttoptr", "IntToPtr",
614+ def LLVM_IntToPtrOp : LLVM_DereferenceableCastOp <"inttoptr", "IntToPtr",
587615 LLVM_ScalarOrVectorOf<AnySignlessInteger>,
588616 LLVM_ScalarOrVectorOf<LLVM_AnyPointer>>;
589617def LLVM_PtrToIntOp : LLVM_CastOp<"ptrtoint", "PtrToInt",
0 commit comments