llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-mlir-llvm

@llvm/pr-subscribers-mlir

Author: Tobias Gysi (gysit)

<details>
<summary>Changes</summary>

llvm.intr.masked.load, masked.store, masked.gather and masked.scatter 
implemented neither AccessGroupOpInterface nor AliasAnalysisOpInterface, so 
they could not carry access_groups, alias_scopes, noalias_scopes or tbaa. 
Importing LLVM IR that attached such metadata to one of them silently dropped 
it, while llvm.memcpy in the same module preserved it.

Also widen alignment from I32Attr to I64Attr, matching the rest of the LLVM 
dialect and LLVM proper, and make it optional. LangRef gives the default 
alignment of these four intrinsics as the ABI alignment of the type, exactly as 
for llvm.load and llvm.store, so an absent align parameter attribute now 
imports as an absent alignment attribute instead of being materialised as align 
1, and an absent alignment attribute exports without an align parameter 
attribute. This changes the textual IR, as alignment = 4 : i32 becomes 
alignment = 4 : i64. Downstream updates should rewrite only lines that mention 
a masked intrinsic rather than blanket-substituting i32 with i64; other i32 
spellings must stay, including llvm.intr.matrix.*'s rows and columns attributes 
and i32 vector and element types on the intrinsics themselves.

---

Patch is 77.39 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/221879.diff


17 Files Affected:

- (modified) clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp (+1-3) 
- (modified) mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td (+167-47) 
- (modified) mlir/include/mlir/Dialect/LLVMIR/LLVMOpBase.td (+3-1) 
- (modified) mlir/lib/Conversion/VectorToLLVM/ConvertVectorToLLVM.cpp (+2-3) 
- (modified) mlir/lib/Dialect/LLVMIR/IR/LLVMInterfaces.cpp (+16) 
- (modified) mlir/test/Conversion/VectorToLLVM/use-vector-alignment.mlir 
(+16-16) 
- (modified) mlir/test/Conversion/VectorToLLVM/vector-to-llvm-interface.mlir 
(+26-26) 
- (modified) mlir/test/Conversion/VectorToLLVM/vector-to-llvm.mlir (+4-4) 
- (modified) mlir/test/Conversion/VectorToLLVM/vector-xfer-to-llvm.mlir (+8-8) 
- (modified) mlir/test/Dialect/LLVMIR/opaque-ptr.mlir (+2-2) 
- (modified) mlir/test/Dialect/LLVMIR/roundtrip.mlir (+23) 
- (modified) mlir/test/Target/LLVMIR/Import/intrinsic.ll (+35-23) 
- (added) mlir/test/Target/LLVMIR/Import/masked-intrinsic-metadata.ll (+64) 
- (modified) mlir/test/Target/LLVMIR/llvmir-intrinsics.mlir (+20-8) 
- (modified) mlir/test/Target/LLVMIR/llvmir-invalid.mlir (+6-6) 
- (added) mlir/test/Target/LLVMIR/masked-intrinsic-metadata.mlir (+73) 
- (modified) mlir/test/Target/LLVMIR/opaque-ptr.mlir (+2-2) 


``````````diff
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp 
b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 31e01c770c55b..69b73b6fa516e 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -2373,11 +2373,9 @@ 
cir::direct::CIRToLLVMVecMaskedLoadOpLowering::matchAndRewrite(
   unsigned alignment =
       (unsigned)opAlign.value_or(dataLayout.getTypeABIAlignment(llvmResTy));
 
-  mlir::IntegerAttr alignAttr = rewriter.getI32IntegerAttr(alignment);
-
   auto newLoad = mlir::LLVM::MaskedLoadOp::create(
       rewriter, op.getLoc(), llvmResTy, adaptor.getAddr(), adaptor.getMask(),
-      adaptor.getPassThru(), alignAttr);
+      adaptor.getPassThru(), alignment);
 
   rewriter.replaceOp(op, newLoad.getResult());
   return mlir::success();
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td 
b/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td
index 5eb58b16a5216..8495a7d414f19 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td
@@ -17,6 +17,7 @@ class LLVM_UnaryIntrOpBase<string func, Type element,
                            list<Trait> traits = [], bit requiresFastmath = 0> :
     LLVM_OneResultIntrOp<func, [], [0],
            !listconcat([Pure, SameOperandsAndResultType], traits),
