diff --git a/libcxx/include/functional b/libcxx/include/functional index fa55864bc5d65e..9d15485839304d 100644 --- a/libcxx/include/functional +++ b/libcxx/include/functional @@ -2387,7 +2387,7 @@ public: function& operator=(const function&); function& operator=(function&&) _NOEXCEPT; function& operator=(nullptr_t) _NOEXCEPT; - template> + template::type>> function& operator=(_Fp&&); ~function(); diff --git a/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F_assign.pass.cpp b/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F_assign.pass.cpp index a2458414b04871..4fc7bcfc48710c 100644 --- a/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F_assign.pass.cpp +++ b/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F_assign.pass.cpp @@ -118,6 +118,26 @@ int main(int, char**) static_assert(!std::is_assignable::value, ""); static_assert(!std::is_assignable::value, ""); } + { + using Fn = std::function; + static_assert(std::is_assignable::value, ""); + } + { + using F1 = std::function; + using F2 = std::function; + static_assert(!std::is_assignable::value, ""); + } + { + using F1 = std::function; + using F2 = std::function; + static_assert(!std::is_assignable::value, ""); + static_assert(!std::is_assignable::value, ""); + } + { + using F1 = std::function; + using F2 = std::function; + static_assert(!std::is_assignable::value, ""); + } #endif return 0; diff --git a/libcxx/www/cxx1z_status.html b/libcxx/www/cxx1z_status.html index 83aedb96bdb756..c8b3374ba42e96 100644 --- a/libcxx/www/cxx1z_status.html +++ b/libcxx/www/cxx1z_status.html @@ -299,7 +299,7 @@

Library Working group Issues Status

