Skip to content

Commit 8fe572c

Browse files
author
Dwight Guth
authored
Improvements to MINT hooks (#1128)
This PR contains a couple different small changes to improve support for MInt in the WASM semantics: * Add implementation of MINT.round, MINT.sext, MINT.umin, MINT.umax, MINT.smin, and MINT.smax. * Add support for equality between machine integers of size 32 and 64 bits. * Add variant of hook_LIST_update which takes an MInt.
1 parent 9088cef commit 8fe572c

File tree

5 files changed

+83
-6
lines changed

5 files changed

+83
-6
lines changed

cmake/RuntimeConfig.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ set(VARIABLE_LAYOUT 9)
3737
set(RANGEMAP_LAYOUT 10)
3838
set(SETITER_LAYOUT 11)
3939
set(MAPITER_LAYOUT 12)
40+
set(MINT_LAYOUT 13)
4041

4142
get_filename_component(INSTALL_DIR_ABS_PATH "${CMAKE_INSTALL_PREFIX}"
4243
REALPATH BASE_DIR "${CMAKE_BINARY_DIR}")

config/macros.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#define RANGEMAP_LAYOUT @RANGEMAP_LAYOUT@
2828
#define SETITER_LAYOUT @SETITER_LAYOUT@
2929
#define MAPITER_LAYOUT @MAPITER_LAYOUT@
30+
#define MINT_LAYOUT @MINT_LAYOUT@
3031

3132
#define STRINGIFY(x) #x
3233
#define TOSTRING(X) STRINGIFY(X)

lib/codegen/CreateTerm.cpp

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -565,13 +565,65 @@ llvm::Value *create_term::create_hook(
565565
}
566566
return result;
567567
}
568+
if (name == "MINT.round") {
569+
llvm::Value *in = alloc_arg(pattern, 0, true, location_stack);
570+
auto *type_in = llvm::dyn_cast<llvm::IntegerType>(in->getType());
571+
assert(type_in);
572+
unsigned bits_in = type_in->getBitWidth();
573+
value_type cat_out = dynamic_cast<kore_composite_sort *>(
574+
pattern->get_constructor()->get_sort().get())
575+
->get_category(definition_);
576+
unsigned bits_out = cat_out.bits;
577+
auto *type_out = llvm::IntegerType::get(ctx_, bits_out);
578+
if (bits_in == bits_out) {
579+
// no-op
580+
return in;
581+
}
582+
if (bits_in < bits_out) {
583+
return new llvm::ZExtInst(in, type_out, "zext", current_block_);
584+
}
585+
return new llvm::TruncInst(in, type_out, "trunc", current_block_);
586+
}
587+
if (name == "MINT.sext") {
588+
llvm::Value *in = alloc_arg(pattern, 0, true, location_stack);
589+
auto *type_in = llvm::dyn_cast<llvm::IntegerType>(in->getType());
590+
assert(type_in);
591+
unsigned bits_in = type_in->getBitWidth();
592+
value_type cat_out = dynamic_cast<kore_composite_sort *>(
593+
pattern->get_constructor()->get_sort().get())
594+
->get_category(definition_);
595+
unsigned bits_out = cat_out.bits;
596+
auto *type_out = llvm::IntegerType::get(ctx_, bits_out);
597+
if (bits_in == bits_out) {
598+
// no-op
599+
return in;
600+
}
601+
if (bits_in < bits_out) {
602+
return new llvm::SExtInst(in, type_out, "sext", current_block_);
603+
}
604+
return new llvm::TruncInst(in, type_out, "trunc", current_block_);
605+
}
568606
if (name == "MINT.neg") {
569607
llvm::Value *in = alloc_arg(pattern, 0, true, location_stack);
570608
return llvm::BinaryOperator::CreateNeg(in, "hook_MINT_neg", current_block_);
571609
}
572610
if (name == "MINT.not") {
573611
llvm::Value *in = alloc_arg(pattern, 0, true, location_stack);
574612
return llvm::BinaryOperator::CreateNot(in, "hook_MINT_not", current_block_);
613+
#define MINT_MINMAX(hookname, inst) \
614+
} \
615+
if (name == "MINT." #hookname) { \
616+
llvm::Value *first = alloc_arg(pattern, 0, true, location_stack); \
617+
llvm::Value *second = alloc_arg(pattern, 1, true, location_stack); \
618+
auto *cmp = new llvm::ICmpInst( \
619+
*current_block_, llvm::CmpInst::inst, first, second, \
620+
"cmp_" #hookname); \
621+
return llvm::SelectInst::Create( \
622+
cmp, first, second, "hook_MINT_" #hookname, current_block_)
623+
MINT_MINMAX(umin, ICMP_ULE);
624+
MINT_MINMAX(umax, ICMP_UGE);
625+
MINT_MINMAX(smin, ICMP_SLE);
626+
MINT_MINMAX(smax, ICMP_SGE);
575627
#define MINT_CMP(hookname, inst) \
576628
} \
577629
if (name == "MINT." #hookname) { \

runtime/collections/kelemle.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,25 @@ bool hook_KEQUAL_eq(block *arg1, block *arg2) {
125125
}
126126
break;
127127
}
128+
case MINT_LAYOUT + 32: {
129+
auto *child1ptr = (int32_t *)(child1intptr);
130+
auto *child2ptr = (int32_t *)(child2intptr);
131+
bool cmp = *child1ptr == *child2ptr;
132+
if (!cmp) {
133+
return false;
134+
}
135+
break;
136+
}
137+
case MINT_LAYOUT + 64: {
138+
auto *child1ptr = (int64_t *)(child1intptr);
139+
auto *child2ptr = (int64_t *)(child2intptr);
140+
bool cmp = *child1ptr == *child2ptr;
141+
if (!cmp) {
142+
return false;
143+
}
144+
break;
145+
}
146+
128147
default: abort();
129148
}
130149
}

runtime/collections/lists.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -113,19 +113,23 @@ list hook_LIST_make(SortInt len, SortKItem value) {
113113
return {length, value};
114114
}
115115

116+
list hook_LIST_update_long(SortList list, size_t idx, SortKItem value) {
117+
if (idx >= list->size()) {
118+
KLLVM_HOOK_INVALID_ARGUMENT(
119+
"Index out of range for update: index={}, size={}", idx, list->size());
120+
}
121+
122+
return list->set(idx, value);
123+
}
124+
116125
list hook_LIST_update(SortList list, SortInt index, SortKItem value) {
117126
if (!mpz_fits_ulong_p(index)) {
118127
KLLVM_HOOK_INVALID_ARGUMENT(
119128
"Length is too large for update: {}", int_to_string(index));
120129
}
121130

122131
size_t idx = mpz_get_ui(index);
123-
if (idx >= list->size()) {
124-
KLLVM_HOOK_INVALID_ARGUMENT(
125-
"Index out of range for update: index={}, size={}", idx, list->size());
126-
}
127-
128-
return list->set(idx, value);
132+
return hook_LIST_update_long(list, idx, value);
129133
}
130134

131135
list hook_LIST_updateAll(SortList l1, SortInt index, SortList l2) {

0 commit comments

Comments
 (0)