diff --git a/ir/type.cpp b/ir/type.cpp index 720ca44d6..58a04d376 100644 --- a/ir/type.cpp +++ b/ir/type.cpp @@ -6,6 +6,7 @@ #include "ir/state.h" #include "smt/solver.h" #include "util/compiler.h" +#include "util/config.h" #include #include #include @@ -1089,12 +1090,19 @@ void ArrayType::print(ostream &os) const { } -VectorType::VectorType(string &&name, unsigned elements, Type &elementTy) - : AggregateType(std::move(name), false) { - assert(elements != 0); - this->elements = elements; +expr VectorType::vscale() const { + return defined ? expr::mkUInt(vscale_value, var_vector_elements) : + var("vscale", var_vector_elements); +} + +VectorType::VectorType(string &&name, unsigned elems, Type &elTy, bool scal) + : AggregateType(std::move(name), false), scalable(scal), min_elements(elems) { + assert(elems != 0); + if (scalable) + elems *= util::config::vscale_value; + this->elements = elems; defined = true; - children.resize(elements, &elementTy); + children.resize(elements, &elTy); is_padding.resize(elements, false); } @@ -1172,14 +1180,25 @@ bool VectorType::isVectorType() const { return true; } +void VectorType::fixup(const Model &m) { + if (!defined) + vscale_value = m.getUInt(vscale()); + AggregateType::fixup(m); +} + expr VectorType::enforceVectorType( const function &enforceElem) const { return enforceElem(*children[0]); } void VectorType::print(ostream &os) const { - if (elements) - os << '<' << elements << " x " << *children[0] << '>'; + if (!elements) + return; + os << '<'; + if (scalable) { + os << "vscale" << ":" << util::config::vscale_value << " x "; + } + os << min_elements << " x " << *children[0] << '>'; } diff --git a/ir/type.h b/ir/type.h index d732490c6..ee3d9ca42 100644 --- a/ir/type.h +++ b/ir/type.h @@ -5,6 +5,7 @@ #include "ir/attrs.h" #include "smt/expr.h" +#include "util/config.h" #include #include @@ -335,9 +336,14 @@ class ArrayType final : public AggregateType { class VectorType final : public AggregateType { +private: + bool scalable = false; + unsigned min_elements, vscale_value; + public: + smt::expr vscale() const; VectorType(std::string &&name) : AggregateType(std::move(name)) {} - VectorType(std::string &&name, unsigned elements, Type &elementTy); + VectorType(std::string &&name, unsigned elems, Type &elemTy, bool scalable); IR::StateValue extract(const IR::StateValue &vector, const smt::expr &index) const; @@ -348,6 +354,7 @@ class VectorType final : public AggregateType { unsigned maxSubBitAccess() const override; smt::expr scalarSize() const override; bool isVectorType() const override; + void fixup(const smt::Model &m) override; smt::expr enforceVectorType( const std::function &enforceElem) const override; void print(std::ostream &os) const override; diff --git a/llvm_util/cmd_args_def.h b/llvm_util/cmd_args_def.h index fd4443bc6..4865f753e 100644 --- a/llvm_util/cmd_args_def.h +++ b/llvm_util/cmd_args_def.h @@ -24,6 +24,7 @@ config::debug = opt_debug; config::quiet = opt_quiet; config::max_offset_bits = opt_max_offset_in_bits; config::max_sizet_bits = opt_max_sizet_in_bits; +config::vscale_value = opt_vscale; if ((config::disallow_ub_exploitation = opt_disallow_ub_exploitation)) { config::disable_undef_input = true; diff --git a/llvm_util/cmd_args_list.h b/llvm_util/cmd_args_list.h index b732ec92a..853deb6b1 100644 --- a/llvm_util/cmd_args_list.h +++ b/llvm_util/cmd_args_list.h @@ -185,4 +185,9 @@ llvm::cl::opt opt_disallow_ub_exploitation( llvm::cl::desc("Disallow UB exploitation by optimizations (default=allow)"), llvm::cl::init(false), llvm::cl::cat(alive_cmdargs)); +llvm::cl::opt opt_vscale(LLVM_ARGS_PREFIX "vscale", + llvm::cl::desc("Set vscale value for scalable vectors (default=2)"), + llvm::cl::init(2), llvm::cl::value_desc("value"), + llvm::cl::cat(alive_cmdargs)); + } diff --git a/llvm_util/llvm2alive.cpp b/llvm_util/llvm2alive.cpp index f57e7900d..d446a1863 100644 --- a/llvm_util/llvm2alive.cpp +++ b/llvm_util/llvm2alive.cpp @@ -1179,6 +1179,13 @@ class llvm2alive_ : public llvm::InstVisitor> { PARSE_BINOP(); return make_unique(*a, *b); } + case llvm::Intrinsic::vscale: { + auto ty = llvm_type2alive(i.getType()); + if (!ty) + return error(i); + auto val = make_intconst(config::vscale_value, ty->bits()); + return make_unique(*ty, value_name(i), *val, UnaryOp::Copy); + } // do nothing intrinsics case llvm::Intrinsic::dbg_declare: @@ -1287,8 +1294,17 @@ class llvm2alive_ : public llvm::InstVisitor> { RetTy visitShuffleVectorInst(llvm::ShuffleVectorInst &i) { PARSE_BINOP(); vector mask; - for (auto m : i.getShuffleMask()) - mask.push_back(m); + + unsigned replicate = 1; + if (i.getType()->isScalableTy()) { + replicate = config::vscale_value; + } + + auto &&sm = i.getShuffleMask(); + for (unsigned j = 0; j < replicate; j++) { + mask.insert(mask.end(), sm.begin(), sm.end()); + } + return make_unique(*ty, value_name(i), *a, *b, std::move(mask)); } diff --git a/llvm_util/utils.cpp b/llvm_util/utils.cpp index a359edea0..4e24ff201 100644 --- a/llvm_util/utils.cpp +++ b/llvm_util/utils.cpp @@ -199,7 +199,8 @@ Type* llvm_type2alive(const llvm::Type *ty) { return cache.get(); } // TODO: non-fixed sized vectors - case llvm::Type::FixedVectorTyID: { + case llvm::Type::FixedVectorTyID: + case llvm::Type::ScalableVectorTyID: { auto &cache = type_cache[ty]; if (!cache) { auto vty = cast(ty); @@ -208,7 +209,7 @@ Type* llvm_type2alive(const llvm::Type *ty) { if (!ety || elems > 1024) return nullptr; cache = make_unique("ty_" + to_string(type_id_counter++), - elems, *ety); + elems, *ety, vty->isScalableTy()); } return cache.get(); } diff --git a/tests/alive-tv/vector/scalable/insert-loop1.ll b/tests/alive-tv/vector/scalable/insert-loop1.ll new file mode 100644 index 000000000..29d7d79c3 --- /dev/null +++ b/tests/alive-tv/vector/scalable/insert-loop1.ll @@ -0,0 +1,29 @@ +define i32 @src() { + ret i32 1 +} + +define i32 @tgt() { +entry: + %vs = call i32 @llvm.vscale.i32() + %len = mul i32 %vs, 2 + %init_vec = insertelement poison, i32 0, i32 0 + br label %for.cond + +for.cond: + %i = phi i32 [ 0, %entry ], [ %inc, %for.body ] + %vec = phi [ %init_vec, %entry ], [ %new_vec, %for.body ] + %cmp = icmp slt i32 %i, %len + br i1 %cmp, label %for.body, label %exit + +for.body: + %new_vec = insertelement %vec, i32 %i, i32 %i + %inc = add i32 %i, 1 + br label %for.cond + +exit: + %last_idx = sub i32 %len, 1 + %result = extractelement %vec, i32 %last_idx + ret i32 %result +} + +; TEST-ARGS: --vscale=1 -tgt-unroll=2 diff --git a/tests/alive-tv/vector/scalable/insert-loop2.ll b/tests/alive-tv/vector/scalable/insert-loop2.ll new file mode 100644 index 000000000..5358deb8a --- /dev/null +++ b/tests/alive-tv/vector/scalable/insert-loop2.ll @@ -0,0 +1,28 @@ +define i32 @src() { + ret i32 3 +} +define i32 @tgt() { +entry: + %vs = call i32 @llvm.vscale.i32() + %len = mul i32 %vs, 2 + %init_vec = insertelement poison, i32 0, i32 0 + br label %for.cond + +for.cond: + %i = phi i32 [ 0, %entry ], [ %inc, %for.body ] + %vec = phi [ %init_vec, %entry ], [ %new_vec, %for.body ] + %cmp = icmp slt i32 %i, %len + br i1 %cmp, label %for.body, label %exit + +for.body: + %new_vec = insertelement %vec, i32 %i, i32 %i + %inc = add i32 %i, 1 + br label %for.cond + +exit: + %last_idx = sub i32 %len, 1 + %result = extractelement %vec, i32 %last_idx + ret i32 %result +} + +; TEST-ARGS: --vscale=2 -tgt-unroll=4 diff --git a/tests/alive-tv/vector/scalable/insert-loop3.ll b/tests/alive-tv/vector/scalable/insert-loop3.ll new file mode 100644 index 000000000..7c5afca99 --- /dev/null +++ b/tests/alive-tv/vector/scalable/insert-loop3.ll @@ -0,0 +1,28 @@ +define i32 @src() { + ret i32 5 +} +define i32 @tgt() { +entry: + %vs = call i32 @llvm.vscale.i32() + %len = mul i32 %vs, 2 + %init_vec = insertelement poison, i32 0, i32 0 + br label %for.cond + +for.cond: + %i = phi i32 [ 0, %entry ], [ %inc, %for.body ] + %vec = phi [ %init_vec, %entry ], [ %new_vec, %for.body ] + %cmp = icmp slt i32 %i, %len + br i1 %cmp, label %for.body, label %exit + +for.body: + %new_vec = insertelement %vec, i32 %i, i32 %i + %inc = add i32 %i, 1 + br label %for.cond + +exit: + %last_idx = sub i32 %len, 1 + %result = extractelement %vec, i32 %last_idx + ret i32 %result +} + +; TEST-ARGS: --vscale=3 -tgt-unroll=6 diff --git a/tests/alive-tv/vector/scalable/shufflevector-poison1.srctgt.ll b/tests/alive-tv/vector/scalable/shufflevector-poison1.srctgt.ll new file mode 100644 index 000000000..ef31ad7dc --- /dev/null +++ b/tests/alive-tv/vector/scalable/shufflevector-poison1.srctgt.ll @@ -0,0 +1,11 @@ +define @src( %vec) { + %insert = insertelement %vec, i32 0, i32 0 + %shuf = shufflevector %insert, poison, poison + ret %shuf +} + +define @tgt( %vec) { + ret poison +} + +; TEST-ARGS: --vscale=1 diff --git a/tests/alive-tv/vector/scalable/shufflevector-poison2.srctgt.ll b/tests/alive-tv/vector/scalable/shufflevector-poison2.srctgt.ll new file mode 100644 index 000000000..318f7e737 --- /dev/null +++ b/tests/alive-tv/vector/scalable/shufflevector-poison2.srctgt.ll @@ -0,0 +1,11 @@ +define @src( %vec) { + %insert = insertelement %vec, i32 0, i32 0 + %shuf = shufflevector %insert, poison, poison + ret %shuf +} + +define @tgt( %vec) { + ret poison +} + +; TEST-ARGS: --vscale=2 diff --git a/tests/alive-tv/vector/scalable/shufflevector-poison3.srctgt.ll b/tests/alive-tv/vector/scalable/shufflevector-poison3.srctgt.ll new file mode 100644 index 000000000..0c7ea7b71 --- /dev/null +++ b/tests/alive-tv/vector/scalable/shufflevector-poison3.srctgt.ll @@ -0,0 +1,11 @@ +define @src( %vec) { + %insert = insertelement %vec, i32 0, i32 0 + %shuf = shufflevector %insert, poison, poison + ret %shuf +} + +define @tgt( %vec) { + ret poison +} + +; TEST-ARGS: --vscale=3 diff --git a/tests/alive-tv/vector/scalable/shufflevector1.srctgt.ll b/tests/alive-tv/vector/scalable/shufflevector1.srctgt.ll new file mode 100644 index 000000000..5511ebece --- /dev/null +++ b/tests/alive-tv/vector/scalable/shufflevector1.srctgt.ll @@ -0,0 +1,11 @@ +define @src( %vec) { + %insert = insertelement %vec, i32 0, i32 0 + %shuf = shufflevector %insert, poison, zeroinitializer + ret %shuf +} + +define @tgt( %vec) { + ret zeroinitializer +} + +; TEST-ARGS: --vscale=1 diff --git a/tests/alive-tv/vector/scalable/shufflevector2.srctgt.ll b/tests/alive-tv/vector/scalable/shufflevector2.srctgt.ll new file mode 100644 index 000000000..1a1a8679c --- /dev/null +++ b/tests/alive-tv/vector/scalable/shufflevector2.srctgt.ll @@ -0,0 +1,11 @@ +define @src( %vec) { + %insert = insertelement %vec, i32 0, i32 0 + %shuf = shufflevector %insert, poison, zeroinitializer + ret %shuf +} + +define @tgt( %vec) { + ret zeroinitializer +} + +; TEST-ARGS: --vscale=2 diff --git a/tests/alive-tv/vector/scalable/shufflevector3.srctgt.ll b/tests/alive-tv/vector/scalable/shufflevector3.srctgt.ll new file mode 100644 index 000000000..dd8307b55 --- /dev/null +++ b/tests/alive-tv/vector/scalable/shufflevector3.srctgt.ll @@ -0,0 +1,11 @@ +define @src( %vec) { + %insert = insertelement %vec, i32 0, i32 0 + %shuf = shufflevector %insert, poison, zeroinitializer + ret %shuf +} + +define @tgt( %vec) { + ret zeroinitializer +} + +; TEST-ARGS: --vscale=3 diff --git a/tests/alive-tv/vector/scalable/splat_with_insertelement1.srctgt.ll b/tests/alive-tv/vector/scalable/splat_with_insertelement1.srctgt.ll new file mode 100644 index 000000000..409437536 --- /dev/null +++ b/tests/alive-tv/vector/scalable/splat_with_insertelement1.srctgt.ll @@ -0,0 +1,13 @@ +define @src( %vec, i32 %val) { + %vec1 = insertelement %vec, i32 0, i32 0 + %vec2 = insertelement %vec1, i32 0, i32 1 + %vec3 = insertelement %vec2, i32 0, i32 2 + %result = insertelement %vec3, i32 0, i32 3 + ret %result +} + +define @tgt( %vec, i32 %val) { + ret poison +} + +; TEST-ARGS: --vscale=1 diff --git a/tests/alive-tv/vector/scalable/splat_with_insertelement2.srctgt.ll b/tests/alive-tv/vector/scalable/splat_with_insertelement2.srctgt.ll new file mode 100644 index 000000000..08556c098 --- /dev/null +++ b/tests/alive-tv/vector/scalable/splat_with_insertelement2.srctgt.ll @@ -0,0 +1,13 @@ +define @src( %vec, i32 %val) { + %vec1 = insertelement %vec, i32 0, i32 0 + %vec2 = insertelement %vec1, i32 0, i32 1 + %vec3 = insertelement %vec2, i32 0, i32 2 + %result = insertelement %vec3, i32 0, i32 3 + ret %result +} + +define @tgt( %vec, i32 %val) { + ret zeroinitializer +} + +; TEST-ARGS: --vscale=2 diff --git a/tests/alive-tv/vector/scalable/splat_with_insertelement3.srctgt.ll b/tests/alive-tv/vector/scalable/splat_with_insertelement3.srctgt.ll new file mode 100644 index 000000000..69fcea4ed --- /dev/null +++ b/tests/alive-tv/vector/scalable/splat_with_insertelement3.srctgt.ll @@ -0,0 +1,14 @@ +define @src( %vec, i32 %val) { + %vec1 = insertelement %vec, i32 0, i32 0 + %vec2 = insertelement %vec1, i32 0, i32 1 + %vec3 = insertelement %vec2, i32 0, i32 2 + %result = insertelement %vec3, i32 0, i32 3 + ret %result +} + +define @tgt( %vec, i32 %val) { + ret zeroinitializer +} + +; TEST-ARGS: --vscale=3 +; ERROR: Value mismatch diff --git a/tests/alive-tv/vector/scalable/vscale-i32-intrinsic-1.srctgt.ll b/tests/alive-tv/vector/scalable/vscale-i32-intrinsic-1.srctgt.ll new file mode 100644 index 000000000..a137f0342 --- /dev/null +++ b/tests/alive-tv/vector/scalable/vscale-i32-intrinsic-1.srctgt.ll @@ -0,0 +1,13 @@ +declare i32 @llvm.vscale.i32() + +define i32 @src() { + %v = call i32 @llvm.vscale.i32() + ret i32 %v +} + +define i32 @tgt() { + ret i32 1 +} + + +; TEST-ARGS: --vscale=1 diff --git a/tests/alive-tv/vector/scalable/vscale-i32-intrinsic-2.srctgt.ll b/tests/alive-tv/vector/scalable/vscale-i32-intrinsic-2.srctgt.ll new file mode 100644 index 000000000..396ec367c --- /dev/null +++ b/tests/alive-tv/vector/scalable/vscale-i32-intrinsic-2.srctgt.ll @@ -0,0 +1,13 @@ +declare i32 @llvm.vscale.i32() + +define i32 @src() { + %v = call i32 @llvm.vscale.i32() + ret i32 %v +} + +define i32 @tgt() { + ret i32 2 +} + + +; TEST-ARGS: --vscale=2 diff --git a/tests/alive-tv/vector/scalable/vscale-i32-intrinsic-3.srctgt.ll b/tests/alive-tv/vector/scalable/vscale-i32-intrinsic-3.srctgt.ll new file mode 100644 index 000000000..1911e0c92 --- /dev/null +++ b/tests/alive-tv/vector/scalable/vscale-i32-intrinsic-3.srctgt.ll @@ -0,0 +1,13 @@ +declare i32 @llvm.vscale.i32() + +define i32 @src() { + %v = call i32 @llvm.vscale.i32() + ret i32 %v +} + +define i32 @tgt() { + ret i32 3 +} + + +; TEST-ARGS: --vscale=3 diff --git a/tests/alive-tv/vector/scalable/vscale-i64-intrinsic-1.srctgt.ll b/tests/alive-tv/vector/scalable/vscale-i64-intrinsic-1.srctgt.ll new file mode 100644 index 000000000..6b51c8c30 --- /dev/null +++ b/tests/alive-tv/vector/scalable/vscale-i64-intrinsic-1.srctgt.ll @@ -0,0 +1,13 @@ +declare i64 @llvm.vscale.i64() + +define i64 @src() { + %v = call i64 @llvm.vscale.i64() + ret i64 %v +} + +define i64 @tgt() { + ret i64 1 +} + + +; TEST-ARGS: --vscale=1 diff --git a/tests/alive-tv/vector/scalable/vscale-i64-intrinsic-2.srctgt.ll b/tests/alive-tv/vector/scalable/vscale-i64-intrinsic-2.srctgt.ll new file mode 100644 index 000000000..919f9717c --- /dev/null +++ b/tests/alive-tv/vector/scalable/vscale-i64-intrinsic-2.srctgt.ll @@ -0,0 +1,13 @@ +declare i64 @llvm.vscale.i64() + +define i64 @src() { + %v = call i64 @llvm.vscale.i64() + ret i64 %v +} + +define i64 @tgt() { + ret i64 2 +} + + +; TEST-ARGS: --vscale=2 diff --git a/tests/alive-tv/vector/scalable/vscale-i64-intrinsic-3.srctgt.ll b/tests/alive-tv/vector/scalable/vscale-i64-intrinsic-3.srctgt.ll new file mode 100644 index 000000000..7a8b68805 --- /dev/null +++ b/tests/alive-tv/vector/scalable/vscale-i64-intrinsic-3.srctgt.ll @@ -0,0 +1,13 @@ +declare i64 @llvm.vscale.i64() + +define i64 @src() { + %v = call i64 @llvm.vscale.i64() + ret i64 %v +} + +define i64 @tgt() { + ret i64 3 +} + + +; TEST-ARGS: --vscale=3 diff --git a/tests/unit/vector/scalablevector1.opt b/tests/unit/vector/scalablevector1.opt new file mode 100644 index 000000000..fdfa22135 --- /dev/null +++ b/tests/unit/vector/scalablevector1.opt @@ -0,0 +1,76 @@ +Name: scalable vector add - identity +%r = add %a, %b + => +%r = add %a, %b + + +Name: scalable vector add - commutative +%r = add %a, %b + => +%r = add %b, %a + + +Name: scalable vector mul - identity +%r = mul %a, %b + => +%r = mul %a, %b + + +Name: scalable vector mul - commutative +%r = mul %a, %b + => +%r = mul %b, %a + + +Name: scalable vector extract - identity +%r = extractelement %vec, i32 %idx + => +%r = extractelement %vec, i32 %idx + + +Name: scalable vector insert - identity +%r = insertelement %vec, i4 %val, i32 %idx + => +%r = insertelement %vec, i4 %val, i32 %idx + + +Name: scalable vector sub - identity +%r = sub %a, %b + => +%r = sub %a, %b + + +Name: scalable vector and - identity +%r = and %a, %b + => +%r = and %a, %b + + +Name: scalable vector or - identity +%r = or %a, %b + => +%r = or %a, %b + + +Name: scalable vector xor - identity +%r = xor %a, %b + => +%r = xor %a, %b + + +Name: scalable vector shl - identity +%r = shl %a, %b + => +%r = shl %a, %b + + +Name: scalable vector lshr - identity +%r = lshr %a, %b + => +%r = lshr %a, %b + + +Name: scalable vector ashr - identity +%r = ashr %a, %b + => +%r = ashr %a, %b diff --git a/tests/unit/vector/scalablevector2.opt b/tests/unit/vector/scalablevector2.opt new file mode 100644 index 000000000..adec151c2 --- /dev/null +++ b/tests/unit/vector/scalablevector2.opt @@ -0,0 +1,15 @@ +; TEST-ARGS: -vscale:2 +Name: insert and extract on same location +%t = insertelement %vec, i4 %x, i64 3 +%r = extractelement %t, i64 3 + => +%r = i4 %x + + +Name: insert and extract on different location +%t = insertelement %vec, i4 %x, i64 3 +%r = extractelement %t, i64 0 + => +%r = i4 %x + +; ERROR: Target is more poisonous than source for i4 %r diff --git a/tools/alive.cpp b/tools/alive.cpp index 1ca919f21..75fe31b0c 100644 --- a/tools/alive.cpp +++ b/tools/alive.cpp @@ -36,6 +36,7 @@ static void show_help() { " -skip-smt\t\tSkip all SMT queries\n" " -disable-poison-input\tAssume input variables can never be poison\n" " -disable-undef-input\tAssume input variables can never be undef\n" + " -vscale:x\t\tSet vscale value for scalable vectors (default: 1)\n" " -h / --help / -v / --version\tShow this help\n"; } @@ -76,6 +77,8 @@ int main(int argc, char **argv) { config::disable_undef_input = true; else if (arg == "-disable-poison-input") config::disable_poison_input = true; + else if (arg.compare(0, 8, "-vscale:") == 0 && arg.size() > 8) + config::vscale_value = strtoul(arg.substr(8).data(), nullptr, 10); else if (arg == "-h" || arg == "--help" || arg == "-v" || arg == "--version") { show_help(); diff --git a/tools/alive_lexer.re b/tools/alive_lexer.re index f2881a738..f12cbf83e 100644 --- a/tools/alive_lexer.re +++ b/tools/alive_lexer.re @@ -105,9 +105,14 @@ space+ { return INT_TYPE; } +"("vty_" + to_string(vector_types.size()), - elements, elemTy)).get(); + elements, elemTy, scalable)).get(); } static Type& parse_array_type(); @@ -1330,7 +1332,8 @@ static unique_ptr parse_instr(string_view name) { case HALF: case FLOAT: case DOUBLE: - case VECTOR_TYPE_PREFIX: + case FIXED_VECTOR_TYPE_PREFIX: + case SCALABLE_VECTOR_TYPE_PREFIX: case LBRACE: case NUM: case FP_NUM: diff --git a/tools/tokens.h b/tools/tokens.h index 8d80973ff..453e5180d 100644 --- a/tools/tokens.h +++ b/tools/tokens.h @@ -164,7 +164,8 @@ TOKEN(UREM) TOKEN(USUB_OVERFLOW) TOKEN(USUB_SAT) TOKEN(USHL_SAT) -TOKEN(VECTOR_TYPE_PREFIX) +TOKEN(FIXED_VECTOR_TYPE_PREFIX) +TOKEN(SCALABLE_VECTOR_TYPE_PREFIX) TOKEN(WRITE) TOKEN(XOR) TOKEN(ZEXT) diff --git a/util/config.cpp b/util/config.cpp index 632b72561..41306c111 100644 --- a/util/config.cpp +++ b/util/config.cpp @@ -24,6 +24,7 @@ unsigned src_unroll_cnt = 0; unsigned tgt_unroll_cnt = 0; unsigned max_offset_bits = 64; unsigned max_sizet_bits = 64; +unsigned vscale_value = 2; ostream &dbg() { return *debug_os; diff --git a/util/config.h b/util/config.h index 6cf2314ff..5b1baf468 100644 --- a/util/config.h +++ b/util/config.h @@ -46,6 +46,9 @@ extern unsigned max_offset_bits; // size and size of pointers (not to be confused with program pointer size). extern unsigned max_sizet_bits; +// The vscale value for scalable vectors. +extern unsigned vscale_value; + std::ostream &dbg(); void set_debug(std::ostream &os);