diff --git a/include/cudaq/Optimizer/Dialect/Quake/QuakeTypes.td b/include/cudaq/Optimizer/Dialect/Quake/QuakeTypes.td index 2e6fc9dfe3..7dd31469fd 100644 --- a/include/cudaq/Optimizer/Dialect/Quake/QuakeTypes.td +++ b/include/cudaq/Optimizer/Dialect/Quake/QuakeTypes.td @@ -150,7 +150,6 @@ def VeqType : QuakeType<"Veq", "veq"> { let parameters = (ins "std::size_t":$size); - let genVerifyDecl = 1; let hasCustomAssemblyFormat = 1; let extraClassDeclaration = [{ @@ -177,8 +176,10 @@ def StruqType : QuakeType<"Struq", "struq"> { let parameters = (ins "mlir::StringAttr":$name, + // members must be NonStruqRefType. ArrayRefParameter<"mlir::Type">:$members ); + let hasCustomAssemblyFormat = 1; let extraClassDeclaration = [{ diff --git a/lib/Optimizer/Dialect/Quake/QuakeOps.cpp b/lib/Optimizer/Dialect/Quake/QuakeOps.cpp index e3d9ab13d1..b4185c2a1e 100644 --- a/lib/Optimizer/Dialect/Quake/QuakeOps.cpp +++ b/lib/Optimizer/Dialect/Quake/QuakeOps.cpp @@ -162,6 +162,16 @@ LogicalResult quake::AllocaOp::verify() { return emitOpError("size operand required"); } } + } else { + // Size has no semantics for any type other than quake.veq. + if (getSize()) + return emitOpError("cannot specify size with this quantum type"); + + if (auto stqTy = dyn_cast(getResult().getType())) + for (auto t : stqTy.getMembers()) + if (auto vt = dyn_cast(t)) + if (!vt.hasSpecifiedSize()) + return emitOpError("struq type must have specified size"); } // Check the uses. If any use is a InitializeStateOp, then it must be the only diff --git a/lib/Optimizer/Dialect/Quake/QuakeTypes.cpp b/lib/Optimizer/Dialect/Quake/QuakeTypes.cpp index 959a869fe5..c4eb8faee1 100644 --- a/lib/Optimizer/Dialect/Quake/QuakeTypes.cpp +++ b/lib/Optimizer/Dialect/Quake/QuakeTypes.cpp @@ -49,13 +49,6 @@ Type quake::VeqType::parse(AsmParser &parser) { return get(parser.getContext(), size); } -LogicalResult -quake::VeqType::verify(llvm::function_ref emitError, - std::size_t size) { - // FIXME: Do we want to check the size of the veq for some bound? - return success(); -} - //===----------------------------------------------------------------------===// Type quake::StruqType::parse(AsmParser &parser) { @@ -77,6 +70,9 @@ Type quake::StruqType::parse(AsmParser &parser) { break; if (!succeeded(*optTy)) return {}; + if (!llvm::isa(member)) + parser.emitError(parser.getCurrentLocation(), + "invalid struq member type"); members.push_back(member); } while (succeeded(parser.parseOptionalComma())); if (parser.parseGreater()) diff --git a/test/Quake/invalid.qke b/test/Quake/invalid.qke index 1dd79e84c0..45fa797f57 100644 --- a/test/Quake/invalid.qke +++ b/test/Quake/invalid.qke @@ -12,6 +12,7 @@ func.func @test_struq() { %0 = quake.alloca !quake.veq<4> %1 = arith.constant 1 : i32 %2 = arith.constant 2.0 : f32 + // expected-error@+2 {{invalid struq member type}} // expected-error@+1 {{must be non-struct quantum reference type}} %6 = quake.make_struq %0, %1, %2 : (!quake.veq<4>, i32, f32) -> !quake.struq, i32, f32> return @@ -54,3 +55,19 @@ func.func @test_struq(%arg : !quake.struq, !quake.veq<2>, !quake.v %6 = quake.get_member %arg[3] : (!quake.struq, !quake.veq<2>, !quake.veq<3>>) -> !quake.veq<1> return } + +// ----- + +func.func @test_struq() { + // expected-error@+1 {{struq type must have specified size}} + %0 = quake.alloca !quake.struq, !quake.veq> + return +} + +// ----- + +func.func @test_struq() { + // expected-error@+1 {{invalid struq member type}} + %0 = quake.alloca !quake.struq, !quake.ref>, !quake.veq<7>> + return +} diff --git a/test/Quake/roundtrip-ops.qke b/test/Quake/roundtrip-ops.qke index 2d094e4060..c73685d9b8 100644 --- a/test/Quake/roundtrip-ops.qke +++ b/test/Quake/roundtrip-ops.qke @@ -818,6 +818,7 @@ func.func @quantum_product_type() { %22 = quake.make_struq %20, %21 : (!quake.veq<7>, !quake.veq<8>) -> !quake.struq, !quake.veq<8>> %23 = quake.get_member %22[0] : (!quake.struq, !quake.veq<8>>) -> !quake.veq<7> %24 = quake.get_member %22[1] : (!quake.struq, !quake.veq<8>>) -> !quake.veq<8> + %25 = quake.alloca !quake.struq, !quake.veq<5>> return } @@ -837,5 +838,6 @@ func.func @quantum_product_type() { // CHECK: %[[VAL_12:.*]] = quake.make_struq %[[VAL_10]], %[[VAL_11]] : (!quake.veq<7>, !quake.veq<8>) -> !quake.struq, !quake.veq<8>> // CHECK: %[[VAL_13:.*]] = quake.get_member %[[VAL_12]][0] : (!quake.struq, !quake.veq<8>>) -> !quake.veq<7> // CHECK: %[[VAL_14:.*]] = quake.get_member %[[VAL_12]][1] : (!quake.struq, !quake.veq<8>>) -> !quake.veq<8> +// CHECK: %[[VAL_15:.*]] = quake.alloca !quake.struq, !quake.veq<5>> // CHECK: return // CHECK: }