+           /*requiresAccessGroup=*/0, /*requiresAliasAnalysis=*/0,
            requiresFastmath> {
   dag commonArgs = (ins LLVM_ScalarOrVectorOf<element>:$in);
   let assemblyFormat = "`(` operands `)` attr-dict `:` "
@@ -39,6 +40,7 @@ class LLVM_BinarySameArgsIntrOpBase<string func, Type element,
               list<Trait> traits = [], bit requiresFastmath = 0> :
     LLVM_OneResultIntrOp<func, [], [0],
            !listconcat([Pure, SameOperandsAndResultType], traits),
+           /*requiresAccessGroup=*/0, /*requiresAliasAnalysis=*/0,
            requiresFastmath> {
   dag commonArgs = (ins LLVM_ScalarOrVectorOf<element>:$a,
                         LLVM_ScalarOrVectorOf<element>:$b);
@@ -63,6 +65,7 @@ class LLVM_TernarySameArgsIntrOpBase<string func, Type 
element,
               list<Trait> traits = [], bit requiresFastmath = 0> :
     LLVM_OneResultIntrOp<func, [], [0],
            !listconcat([Pure, SameOperandsAndResultType], traits),
+           /*requiresAccessGroup=*/0, /*requiresAliasAnalysis=*/0,
            requiresFastmath> {
   dag commonArgs = (ins LLVM_ScalarOrVectorOf<element>:$a,
                        LLVM_ScalarOrVectorOf<element>:$b,
@@ -87,6 +90,7 @@ class LLVM_TernarySameArgsIntrOpF<string func, list<Trait> 
traits = []> :
 class LLVM_CountZerosIntrOp<string func, list<Trait> traits = []> :
     LLVM_OneResultIntrOp<func, [], [0],
            !listconcat([Pure, SameOperandsAndResultType], traits),
+            /*requiresAccessGroup=*/0, /*requiresAliasAnalysis=*/0,
             /*requiresFastmath=*/0, /*requiresArgAndResultAttrs=*/0,
             /*immArgPositions=*/[1], /*immArgAttrNames=*/["is_zero_poison"]> {
   let arguments = (ins LLVM_ScalarOrVectorOf<AnySignlessInteger>:$in,
@@ -94,6 +98,7 @@ class LLVM_CountZerosIntrOp<string func, list<Trait> traits = 
[]> :
 }
 
 def LLVM_AbsOp : LLVM_OneResultIntrOp<"abs", [], [0], [Pure],
+    /*requiresAccessGroup=*/0, /*requiresAliasAnalysis=*/0,
     /*requiresFastmath=*/0, /*requiresArgAndResultAttrs=*/0,
     /*immArgPositions=*/[1], /*immArgAttrNames=*/["is_int_min_poison"]> {
   let arguments = (ins LLVM_ScalarOrVectorOf<AnySignlessInteger>:$in,
@@ -108,6 +113,7 @@ def LLVM_ArithmeticFenceOp
 }
 
 def LLVM_IsFPClass : LLVM_OneResultIntrOp<"is.fpclass", [], [0], [Pure],
+  /*requiresAccessGroup=*/0, /*requiresAliasAnalysis=*/0,
   /*requiresFastmath=*/0, /*requiresArgAndResultAttrs=*/0,
   /*immArgPositions=*/[1], /*immArgAttrNames=*/["bit"]> {
   let arguments = (ins LLVM_ScalarOrVectorOf<LLVM_AnyFloat>:$in, I32Attr:$bit);
@@ -115,7 +121,8 @@ def LLVM_IsFPClass : LLVM_OneResultIntrOp<"is.fpclass", [], 
[0], [Pure],
 
 class LLVM_PowFI<string func> :
     LLVM_OneResultIntrOp<func, [], [0,1],
-        [Pure], /*requiresFastmath=*/1> {
+        [Pure], /*requiresAccessGroup=*/0, /*requiresAliasAnalysis=*/0,
+        /*requiresFastmath=*/1> {
     let arguments =
         (ins LLVM_ScalarOrVectorOf<LLVM_AnyFloat>:$val,
             AnySignlessInteger:$power,
@@ -388,6 +395,7 @@ def LLVM_LifetimeEndOp : 
LLVM_LifetimeBaseOp<"lifetime.end">;
 
 def LLVM_InvariantStartOp : LLVM_OneResultIntrOp<"invariant.start", [], [1],
     [DeclareOpInterfaceMethods<PromotableOpInterface>],
+    /*requiresAccessGroup=*/0, /*requiresAliasAnalysis=*/0,
     /*requiresFastmath=*/0, /*requiresArgAndResultAttrs=*/0,
     /*immArgPositions=*/[0], /*immArgAttrNames=*/["size"]> {
   let arguments = (ins I64Attr:$size, LLVM_AnyPointer:$ptr);
@@ -441,6 +449,8 @@ class LLVM_ConstrainedIntr<string mnem, int numArgs,
                                !gt(hasRoundingMode, 0) : 
[DeclareOpInterfaceMethods<RoundingModeOpInterface>],
                                true : [])
                            # extraTraits,
+                           /*requiresAccessGroup=*/0,
+                           /*requiresAliasAnalysis=*/0,
                            /*requiresFastmath=*/1,
                            /*requiresArgAndResultAttrs=*/0,
                            /*immArgPositions=*/[],
@@ -589,6 +599,7 @@ class LLVM_ConstrainedFCmpIntrBase<string mnem>
                          "operands", "arg_0", "res",
                          "::mlir::LLVM::getI1SameShape($_self)">,
           DeclareOpInterfaceMethods<FPExceptionBehaviorOpInterface>],
+        /*requiresAccessGroup=*/0, /*requiresAliasAnalysis=*/0,
         /*requiresFastmath=*/1> {
   let arguments = (ins FCmpPredicate:$predicate,
                        LLVM_Type:$arg_0,
@@ -880,6 +891,7 @@ def LLVM_ExpectOp
 def LLVM_ExpectWithProbabilityOp
   : LLVM_OneResultIntrOp<"expect.with.probability", [], [0],
                          [Pure, AllTypesMatch<["val", "expected", "res"]>],
+                         /*requiresAccessGroup=*/0, 
/*requiresAliasAnalysis=*/0,
                          /*requiresFastmath=*/0, 
/*requiresArgAndResultAttrs=*/0,
                          /*immArgPositions=*/[2], 
/*immArgAttrNames=*/["prob"]> {
   let arguments = (ins AnySignlessInteger:$val,
@@ -1184,6 +1196,7 @@ def LLVM_StackRestoreOp : 
LLVM_ZeroResultIntrOp<"stackrestore", [0]> {
 class LLVM_VecReductionBase<string mnem, Type element, bit requiresFastmath=0>
     : LLVM_OneResultIntrOp<"vector.reduce." # mnem, [], [0],
                            [Pure, SameOperandsAndResultElementType],
+                           /*requiresAccessGroup=*/0, 
/*requiresAliasAnalysis=*/0,
                            requiresFastmath> {
       dag commonArgs = (ins LLVM_VectorOf<element>:$in);
 }
@@ -1210,6 +1223,8 @@ class LLVM_VecReductionAccBase<string mnem, Type element>
                            /*overloadedResults=*/[],
                            /*overloadedOperands=*/[1],
                            /*traits=*/[Pure, SameOperandsAndResultElementType],
+                           /*requiresAccessGroup=*/0,
+                           /*requiresAliasAnalysis=*/0,
                            /*requiresFastmath=*/1>,
       Arguments<(ins element:$start_value,
                      LLVM_VectorOf<element>:$input,
@@ -1363,104 +1378,206 @@ def LLVM_GetActiveLaneMaskOp
 }
 
 /// Create a call to Masked Load intrinsic.
-def LLVM_MaskedLoadOp : LLVM_OneResultIntrOp<"masked.load"> {
-  let arguments = (ins LLVM_AnyPointer:$data, LLVM_VectorOf<I1>:$mask,
-                   Optional<LLVM_AnyVector>:$pass_thru, I32Attr:$alignment,
-                   UnitAttr:$nontemporal);
+def LLVM_MaskedLoadOp
+    : LLVM_OneResultIntrOp<"masked.load", /*overloadedResults=*/[],
+      /*overloadedOperands=*/[], /*traits=*/[],
+      /*requiresAccessGroup=*/1, /*requiresAliasAnalysis=*/1> {
+  dag args = (ins LLVM_AnyPointer:$data, LLVM_VectorOf<I1>:$mask,
+                  Optional<LLVM_AnyVector>:$pass_thru,
+                  OptionalAttr<I64Attr>:$alignment, UnitAttr:$nontemporal);
+  let arguments = !con(args, baseArgs);
   let results = (outs LLVM_AnyVector:$res);
+  let builders = [
+    OpBuilder<(ins "Type":$res, "Value":$data, "Value":$mask,
+                   "Value":$pass_thru, "uint64_t":$alignment,
+                   CArg<"bool", "false">:$nontemporal), [{
+      build($_builder, $_state, res, data, mask, pass_thru,
+            $_builder.getI64IntegerAttr(alignment),
+            nontemporal ? $_builder.getUnitAttr() : nullptr,
+            /*access_groups=*/nullptr, /*alias_scopes=*/nullptr,
+            /*noalias_scopes=*/nullptr, /*tbaa=*/nullptr);
+    }]>
+  ];
   let assemblyFormat =
     "operands attr-dict `:` functional-type(operands, results)";
 
   string llvmBuilder = [{
+    // An absent alignment attribute means the ABI alignment of the type, which
+    // LLVM spells as an absent align parameter attribute. The IRBuilder helper
+    // always attaches one, so remove it again in that case.
+    llvm::Align alignment =
+        $alignment ? llvm::Align(*$alignment) : llvm::Align(1);
     auto *inst = $pass_thru ? builder.CreateMaskedLoad(
-        $_resultType, $data, llvm::Align($alignment), $mask, $pass_thru) :
+        $_resultType, $data, alignment, $mask, $pass_thru) :
       builder.CreateMaskedLoad(
-        $_resultType, $data, llvm::Align($alignment), $mask);
+        $_resultType, $data, alignment, $mask);
+    if (!$alignment)
+      inst->removeParamAttr(0, llvm::Attribute::Alignment);
     $res = inst;
-  }] #setNonTemporalMetadataCode;
+  }] # setNonTemporalMetadataCode
+     # setAccessGroupsMetadataCode
+     # setAliasAnalysisMetadataCode;
   string mlirBuilder = [{
     auto *intrinInst = dyn_cast<llvm::IntrinsicInst>(inst);
     bool nontemporal = 
intrinInst->hasMetadata(llvm::LLVMContext::MD_nontemporal);
-    llvm::Align alignment = intrinInst->getParamAlign(0).valueOrOne();
+    llvm::MaybeAlign alignment = intrinInst->getParamAlign(0);
     $res = LLVM::MaskedLoadOp::create($_builder, $_location,
       $_resultType, $data, $mask, $pass_thru,
-      $_builder.getI32IntegerAttr(alignment.value()),
-      nontemporal ? $_builder.getUnitAttr() : nullptr);
+      alignment ? $_builder.getI64IntegerAttr(alignment->value())
+                : ::mlir::IntegerAttr(),
+      nontemporal ? $_builder.getUnitAttr() : nullptr,
+      /*access_groups=*/nullptr, /*alias_scopes=*/nullptr,
+      /*noalias_scopes=*/nullptr, /*tbaa=*/nullptr);
   }];
-  list<int> llvmArgIndices = [0, 1, 2, -1, -1];
+  list<int> llvmArgIndices = [0, 1, 2, -1, -1, -1, -1, -1, -1];
 }
 
 /// Create a call to Masked Store intrinsic.
-def LLVM_MaskedStoreOp : LLVM_ZeroResultIntrOp<"masked.store"> {
-  let arguments = (ins LLVM_AnyVector:$value, LLVM_AnyPointer:$data,
-                   LLVM_VectorOf<I1>:$mask, I32Attr:$alignment,
-                   UnitAttr:$nontemporal);
-  let builders = [LLVM_VoidResultTypeOpBuilder, LLVM_ZeroResultOpBuilder];
+def LLVM_MaskedStoreOp
+    : LLVM_ZeroResultIntrOp<"masked.store", /*overloadedOperands=*/[],
+      /*traits=*/[], /*requiresAccessGroup=*/1, /*requiresAliasAnalysis=*/1> {
+  dag args = (ins LLVM_AnyVector:$value, LLVM_AnyPointer:$data,
+                  LLVM_VectorOf<I1>:$mask, OptionalAttr<I64Attr>:$alignment,
+                  UnitAttr:$nontemporal);
+  let arguments = !con(args, baseArgs);
+  let builders = [
+    LLVM_VoidResultTypeOpBuilder, LLVM_ZeroResultOpBuilder,
+    OpBuilder<(ins "Value":$value, "Value":$data, "Value":$mask,
+                   "uint64_t":$alignment,
+                   CArg<"bool", "false">:$nontemporal), [{
+      build($_builder, $_state, value, data, mask,
+            $_builder.getI64IntegerAttr(alignment),
+            nontemporal ? $_builder.getUnitAttr() : nullptr,
+            /*access_groups=*/nullptr, /*alias_scopes=*/nullptr,
+            /*noalias_scopes=*/nullptr, /*tbaa=*/nullptr);
+    }]>
+  ];
   let assemblyFormat = "$value `,` $data `,` $mask attr-dict `:` "
     "type($value) `,` type($mask) `into` qualified(type($data))";
 
   string llvmBuilder = [{
-    auto *inst = builder.CreateMaskedStore(
-      $value, $data, llvm::Align($alignment), $mask);
-  }] #setNonTemporalMetadataCode;
+    // An absent alignment attribute means the ABI alignment of the type, which
+    // LLVM spells as an absent align parameter attribute. The IRBuilder helper
+    // always attaches one, so remove it again in that case.
+    llvm::Align alignment =
+        $alignment ? llvm::Align(*$alignment) : llvm::Align(1);
+    auto *inst = builder.CreateMaskedStore($value, $data, alignment, $mask);
+    if (!$alignment)
+      inst->removeParamAttr(1, llvm::Attribute::Alignment);
+  }] # setNonTemporalMetadataCode
+     # setAccessGroupsMetadataCode
+     # setAliasAnalysisMetadataCode;
   string mlirBuilder = [{
     auto *intrinInst = dyn_cast<llvm::IntrinsicInst>(inst);
-    llvm::Align alignment = intrinInst->getParamAlign(1).valueOrOne();
+    llvm::MaybeAlign alignment = intrinInst->getParamAlign(1);
     bool nontemporal = 
intrinInst->hasMetadata(llvm::LLVMContext::MD_nontemporal);
     $_op = LLVM::MaskedStoreOp::create($_builder, $_location,
-      $value, $data, $mask, $_builder.getI32IntegerAttr(alignment.value()),
-      nontemporal ? $_builder.getUnitAttr() : nullptr);
+      $value, $data, $mask,
+      alignment ? $_builder.getI64IntegerAttr(alignment->value())
+                : ::mlir::IntegerAttr(),
+      nontemporal ? $_builder.getUnitAttr() : nullptr,
+      /*access_groups=*/nullptr, /*alias_scopes=*/nullptr,
+      /*noalias_scopes=*/nullptr, /*tbaa=*/nullptr);
   }];
-  list<int> llvmArgIndices = [0, 1, 2, -1, -1];
+  list<int> llvmArgIndices = [0, 1, 2, -1, -1, -1, -1, -1, -1];
 }
 
 /// Create a call to Masked Gather intrinsic.
-def LLVM_masked_gather : LLVM_OneResultIntrOp<"masked.gather"> {
-  let arguments = (ins LLVM_VectorOf<LLVM_AnyPointer>:$ptrs,
-                   LLVM_VectorOf<I1>:$mask, 
Variadic<LLVM_AnyVector>:$pass_thru,
-                   I32Attr:$alignment);
+def LLVM_masked_gather
+    : LLVM_OneResultIntrOp<"masked.gather", /*overloadedResults=*/[],
+      /*overloadedOperands=*/[], /*traits=*/[],
+      /*requiresAccessGroup=*/1, /*requiresAliasAnalysis=*/1> {
+  dag args = (ins LLVM_VectorOf<LLVM_AnyPointer>:$ptrs,
+                  LLVM_VectorOf<I1>:$mask, Variadic<LLVM_AnyVector>:$pass_thru,
+                  OptionalAttr<I64Attr>:$alignment);
+  let arguments = !con(args, baseArgs);
   let results = (outs LLVM_AnyVector:$res);
-  let builders = [LLVM_OneResultOpBuilder];
+  let builders = [
+    LLVM_OneResultOpBuilder,
+    OpBuilder<(ins "Type":$res, "Value":$ptrs, "Value":$mask,
+                   "ValueRange":$pass_thru, "uint64_t":$alignment), [{
+      build($_builder, $_state, res, ptrs, mask, pass_thru,
+            $_builder.getI64IntegerAttr(alignment),
+            /*access_groups=*/nullptr, /*alias_scopes=*/nullptr,
+            /*noalias_scopes=*/nullptr, /*tbaa=*/nullptr);
+    }]>
+  ];
   let assemblyFormat =
     "operands attr-dict `:` functional-type(operands, results)";
 
   string llvmBuilder = [{
-    $res = $pass_thru.empty() ? builder.CreateMaskedGather(
-        $_resultType, $ptrs, llvm::Align($alignment), $mask) :
+    // An absent alignment attribute means the ABI alignment of the type, which
+    // LLVM spells as an absent align parameter attribute. The IRBuilder helper
+    // always attaches one, so remove it again in that case.
+    llvm::Align alignment =
+        $alignment ? llvm::Align(*$alignment) : llvm::Align(1);
+    auto *inst = $pass_thru.empty() ? builder.CreateMaskedGather(
+        $_resultType, $ptrs, alignment, $mask) :
       builder.CreateMaskedGather(
-        $_resultType, $ptrs, llvm::Align($alignment), $mask, $pass_thru[0]);
-  }];
+        $_resultType, $ptrs, alignment, $mask, $pass_thru[0]);
+    if (!$alignment)
+      inst->removeParamAttr(0, llvm::Attribute::Alignment);
+    $res = inst;
+  }] # setAccessGroupsMetadataCode
+     # setAliasAnalysisMetadataCode;
   string mlirBuilder = [{
     auto *intrinInst = dyn_cast<llvm::IntrinsicInst>(inst);
-    llvm::Align alignment = intrinInst->getParamAlign(0).valueOrOne();
+    llvm::MaybeAlign alignment = intrinInst->getParamAlign(0);
     $res = LLVM::masked_gather::create($_builder, $_location,
       $_resultType, $ptrs, $mask, $pass_thru,
-      $_builder.getI32IntegerAttr(alignment.value()));
+      alignment ? $_builder.getI64IntegerAttr(alignment->value())
+                : ::mlir::IntegerAttr(),
+      /*access_groups=*/nullptr, /*alias_scopes=*/nullptr,
+      /*noalias_scopes=*/nullptr, /*tbaa=*/nullptr);
   }];
-  list<int> llvmArgIndices = [0, 1, 2, -1];
+  list<int> llvmArgIndices = [0, 1, 2, -1, -1, -1, -1, -1];
 
   let hasVerifier = 1;
 }
 
 /// Create a call to Masked Scatter intrinsic.
-def LLVM_masked_scatter : LLVM_ZeroResultIntrOp<"masked.scatter"> {
-  let arguments = (ins LLVM_AnyVector:$value, 
LLVM_VectorOf<LLVM_AnyPointer>:$ptrs,
-                   LLVM_VectorOf<I1>:$mask, I32Attr:$alignment);
-  let builders = [LLVM_VoidResultTypeOpBuilder, LLVM_ZeroResultOpBuilder];
+def LLVM_masked_scatter
+    : LLVM_ZeroResultIntrOp<"masked.scatter", /*overloadedOperands=*/[],
+      /*traits=*/[], /*requiresAccessGroup=*/1, /*requiresAliasAnalysis=*/1> {
+  dag args = (ins LLVM_AnyVector:$value,
+                  LLVM_VectorOf<LLVM_AnyPointer>:$ptrs,
+                  LLVM_VectorOf<I1>:$mask, OptionalAttr<I64Attr>:$alignment);
+  let arguments = !con(args, baseArgs);
+  let builders = [
+    LLVM_VoidResultTypeOpBuilder, LLVM_ZeroResultOpBuilder,
+    OpBuilder<(ins "Value":$value, "Value":$ptrs, "Value":$mask,
+                   "uint64_t":$alignment), [{
+      build($_builder, $_state, value, ptrs, mask,
+            $_builder.getI64IntegerAttr(alignment),
+            /*access_groups=*/nullptr, /*alias_scopes=*/nullptr,
+            /*noalias_scopes=*/nullptr, /*tbaa=*/nullptr);
+    }]>
+  ];
   let assemblyFormat = "$value `,` $ptrs `,` $mask attr-dict `:` "
     "type($value) `,` type($mask) `into` type($ptrs)";
 
   string llvmBuilder = [{
-    builder.CreateMaskedScatter(
-      $value, $ptrs, llvm::Align($alignment), $mask);
-  }];
+    // An absent alignment attribute means the ABI alignment of the type, which
+    // LLVM spells as an absent align parameter attribute. The IRBuilder helper
+    // always attaches one, so remove it again in that case.
+    llvm::Align alignment =
+        $alignment ? llvm::Align(*$alignment) : llvm::Align(1);
+    auto *inst = builder.CreateMaskedScatter($value, $ptrs, alignment, $mask);
+    if (!$alignment)
+      inst->removeParamAttr(1, llvm::Attribute::Alignment);
+  }] # setAccessGroupsMetadataCode
+     # setAliasAnalysisMetadataCode;
   string mlirBuilder = [{
     auto *intrinInst = dyn_cast<llvm::IntrinsicInst>(inst);
-    llvm::Align alignment = intrinInst->getParamAlign(1).valueOrOne();
+    llvm::MaybeAlign alignment = intrinInst->getParamAlign(1);
     $_op = LLVM::masked_scatter::create($_builder, $_location,
-      $value, $ptrs, $mask, $_builder.getI32IntegerAttr(alignment.value()));
+      $value, $ptrs, $mask,
+      alignment ? $_builder.getI64IntegerAttr(alignment->value())
+                : ::mlir::IntegerAttr(),
+      /*access_groups=*/nullptr, /*alias_scopes=*/nullptr,
+      /*noalias_scopes=*/nullptr, /*tbaa=*/nullptr);
   }];
-  list<int> llvmArgIndices = [0, 1, 2, -1];
+  list<int> llvmArgIndices = [0, 1, 2, -1, -1, -1, -1, -1];
 
   let hasVerifier = 1;
 }
@@ -1468,7 +1585,8 @@ def LLVM_masked_scatter : 
LLVM_ZeroResultIntrOp<"masked.scatter"> {
 /// Create a call to Masked Expand Load intrinsic.
 def LLVM_masked_expandload
   : LLVM_OneResultIntrOp<"masked.expandload", [0], [0],
-  /*traits=*/[], /*requiresFastMath=*/0, /*requiresArgAndResultAttrs=*/1,
+  /*traits=*/[], /*requiresAccessGroup=*/0, /*requiresAliasAnalysis=*/0,
+  /*requiresFastmath=*/0, /*requiresArgAndResultAttrs=*/1,
   /*immArgPositions=*/[], /*immArgAttrNames=*/[]> {
   dag args = (ins LLVM_AnyPointer:$ptr,
                        LLVM_VectorOf<I1>:$mask,
@@ -1580,6 +1698,7 @@ def LLVM_vector_insert
                   PredOpTrait<"it is not inserting scalable into fixed-length 
vectors.",
                     CPred<"!isScalableVectorType($srcvec.getType()) || "
                           "...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/221879
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to