2566Requirements on the first template parameter of container adaptorsJacksonvilleComplete 2571§[map.modifiers]/2 imposes nonsensical requirement on insert(InputIterator, InputIterator)JacksonvilleComplete 2572The remarks for shared_ptr::operator* should apply to cv-qualified void as wellJacksonvilleComplete - 2574[fund.ts.v2] std::experimental::function::operator=(F&&) should be constrainedJacksonville + 2574[fund.ts.v2] std::experimental::function::operator=(F&&) should be constrainedJacksonvilleComplete 2575[fund.ts.v2] experimental::function::assign should be removedJacksonville 2576istream_iterator and ostream_iterator should use std::addressofJacksonvilleComplete 2577{shared,unique}_lock should use std::addressofJacksonvilleComplete diff --git a/lldb/test/API/functionalities/load_using_paths/TestLoadUsingPaths.py b/lldb/test/API/functionalities/load_using_paths/TestLoadUsingPaths.py index 0adb3d09b606c9..a7d5f07a097669 100644 --- a/lldb/test/API/functionalities/load_using_paths/TestLoadUsingPaths.py +++ b/lldb/test/API/functionalities/load_using_paths/TestLoadUsingPaths.py @@ -40,6 +40,7 @@ def setUp(self): @not_remote_testsuite_ready @skipIfWindows # Windows doesn't have dlopen and friends, dynamic libraries work differently @expectedFlakeyNetBSD + @expectedFailureAll(oslist=["linux"], archs=['arm'], bugnumber="llvm.org/pr45894") def test_load_using_paths(self): """Test that we can load a module by providing a set of search paths.""" if self.platformIsDarwin(): diff --git a/lldb/test/API/python_api/thread/TestThreadAPI.py b/lldb/test/API/python_api/thread/TestThreadAPI.py index 87d4eb8ae712cd..6e4aeddc82c9d2 100644 --- a/lldb/test/API/python_api/thread/TestThreadAPI.py +++ b/lldb/test/API/python_api/thread/TestThreadAPI.py @@ -38,6 +38,7 @@ def test_run_to_address(self): self.run_to_address(self.exe_name) @add_test_categories(['pyapi']) + @expectedFailureAll(oslist=["linux"], archs=['arm'], bugnumber="llvm.org/pr45892") @expectedFailureAll(oslist=['freebsd'], bugnumber='llvm.org/pr20476') @expectedFailureAll(oslist=["windows"]) @expectedFailureNetBSD diff --git a/lldb/test/Shell/ObjectFile/ELF/minidebuginfo-set-and-hit-breakpoint.test b/lldb/test/Shell/ObjectFile/ELF/minidebuginfo-set-and-hit-breakpoint.test index 84c69bea87f741..9507c5d6d17fc9 100644 --- a/lldb/test/Shell/ObjectFile/ELF/minidebuginfo-set-and-hit-breakpoint.test +++ b/lldb/test/Shell/ObjectFile/ELF/minidebuginfo-set-and-hit-breakpoint.test @@ -41,7 +41,7 @@ # in the .dynsym section of the main binary. The bits removing .rela.plt, # .rela.dyn and .dynsym sections can be removed once llvm-objcopy # --only-keep-debug starts to work. -# RUN: llvm-objcopy --remove-section=.rela.plt --remove-section=.rela.dyn \ +# RUN: llvm-objcopy --remove-section=.rela.plt --remove-section=.rela.dyn --remove-section=.rel.plt --remove-section=.rel.dyn \ # RUN: --remove-section=.gnu.version --remove-section=.gnu.hash --remove-section=.hash --remove-section=.dynsym %t.mini_debuginfo # Drop the full debug info from the original binary. diff --git a/lldb/test/Shell/Recognizer/assert.test b/lldb/test/Shell/Recognizer/assert.test index 9b4aa21611e0cd..d3eb9c8da7c990 100644 --- a/lldb/test/Shell/Recognizer/assert.test +++ b/lldb/test/Shell/Recognizer/assert.test @@ -1,3 +1,4 @@ +# XFAIL: target-arm && linux-gnu # UNSUPPORTED: system-windows # RUN: %clang_host -g -O0 %S/Inputs/assert.c -o %t.out # RUN: %lldb -b -s %s %t.out | FileCheck %s diff --git a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp index c764e9f2acc852..aa459c4b050acb 100644 --- a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp +++ b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp @@ -1009,20 +1009,23 @@ ChangeStatus AAReturnedValuesImpl::updateImpl(Attributor &A) { return indicatePessimisticFixpoint(); // Once returned values "directly" present in the code are handled we try to - // resolve returned calls. + // resolve returned calls. To avoid modifications to the ReturnedValues map + // while we iterate over it we kept record of potential new entries in a copy + // map, NewRVsMap. decltype(ReturnedValues) NewRVsMap; - for (auto &It : ReturnedValues) { - LLVM_DEBUG(dbgs() << "[AAReturnedValues] Returned value: " << *It.first - << " by #" << It.second.size() << " RIs\n"); - CallBase *CB = dyn_cast(It.first); + + auto HandleReturnValue = [&](Value *RV, SmallSetVector &RIs) { + LLVM_DEBUG(dbgs() << "[AAReturnedValues] Returned value: " << *RV + << " by #" << RIs.size() << " RIs\n"); + CallBase *CB = dyn_cast(RV); if (!CB || UnresolvedCalls.count(CB)) - continue; + return; if (!CB->getCalledFunction()) { LLVM_DEBUG(dbgs() << "[AAReturnedValues] Unresolved call: " << *CB << "\n"); UnresolvedCalls.insert(CB); - continue; + return; } // TODO: use the function scope once we have call site AAReturnedValues. @@ -1037,7 +1040,7 @@ ChangeStatus AAReturnedValuesImpl::updateImpl(Attributor &A) { LLVM_DEBUG(dbgs() << "[AAReturnedValues] Unresolved call: " << *CB << "\n"); UnresolvedCalls.insert(CB); - continue; + return; } // Do not try to learn partial information. If the callee has unresolved @@ -1045,7 +1048,7 @@ ChangeStatus AAReturnedValuesImpl::updateImpl(Attributor &A) { auto &RetValAAUnresolvedCalls = RetValAA.getUnresolvedCalls(); if (!RetValAAUnresolvedCalls.empty()) { UnresolvedCalls.insert(CB); - continue; + return; } // Now check if we can track transitively returned values. If possible, thus @@ -1067,14 +1070,14 @@ ChangeStatus AAReturnedValuesImpl::updateImpl(Attributor &A) { } if (Unresolved) - continue; + return; // Now track transitively returned values. unsigned &NumRetAA = NumReturnedValuesPerKnownAA[CB]; if (NumRetAA == RetValAA.getNumReturnValues()) { LLVM_DEBUG(dbgs() << "[AAReturnedValues] Skip call as it has not " "changed since it was seen last\n"); - continue; + return; } NumRetAA = RetValAA.getNumReturnValues(); @@ -1093,21 +1096,32 @@ ChangeStatus AAReturnedValuesImpl::updateImpl(Attributor &A) { continue; } else if (isa(RetVal)) { // Constants are valid everywhere, we can simply take them. - NewRVsMap[RetVal].insert(It.second.begin(), It.second.end()); + NewRVsMap[RetVal].insert(RIs.begin(), RIs.end()); continue; } } - } + }; + + for (auto &It : ReturnedValues) + HandleReturnValue(It.first, It.second); + + // Because processing the new information can again lead to new return values + // we have to be careful and iterate until this iteration is complete. The + // idea is that we are in a stable state at the end of an update. All return + // values have been handled and properly categorized. We might not update + // again if we have not requested a non-fix attribute so we cannot "wait" for + // the next update to analyze a new return value. + while (!NewRVsMap.empty()) { + auto It = std::move(NewRVsMap.back()); + NewRVsMap.pop_back(); - // To avoid modifications to the ReturnedValues map while we iterate over it - // we kept record of potential new entries in a copy map, NewRVsMap. - for (auto &It : NewRVsMap) { assert(!It.second.empty() && "Entry does not add anything."); auto &ReturnInsts = ReturnedValues[It.first]; for (ReturnInst *RI : It.second) if (ReturnInsts.insert(RI)) { LLVM_DEBUG(dbgs() << "[AAReturnedValues] Add new returned value " << *It.first << " => " << *RI << "\n"); + HandleReturnValue(It.first, ReturnInsts); Changed = true; } } diff --git a/llvm/test/Transforms/Attributor/returned.ll b/llvm/test/Transforms/Attributor/returned.ll index cdc67b77c09745..1d14685ed1fc68 100644 --- a/llvm/test/Transforms/Attributor/returned.ll +++ b/llvm/test/Transforms/Attributor/returned.ll @@ -1,6 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes -; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=15 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM -; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=15 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM +; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=14 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM +; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=14 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM ; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM ; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM ; @@ -1234,4 +1234,47 @@ define i32* @dont_use_const() #0 { ret i32* %c } +; UTC_ARGS: --disable +; +; Verify we do not derive constraints for @_Z3fooP1X as if it was returning `null`. +; +; CHEKC-NOT: noalias +; CHECK-NOT: align 536870912 + +%struct.Y = type { %struct.X } +%struct.X = type { i32 (...)** } + +@_ZTI1X = external dso_local constant { i8*, i8* }, align 8 +@_ZTI1Y = external dso_local constant { i8*, i8*, i8* }, align 8 + +define internal i8* @_ZN1Y3barEv(%struct.Y* %this) align 2 { +entry: + %0 = bitcast %struct.Y* %this to i8* + ret i8* %0 +} + +define dso_local i8* @_Z3fooP1X(%struct.X* %x) { +entry: + %0 = icmp eq %struct.X* %x, null + br i1 %0, label %dynamic_cast.null, label %dynamic_cast.notnull + +dynamic_cast.notnull: ; preds = %entry + %1 = bitcast %struct.X* %x to i8* + %2 = call i8* @__dynamic_cast(i8* %1, i8* bitcast ({ i8*, i8* }* @_ZTI1X to i8*), i8* bitcast ({ i8*, i8*, i8* }* @_ZTI1Y to i8*), i64 0) #2 + %3 = bitcast i8* %2 to %struct.Y* + br label %dynamic_cast.end + +dynamic_cast.null: ; preds = %entry + br label %dynamic_cast.end + +dynamic_cast.end: ; preds = %dynamic_cast.null, %dynamic_cast.notnull + %QQ5 = phi %struct.Y* [ %3, %dynamic_cast.notnull ], [ null, %dynamic_cast.null ] + %call = call i8* @_ZN1Y3barEv(%struct.Y* %QQ5) + ret i8* %call +} + +declare dso_local i8* @__dynamic_cast(i8*, i8*, i8*, i64) + +; UTC_ARGS: --enable + attributes #0 = { noinline nounwind uwtable } diff --git a/mlir/lib/Dialect/Vector/VectorTransforms.cpp b/mlir/lib/Dialect/Vector/VectorTransforms.cpp index 6e3e681ad815de..ef536e2194c170 100644 --- a/mlir/lib/Dialect/Vector/VectorTransforms.cpp +++ b/mlir/lib/Dialect/Vector/VectorTransforms.cpp @@ -1187,6 +1187,55 @@ class OuterProductOpLowering : public OpRewritePattern { } }; +/// Progressive lowering of ConstantMaskOp. +/// One: +/// %x = vector.constant_mask_op [a,b] +/// is replaced by: +/// %z = zero-result +/// %l = vector.constant_mask_op [b] +/// %4 = vector.insert %l, %z[0] +/// .. +/// %x = vector.insert %l, %..[a-1] +/// which will be folded at LLVM IR level. +class ConstantMaskOpLowering : public OpRewritePattern { +public: + using OpRewritePattern::OpRewritePattern; + + LogicalResult matchAndRewrite(vector::ConstantMaskOp op, + PatternRewriter &rewriter) const override { + auto loc = op.getLoc(); + auto dstType = op.getResult().getType().cast(); + auto eltType = dstType.getElementType(); + auto dimSizes = op.mask_dim_sizes(); + int64_t rank = dimSizes.size(); + int64_t trueDim = dimSizes[0].cast().getInt(); + + Value trueVal; + if (rank == 1) { + trueVal = rewriter.create( + loc, eltType, rewriter.getIntegerAttr(eltType, 1)); + } else { + VectorType lowType = + VectorType::get(dstType.getShape().drop_front(), eltType); + SmallVector newDimSizes; + for (int64_t r = 1; r < rank; r++) + newDimSizes.push_back(dimSizes[r].cast().getInt()); + trueVal = rewriter.create( + loc, lowType, rewriter.getI64ArrayAttr(newDimSizes)); + } + + Value result = rewriter.create(loc, dstType, + rewriter.getZeroAttr(dstType)); + for (int64_t d = 0; d < trueDim; d++) { + auto pos = rewriter.getI64ArrayAttr(d); + result = + rewriter.create(loc, dstType, trueVal, result, pos); + } + rewriter.replaceOp(op, result); + return success(); + } +}; + /// Progressive lowering of ContractionOp. /// One: /// %x = vector.contract with at least one free/batch dimension @@ -1609,6 +1658,7 @@ void mlir::vector::populateVectorContractLoweringPatterns( VectorTransformsOptions parameters) { patterns.insert(context); + TransposeOpLowering, OuterProductOpLowering, + ConstantMaskOpLowering>(context); patterns.insert(parameters, context); } diff --git a/mlir/test/Conversion/VectorToLLVM/vector-to-llvm.mlir b/mlir/test/Conversion/VectorToLLVM/vector-to-llvm.mlir index 9e0b9464689c51..1c23072b61092a 100644 --- a/mlir/test/Conversion/VectorToLLVM/vector-to-llvm.mlir +++ b/mlir/test/Conversion/VectorToLLVM/vector-to-llvm.mlir @@ -917,3 +917,20 @@ func @transfer_read_1d_non_zero_addrspace(%A : memref, %base: index) - // CHECK-SAME: (!llvm<"float addrspace(3)*">, !llvm.i64) -> !llvm<"float addrspace(3)*"> // CHECK: %[[vecPtr_b:.*]] = llvm.addrspacecast %[[gep_b]] : // CHECK-SAME: !llvm<"float addrspace(3)*"> to !llvm<"<17 x float>*"> + +func @genbool_1d() -> vector<8xi1> { + %0 = vector.constant_mask [4] : vector<8xi1> + return %0 : vector<8xi1> +} +// CHECK-LABEL: func @genbool_1d +// CHECK: %[[T0:.*]] = llvm.mlir.constant(1 : i1) : !llvm.i1 +// CHECK: %[[T1:.*]] = llvm.mlir.constant(dense : vector<8xi1>) : !llvm<"<8 x i1>"> +// CHECK: %[[T2:.*]] = llvm.mlir.constant(0 : i64) : !llvm.i64 +// CHECK: %[[T3:.*]] = llvm.insertelement %[[T0]], %[[T1]][%[[T2]] : !llvm.i64] : !llvm<"<8 x i1>"> +// CHECK: %[[T4:.*]] = llvm.mlir.constant(1 : i64) : !llvm.i64 +// CHECK: %[[T5:.*]] = llvm.insertelement %[[T0]], %[[T3]][%[[T4]] : !llvm.i64] : !llvm<"<8 x i1>"> +// CHECK: %[[T6:.*]] = llvm.mlir.constant(2 : i64) : !llvm.i64 +// CHECK: %[[T7:.*]] = llvm.insertelement %[[T0]], %[[T5]][%[[T6]] : !llvm.i64] : !llvm<"<8 x i1>"> +// CHECK: %[[T8:.*]] = llvm.mlir.constant(3 : i64) : !llvm.i64 +// CHECK: %[[T9:.*]] = llvm.insertelement %[[T0]], %[[T7]][%[[T8]] : !llvm.i64] : !llvm<"<8 x i1>"> +// CHECK: llvm.return %9 : !llvm<"<8 x i1>"> diff --git a/mlir/test/Dialect/Vector/vector-contract-transforms.mlir b/mlir/test/Dialect/Vector/vector-contract-transforms.mlir index 563c9f76d9b2c9..a4d4fe58e8d59c 100644 --- a/mlir/test/Dialect/Vector/vector-contract-transforms.mlir +++ b/mlir/test/Dialect/Vector/vector-contract-transforms.mlir @@ -559,3 +559,49 @@ func @broadcast_stretch_in_middle(%arg0: vector<4x1x2xf32>) -> vector<4x3x2xf32> %0 = vector.broadcast %arg0 : vector<4x1x2xf32> to vector<4x3x2xf32> return %0 : vector<4x3x2xf32> } + +// CHECK-LABEL: func @genbool_1d +// CHECK: %[[TT:.*]] = constant 1 : i1 +// CHECK: %[[C1:.*]] = constant dense : vector<8xi1> +// CHECK: %[[T0.*]] = vector.insert %[[TT]], %[[C1]] [0] : i1 into vector<8xi1> +// CHECK: %[[T1.*]] = vector.insert %[[TT]], %[[T0]] [1] : i1 into vector<8xi1> +// CHECK: %[[T2.*]] = vector.insert %[[TT]], %[[T1]] [2] : i1 into vector<8xi1> +// CHECK: %[[T3.*]] = vector.insert %[[TT]], %[[T2]] [3] : i1 into vector<8xi1> +// CHECK: return %[[T3]] : vector<8xi1> + +func @genbool_1d() -> vector<8xi1> { + %0 = vector.constant_mask [4] : vector<8xi1> + return %0 : vector<8xi1> +} + +// CHECK-LABEL: func @genbool_2d +// CHECK: %[[TT:.*]] = constant 1 : i1 +// CHECK: %[[C1:.*]] = constant dense : vector<4xi1> +// CHECK: %[[C2:.*]] = constant dense : vector<4x4xi1> +// CHECK: %[[T0:.*]] = vector.insert %[[TT]], %[[C1]] [0] : i1 into vector<4xi1> +// CHECK: %[[T1:.*]] = vector.insert %[[TT]], %[[T0]] [1] : i1 into vector<4xi1> +// CHECK: %[[T2:.*]] = vector.insert %[[T1]], %[[C2]] [0] : vector<4xi1> into vector<4x4xi1> +// CHECK: %[[T3:.*]] = vector.insert %[[T1]], %[[T2]] [1] : vector<4xi1> into vector<4x4xi1> +// CHECK: return %[[T3]] : vector<4x4xi1> + +func @genbool_2d() -> vector<4x4xi1> { + %v = vector.constant_mask [2, 2] : vector<4x4xi1> + return %v: vector<4x4xi1> +} + +// CHECK-LABEL: func @genbool_3d +// CHECK: %[[Tt:.*]] = constant 1 : i1 +// CHECK: %[[C1:.*]] = constant dense : vector<4xi1> +// CHECK: %[[C2:.*]] = constant dense : vector<3x4xi1> +// CHECK: %[[C3:.*]] = constant dense : vector<2x3x4xi1> +// CHECK: %[[T0:.*]] = vector.insert %[[TT]], %[[C1]] [0] : i1 into vector<4xi1> +// CHECK: %[[T1:.*]] = vector.insert %[[TT]], %[[T0]] [1] : i1 into vector<4xi1> +// CHECK: %[[T2:.*]] = vector.insert %[[TT]], %[[T1]] [2] : i1 into vector<4xi1> +// CHECK: %[[T3:.*]] = vector.insert %[[T2]], %[[C2]] [0] : vector<4xi1> into vector<3x4xi1> +// CHECK: %[[T4:.*]] = vector.insert %[[T3]], %[[C3]] [0] : vector<3x4xi1> into vector<2x3x4xi1> +// CHECK: return %[[T4]] : vector<2x3x4xi1> + +func @genbool_3d() -> vector<2x3x4xi1> { + %v = vector.constant_mask [1, 1, 3] : vector<2x3x4xi1> + return %v: vector<2x3x4xi1> +} diff --git a/mlir/test/Target/vector-to-llvm-ir.mlir b/mlir/test/Target/vector-to-llvm-ir.mlir new file mode 100644 index 00000000000000..354f70f3f4b9e0 --- /dev/null +++ b/mlir/test/Target/vector-to-llvm-ir.mlir @@ -0,0 +1,23 @@ +// RUN: mlir-opt %s -convert-vector-to-llvm | mlir-translate -mlir-to-llvmir | FileCheck %s + +func @genbool_1d() -> vector<8xi1> { + %0 = vector.constant_mask [4] : vector<8xi1> + return %0 : vector<8xi1> +} +// CHECK-LABEL: @genbool_1d() +// CHECK-NEXT: ret <8 x i1> + +func @genbool_2d() -> vector<4x4xi1> { + %v = vector.constant_mask [2, 2] : vector<4x4xi1> + return %v: vector<4x4xi1> +} +// CHECK-LABEL: @genbool_2d() +// CHECK-NEXT: ret [4 x <4 x i1>] [<4 x i1> , <4 x i1> , <4 x i1> zeroinitializer, <4 x i1> zeroinitializer] + +func @genbool_3d() -> vector<2x3x4xi1> { + %v = vector.constant_mask [1, 1, 3] : vector<2x3x4xi1> + return %v: vector<2x3x4xi1> +} +// CHECK-LABEL: @genbool_3d() +// CHECK-NEXT: ret [2 x [3 x <4 x i1>]] {{\[+}}3 x <4 x i1>] [<4 x i1> , <4 x i1> zeroinitializer, <4 x i1> zeroinitializer], [3 x <4 x i1>] zeroinitializer] +// note: awkward syntax to match [[