Skip to content

record by aliasing group, unit tests for record/replay genext, add PtrToInt#44

Merged
can-lehmann merged 10 commits into
mainfrom
can-record-replay
Jun 3, 2026
Merged

record by aliasing group, unit tests for record/replay genext, add PtrToInt#44
can-lehmann merged 10 commits into
mainfrom
can-record-replay

Conversation

@can-lehmann

Copy link
Copy Markdown
Owner

No description provided.

@can-lehmann
can-lehmann marked this pull request as ready for review June 2, 2026 20:41
@github-actions

github-actions Bot commented Jun 2, 2026

Copy link
Copy Markdown

Coverage

File Lines Functions Regions Branches
genext.hpp 🔴 52.57% 🟡 76.60% 🔴 59.77% 🔴 59.32%
jitir.hpp 🔴 50.30% 🔴 58.59% 🔴 54.66% 🔴 54.03%
jitir_llvmapi.hpp 🔴 56.26% 🔴 66.67% 🟢 92.86% 🔴 66.67%
llvmgen.hpp 🔴 60.57% 🟡 70.00% 🟡 76.24% 🟡 75.89%
lowerllvm.hpp 🔴 63.60% 🟡 75.00% 🔴 41.32% 🔴 56.49%
x86gen.hpp 🟡 74.12% 🟡 81.82% 🟡 75.78% 🟡 83.30%
x86insts.inc.hpp - - - -
TOTAL 🔴 55.41% 🔴 63.29% 🔴 62.67% 🔴 63.74%
Diff Coverage

Diff Coverage

Diff: origin/main...HEAD, staged and unstaged changes

  • genext.hpp (8.0%): Missing lines 26-28,42,45,57,66-67,102-103,905-906,909-912,1412,1417-1422

Summary

  • Total: 25 lines
  • Missing: 23 lines
  • Coverage: 8%

genext.hpp

Lines 22-32

  22     struct Config {
  23       std::set<AliasingGroup> groups;
  24       size_t min_align = 1;
  25 
! 26       bool has(AliasingGroup group) const {
! 27         return groups.find(group) != groups.end();
! 28       }
  29     };
  30   private:
  31     Section* _section;
  32     Builder _builder;

Lines 38-49

  38       
  39       for (Block* block : *_section) {
  40         for (Inst* inst : *block) {
  41           if (dynmatch(LoadInst, load, inst)) {
! 42             if (_config.has(load->aliasing())) {
  43               _builder.move_after(block, inst);
  44       
! 45               Value* aligned_ptr = build_tape_advance(_builder, tape_ptr, _config.min_align, load->type());
  46               _builder.build_store(aligned_ptr, load, AliasingGroup(0), 0);
  47             }
  48           }
  49         }

Lines 53-61

  53     AddRecord(Section* section, Config config):
  54         Pass(section),
  55         _section(section),
  56         _builder(section),
! 57         _config(config) {
  58       
  59       apply();
  60     }

Lines 62-71

  62     AddRecord(Section* section, size_t& max_write_size, Config config):
  63         Pass(section),
  64         _section(section),
  65         _builder(section),
! 66         _config(config) {
! 67 
  68       apply();
  69 
  70       max_write_size = this->max_write_size();
  71     }

Lines 98-107

   98       for (Block* block : *_section) {
   99         size_t size = max_entry_sizes[block];
  100         for (Inst* inst : *block) {
  101           if (dynmatch(LoadInst, load, inst)) {
! 102             if (_config.has(load->aliasing())) {
! 103               size_t load_size = std::max(_config.min_align, type_size(load->type()));
  104               if (size % load_size != 0) {
  105                 size += load_size - (size % load_size);
  106               }
  107               size += load_size;

Lines 901-916

  901 
  902     Value* emit_inst(Inst* inst) {
  903       if (_config.record.has_value()) {
  904         if (dynmatch(LoadInst, load, inst)) {
! 905           if (_config.record->has(load->aliasing())) {
! 906             Value* aligned_ptr = AddRecord::build_tape_advance(_builder, _tape_ptr, _config.record->min_align, load->type());
  907             return _builder.build_load(aligned_ptr, load->type(), LoadFlags::None, AliasingGroup(0), 0);
  908           }
! 909         } else if (dynmatch(StoreInst, store, inst)) {
! 910           if (_config.record->has(store->aliasing())) {
! 911             return nullptr;
! 912           }
  913         }
  914       }
  915       return Clone::clone(inst, _builder, _blocks, _values);
  916     }

Lines 1408-1426

  1408       for (Arg* arg : section->entry()->args()) {
  1409         entry_arg_types.push_back(arg->type());
  1410       }
  1411       entry_arg_types.push_back(Type::Ptr);
! 1412       if (_config.record.has_value()) {
  1413         entry_arg_types.push_back(Type::Ptr);
  1414       }
  1415       _builder.move_to_end(_builder.build_block(entry_arg_types));
  1416 
! 1417       size_t builder_index = _section->entry()->args().size();
! 1418       _jitir_builder = _genext_section->entry()->arg(builder_index);
! 1419       if (_config.record.has_value()) {
! 1420         _tape_ptr = _genext_section->entry()->arg(builder_index + 1);
! 1421       }
! 1422 
  1423       for (Block* block : *section) {
  1424         std::vector<Type> arg_types;
  1425         for (Arg* arg : block->args()) {
  1426           arg_types.push_back(arg->type()); // values

@github-actions

github-actions Bot commented Jun 2, 2026

Copy link
Copy Markdown

Coverage

File Lines Functions Regions Branches
genext.hpp 🔴 52.53% 🟡 76.60% 🔴 59.77% 🔴 59.32%
jitir.hpp 🔴 50.30% 🔴 58.59% 🔴 54.66% 🔴 54.03%
jitir_llvmapi.hpp 🔴 56.26% 🔴 66.67% 🟢 92.86% 🔴 66.67%
llvmgen.hpp 🔴 60.57% 🟡 70.00% 🟡 76.24% 🟡 75.89%
lowerllvm.hpp 🔴 63.60% 🟡 75.00% 🔴 41.32% 🔴 56.49%
x86gen.hpp 🟡 74.12% 🟡 81.82% 🟡 75.78% 🟡 83.30%
x86insts.inc.hpp - - - -
TOTAL 🔴 55.41% 🔴 63.29% 🔴 62.67% 🔴 63.74%
Diff Coverage

Diff Coverage

Diff: origin/main...HEAD, staged and unstaged changes

  • genext.hpp (6.9%): Missing lines 26-28,40,42,44-46,57,66-67,102-103,119,906-907,910-913,1413,1418-1423

Summary

  • Total: 29 lines
  • Missing: 27 lines
  • Coverage: 6%

genext.hpp

Lines 22-32

  22     struct Config {
  23       std::set<AliasingGroup> groups;
  24       size_t min_align = 1;
  25 
! 26       bool has(AliasingGroup group) const {
! 27         return groups.find(group) != groups.end();
! 28       }
  29     };
  30   private:
  31     Section* _section;
  32     Builder _builder;

Lines 36-50

  36       Arg* tape_ptr = _builder.alloc_arg(Type::Ptr, _section->entry()->args().size());
  37       _builder.add_args_to_block(_section->entry(), {tape_ptr});
  38       
  39       for (Block* block : *_section) {
! 40         for (Inst* inst = *block->begin(); inst; inst = inst->next()) {
  41           if (dynmatch(LoadInst, load, inst)) {
! 42             if (_config.has(load->aliasing())) {
  43               _builder.move_after(block, inst);
! 44 
! 45               Value* aligned_ptr = build_tape_advance(_builder, tape_ptr, _config.min_align, load->type());
! 46               inst = _builder.build_store(aligned_ptr, load, AliasingGroup(0), 0);
  47             }
  48           }
  49         }
  50       }

Lines 53-61

  53     AddRecord(Section* section, Config config):
  54         Pass(section),
  55         _section(section),
  56         _builder(section),
! 57         _config(config) {
  58       
  59       apply();
  60     }

Lines 62-71

  62     AddRecord(Section* section, size_t& max_write_size, Config config):
  63         Pass(section),
  64         _section(section),
  65         _builder(section),
! 66         _config(config) {
! 67 
  68       apply();
  69 
  70       max_write_size = this->max_write_size();
  71     }

Lines 98-107

   98       for (Block* block : *_section) {
   99         size_t size = max_entry_sizes[block];
  100         for (Inst* inst : *block) {
  101           if (dynmatch(LoadInst, load, inst)) {
! 102             if (_config.has(load->aliasing())) {
! 103               size_t load_size = std::max(_config.min_align, type_size(load->type()));
  104               if (size % load_size != 0) {
  105                 size += load_size - (size % load_size);
  106               }
  107               size += load_size;

Lines 115-123

  115 
  116         max_size = std::max(max_size, size);
  117       }
  118 
! 119       assert(max_size % _config.min_align == 0);
  120       return max_size;
  121     }
  122   };

Lines 902-917

  902 
  903     Value* emit_inst(Inst* inst) {
  904       if (_config.record.has_value()) {
  905         if (dynmatch(LoadInst, load, inst)) {
! 906           if (_config.record->has(load->aliasing())) {
! 907             Value* aligned_ptr = AddRecord::build_tape_advance(_builder, _tape_ptr, _config.record->min_align, load->type());
  908             return _builder.build_load(aligned_ptr, load->type(), LoadFlags::None, AliasingGroup(0), 0);
  909           }
! 910         } else if (dynmatch(StoreInst, store, inst)) {
! 911           if (_config.record->has(store->aliasing())) {
! 912             return nullptr;
! 913           }
  914         }
  915       }
  916       return Clone::clone(inst, _builder, _blocks, _values);
  917     }

Lines 1409-1427

  1409       for (Arg* arg : section->entry()->args()) {
  1410         entry_arg_types.push_back(arg->type());
  1411       }
  1412       entry_arg_types.push_back(Type::Ptr);
! 1413       if (_config.record.has_value()) {
  1414         entry_arg_types.push_back(Type::Ptr);
  1415       }
  1416       _builder.move_to_end(_builder.build_block(entry_arg_types));
  1417 
! 1418       size_t builder_index = _section->entry()->args().size();
! 1419       _jitir_builder = _genext_section->entry()->arg(builder_index);
! 1420       if (_config.record.has_value()) {
! 1421         _tape_ptr = _genext_section->entry()->arg(builder_index + 1);
! 1422       }
! 1423 
  1424       for (Block* block : *section) {
  1425         std::vector<Type> arg_types;
  1426         for (Arg* arg : block->args()) {
  1427           arg_types.push_back(arg->type()); // values

@can-lehmann can-lehmann changed the title record by aliasing group record by aliasing group, unit tests for record/replay genext, add PtrToInt Jun 2, 2026
@github-actions

github-actions Bot commented Jun 2, 2026

Copy link
Copy Markdown

Coverage

File Lines Functions Regions Branches
genext.hpp 🔴 54.58% 🟡 85.11% 🟡 76.59% 🟡 77.19%
jitir.hpp 🔴 49.18% 🔴 59.29% 🔴 54.41% 🔴 53.67%
jitir_llvmapi.hpp 🔴 56.19% 🔴 66.67% 🟢 92.98% 🔴 66.67%
llvmgen.hpp 🔴 62.94% 🟡 70.00% 🟡 76.55% 🟡 76.32%
lowerllvm.hpp 🔴 63.60% 🟡 75.00% 🔴 41.32% 🔴 56.49%
x86gen.hpp 🟡 74.12% 🟡 81.82% 🟡 75.78% 🟡 83.30%
x86insts.inc.hpp - - - -
TOTAL 🔴 54.97% 🔴 64.15% 🔴 63.40% 🔴 64.72%
Diff Coverage

Diff Coverage

Diff: origin/main...HEAD, staged and unstaged changes

  • genext.hpp (57.9%): Missing lines 57,562-569,1423,1428-1433
  • jitir.hpp (41.8%): Missing lines 1419-1444,4782-4784,5238-5244,6350-6353,6521-6522,8544-8547
  • jitir_llvmapi.hpp (52.6%): Missing lines 636-644
  • llvmgen.hpp (100%)

Summary

  • Total: 141 lines
  • Missing: 71 lines
  • Coverage: 49%

genext.hpp

Lines 53-61

  53     AddRecord(Section* section, Config config):
  54         Pass(section),
  55         _section(section),
  56         _builder(section),
! 57         _config(config) {
  58       
  59       apply();
  60     }

Lines 558-573

  558     build_args.push_back(builder.build_const(Type::Int32, (uint64_t)i->type()));
  559     Value* built = builder.build_call(syms.build_float_to_int_s, Type::Ptr, build_args);
  560     return built;
  561   }
! 562   if (PtrToIntInst* i = dynamic_cast<PtrToIntInst*>(inst)) {
! 563     std::vector<Value*> build_args;
! 564     build_args.push_back(jitir_builder);
! 565     build_args.push_back(args[0]);
! 566     build_args.push_back(builder.build_const(Type::Int32, (uint64_t)i->type()));
! 567     Value* built = builder.build_call(syms.build_ptr_to_int, Type::Ptr, build_args);
! 568     return built;
! 569   }
  570   if (LoadInst* i = dynamic_cast<LoadInst*>(inst)) {
  571     std::vector<Value*> build_args;
  572     build_args.push_back(jitir_builder);
  573     build_args.push_back(args[0]);

Lines 1419-1437

  1419       for (Arg* arg : section->entry()->args()) {
  1420         entry_arg_types.push_back(arg->type());
  1421       }
  1422       entry_arg_types.push_back(Type::Ptr);
! 1423       if (_config.record.has_value()) {
  1424         entry_arg_types.push_back(Type::Ptr);
  1425       }
  1426       _builder.move_to_end(_builder.build_block(entry_arg_types));
  1427 
! 1428       size_t builder_index = _section->entry()->args().size();
! 1429       _jitir_builder = _genext_section->entry()->arg(builder_index);
! 1430       if (_config.record.has_value()) {
! 1431         _tape_ptr = _genext_section->entry()->arg(builder_index + 1);
! 1432       }
! 1433 
  1434       for (Block* block : *section) {
  1435         std::vector<Type> arg_types;
  1436         for (Arg* arg : block->args()) {
  1437           arg_types.push_back(arg->type()); // values

jitir.hpp

Lines 1415-1448

  1415     write_args(stream, is_first);
  1416     if (!is_first) { stream << ", "; } else { is_first = false; }
  1417     stream << Highlight::ArgName << "type=" << Highlight::None; stream << Highlight::Type << _type << Highlight::None;;
  1418   }
! 1419   void write_json(std::ostream& stream) const override {
! 1420     stream << "{";
! 1421     stream << "\"kind\": ";
! 1422     stream << "\"PtrToInt\"";
! 1423     stream << ", ";
! 1424     stream << "\"args\": ";
! 1425     write_args_json(stream);
! 1426     stream << ", ";
! 1427     stream << "\"name\": ";
! 1428     stream << name();
! 1429     stream << ", ";
! 1430     stream << "\"type\": ";
! 1431     stream << "\"" << _type << "\"";
! 1432     stream << "}";
! 1433   }  bool equals(const Value* other) const override {
! 1434     if (this == other) { return true; }
! 1435     if (other == nullptr) { return false; }
! 1436     if (typeid(*this) != typeid(*other)) { return false; }
! 1437     const PtrToIntInst* other_inst = (const PtrToIntInst*) other;
! 1438     if (arg_count() != other_inst->arg_count()) { return false; }
! 1439     for (size_t it = 0; it < arg_count(); it++) {
! 1440       if (arg(it) != other_inst->arg(it)) { return false; }
! 1441     }
! 1442     if (_type != other_inst->_type) { return false; }
! 1443     return true;
! 1444   }
  1445   size_t hash() const override {
  1446     size_t hash = 1926102241188748124ULL;
  1447     hash ^= std::hash<size_t>()(arg_count());
  1448     for (size_t it = 0; it < arg_count(); it++) {

Lines 4778-4788

  4778 }
  4779 void* jitir_build_float_to_int_s(void* builder, void* a, uint32_t type) {
  4780   return (void*)((::metajit::TraceBuilder*)builder)->build_float_to_int_s((Value*) a, (Type) type);
  4781 }
! 4782 void* jitir_build_ptr_to_int(void* builder, void* a, uint32_t type) {
! 4783   return (void*)((::metajit::TraceBuilder*)builder)->build_ptr_to_int((Value*) a, (Type) type);
! 4784 }
  4785 void* jitir_build_load(void* builder, void* ptr, uint32_t type, uint32_t flags, uint32_t aliasing, uint64_t offset) {
  4786   return (void*)((::metajit::TraceBuilder*)builder)->build_load((Value*) ptr, (Type) type, (LoadFlags) flags, (AliasingGroup) aliasing, (uint64_t) offset);
  4787 }
  4788 void* jitir_build_store(void* builder, void* ptr, void* value, uint32_t aliasing, uint64_t offset) {

Lines 5234-5248

  5234     Type type = read_type();
  5235     return _builder.build_float_to_int_s(a, type)
  5236 ;
  5237   } else if (opcode == "PtrToInt") {
! 5238     Value* a = read_value_arg();
! 5239     expect_char(','); skip_whitespace();
! 5240     expect_word("type");
! 5241     expect_char('=');
! 5242     Type type = read_type();
! 5243     return _builder.build_ptr_to_int(a, type)
! 5244 ;
  5245   } else if (opcode == "Load") {
  5246     Value* ptr = read_value_arg();
  5247     expect_char(','); skip_whitespace();
  5248     expect_word("type");

Lines 6346-6357

  6346           return b;
  6347         }
  6348       }
  6349 
! 6350       Bits ptr_to_int(Type to) const {
! 6351         assert(type == Type::Ptr);
! 6352         return Bits::constant(to, value);
! 6353       }
  6354 
  6355       void store(uint8_t* ptr) {
  6356         assert(!is_poison);
  6357         switch (type_size(type)) {

Lines 6517-6526

  6517       } else if (dynmatch(ResizeXInst, resize_x, _inst)) {
  6518         Bits a = at(resize_x->arg(0));
  6519         _values[_inst] = a.resize_x(resize_x->type());
  6520       } else if (dynmatch(PtrToIntInst, ptr_to_int, _inst)) {
! 6521         Bits a = at(ptr_to_int->arg(0));
! 6522         _values[_inst] = a.ptr_to_int(ptr_to_int->type());
  6523       } else if (dynmatch(FreezeInst, freeze, _inst)) {
  6524         Bits a = at(freeze->arg(0));
  6525         // Poison is refined to a non-poison value, we choose zero in this case
  6526         if (a.is_poison) {

Lines 8540-8551

  8540 if (dynamic_cast<FloatToIntSInst*>(inst)) {
  8541   FloatToIntSInst* clone = builder.build_float_to_int_s(clone_arg(inst->arg(0), builder, values), ((FloatToIntSInst*) inst)->type());
  8542   return clone;
  8543 }
! 8544 if (dynamic_cast<PtrToIntInst*>(inst)) {
! 8545   PtrToIntInst* clone = builder.build_ptr_to_int(clone_arg(inst->arg(0), builder, values), ((PtrToIntInst*) inst)->type());
! 8546   return clone;
! 8547 }
  8548 if (dynamic_cast<LoadInst*>(inst)) {
  8549   LoadInst* clone = builder.build_load(clone_arg(inst->arg(0), builder, values), ((LoadInst*) inst)->type(), ((LoadInst*) inst)->flags(), ((LoadInst*) inst)->aliasing(), ((LoadInst*) inst)->offset());
  8550   return clone;
  8551 }

jitir_llvmapi.hpp

Lines 632-648

  632     assert(build_args.size() == 3);
  633     llvm::Value* built = builder.CreateCall(api.build_float_to_int_s, build_args);
  634     return built;
  635   }
! 636   if (PtrToIntInst* i = dynamic_cast<PtrToIntInst*>(inst)) {
! 637     std::vector<llvm::Value*> build_args;
! 638     build_args.push_back(jitir_builder);
! 639     build_args.push_back(args[0]);
! 640     build_args.push_back(llvm::ConstantInt::get(llvm::Type::getInt32Ty(context), (uint64_t)i->type(), false));
! 641     assert(build_args.size() == 3);
! 642     llvm::Value* built = builder.CreateCall(api.build_ptr_to_int, build_args);
! 643     return built;
! 644   }
  645   if (LoadInst* i = dynamic_cast<LoadInst*>(inst)) {
  646     std::vector<llvm::Value*> build_args;
  647     build_args.push_back(jitir_builder);
  648     build_args.push_back(args[0]);

@github-actions

github-actions Bot commented Jun 2, 2026

Copy link
Copy Markdown

Coverage

File Lines Functions Regions Branches
genext.hpp 🔴 54.32% 🟡 83.33% 🟡 76.14% 🟡 76.81%
jitir.hpp 🔴 49.18% 🔴 59.29% 🔴 54.41% 🔴 53.67%
jitir_llvmapi.hpp 🔴 56.19% 🔴 66.67% 🟢 92.98% 🔴 66.67%
llvmgen.hpp 🔴 62.94% 🟡 70.00% 🟡 76.55% 🟡 76.32%
lowerllvm.hpp 🔴 63.60% 🟡 75.00% 🔴 41.32% 🔴 56.49%
x86gen.hpp 🟡 74.12% 🟡 81.82% 🟡 75.78% 🟡 83.30%
x86insts.inc.hpp - - - -
TOTAL 🔴 54.95% 🔴 64.10% 🔴 63.38% 🔴 64.70%
Diff Coverage

Diff Coverage

Diff: origin/main...HEAD, staged and unstaged changes

  • genext.hpp (64.5%): Missing lines 49-50,57-58,88,90,126,567-574,1428,1433-1438
  • jitir.hpp (41.8%): Missing lines 1419-1444,4782-4784,5238-5244,6350-6353,6521-6522,8544-8547
  • jitir_llvmapi.hpp (52.6%): Missing lines 636-644
  • llvmgen.hpp (100%)

Summary

  • Total: 165 lines
  • Missing: 77 lines
  • Coverage: 53%

genext.hpp

Lines 45-54

  45           if (dynmatch(LoadInst, load, inst)) {
  46             if (_config.has(load->aliasing())) {
  47               size_t load_size = std::max(_config.min_align, type_size(load->type()));
  48               if (size % load_size != 0) {
! 49                 size += load_size - (size % load_size);
! 50               }
  51               size += load_size;
  52             }
  53           }
  54         }

Lines 53-62

  53           }
  54         }
  55 
  56         for (Block* succ : block->successors()) {
! 57           max_entry_sizes[succ] = std::max(max_entry_sizes[succ], size);
! 58         }
  59 
  60         _max_write_size = std::max(_max_write_size, size);
  61       }

Lines 84-94

  84     AddRecord(Section* section, Config config):
  85         Pass(section),
  86         _section(section),
  87         _builder(section),
! 88         _config(config) {
  89       
! 90       find_max_write_size();
  91       apply();
  92     }
  93 
  94     AddRecord(Section* section, size_t* max_write_size, Config config):

Lines 122-130

  122 
  123       return aligned_ptr;
  124     }
  125 
! 126     size_t max_write_size() const { return _max_write_size; }
  127   };
  128 
  129   // Codegen for the generating extension uses topological sorting.
  130   // Cycles are broken by selecting an overapproximation.

Lines 563-578

  563     build_args.push_back(builder.build_const(Type::Int32, (uint64_t)i->type()));
  564     Value* built = builder.build_call(syms.build_float_to_int_s, Type::Ptr, build_args);
  565     return built;
  566   }
! 567   if (PtrToIntInst* i = dynamic_cast<PtrToIntInst*>(inst)) {
! 568     std::vector<Value*> build_args;
! 569     build_args.push_back(jitir_builder);
! 570     build_args.push_back(args[0]);
! 571     build_args.push_back(builder.build_const(Type::Int32, (uint64_t)i->type()));
! 572     Value* built = builder.build_call(syms.build_ptr_to_int, Type::Ptr, build_args);
! 573     return built;
! 574   }
  575   if (LoadInst* i = dynamic_cast<LoadInst*>(inst)) {
  576     std::vector<Value*> build_args;
  577     build_args.push_back(jitir_builder);
  578     build_args.push_back(args[0]);

Lines 1424-1442

  1424       for (Arg* arg : section->entry()->args()) {
  1425         entry_arg_types.push_back(arg->type());
  1426       }
  1427       entry_arg_types.push_back(Type::Ptr);
! 1428       if (_config.record.has_value()) {
  1429         entry_arg_types.push_back(Type::Ptr);
  1430       }
  1431       _builder.move_to_end(_builder.build_block(entry_arg_types));
  1432 
! 1433       size_t builder_index = _section->entry()->args().size();
! 1434       _jitir_builder = _genext_section->entry()->arg(builder_index);
! 1435       if (_config.record.has_value()) {
! 1436         _tape_ptr = _genext_section->entry()->arg(builder_index + 1);
! 1437       }
! 1438 
  1439       for (Block* block : *section) {
  1440         std::vector<Type> arg_types;
  1441         for (Arg* arg : block->args()) {
  1442           arg_types.push_back(arg->type()); // values

jitir.hpp

Lines 1415-1448

  1415     write_args(stream, is_first);
  1416     if (!is_first) { stream << ", "; } else { is_first = false; }
  1417     stream << Highlight::ArgName << "type=" << Highlight::None; stream << Highlight::Type << _type << Highlight::None;;
  1418   }
! 1419   void write_json(std::ostream& stream) const override {
! 1420     stream << "{";
! 1421     stream << "\"kind\": ";
! 1422     stream << "\"PtrToInt\"";
! 1423     stream << ", ";
! 1424     stream << "\"args\": ";
! 1425     write_args_json(stream);
! 1426     stream << ", ";
! 1427     stream << "\"name\": ";
! 1428     stream << name();
! 1429     stream << ", ";
! 1430     stream << "\"type\": ";
! 1431     stream << "\"" << _type << "\"";
! 1432     stream << "}";
! 1433   }  bool equals(const Value* other) const override {
! 1434     if (this == other) { return true; }
! 1435     if (other == nullptr) { return false; }
! 1436     if (typeid(*this) != typeid(*other)) { return false; }
! 1437     const PtrToIntInst* other_inst = (const PtrToIntInst*) other;
! 1438     if (arg_count() != other_inst->arg_count()) { return false; }
! 1439     for (size_t it = 0; it < arg_count(); it++) {
! 1440       if (arg(it) != other_inst->arg(it)) { return false; }
! 1441     }
! 1442     if (_type != other_inst->_type) { return false; }
! 1443     return true;
! 1444   }
  1445   size_t hash() const override {
  1446     size_t hash = 1926102241188748124ULL;
  1447     hash ^= std::hash<size_t>()(arg_count());
  1448     for (size_t it = 0; it < arg_count(); it++) {

Lines 4778-4788

  4778 }
  4779 void* jitir_build_float_to_int_s(void* builder, void* a, uint32_t type) {
  4780   return (void*)((::metajit::TraceBuilder*)builder)->build_float_to_int_s((Value*) a, (Type) type);
  4781 }
! 4782 void* jitir_build_ptr_to_int(void* builder, void* a, uint32_t type) {
! 4783   return (void*)((::metajit::TraceBuilder*)builder)->build_ptr_to_int((Value*) a, (Type) type);
! 4784 }
  4785 void* jitir_build_load(void* builder, void* ptr, uint32_t type, uint32_t flags, uint32_t aliasing, uint64_t offset) {
  4786   return (void*)((::metajit::TraceBuilder*)builder)->build_load((Value*) ptr, (Type) type, (LoadFlags) flags, (AliasingGroup) aliasing, (uint64_t) offset);
  4787 }
  4788 void* jitir_build_store(void* builder, void* ptr, void* value, uint32_t aliasing, uint64_t offset) {

Lines 5234-5248

  5234     Type type = read_type();
  5235     return _builder.build_float_to_int_s(a, type)
  5236 ;
  5237   } else if (opcode == "PtrToInt") {
! 5238     Value* a = read_value_arg();
! 5239     expect_char(','); skip_whitespace();
! 5240     expect_word("type");
! 5241     expect_char('=');
! 5242     Type type = read_type();
! 5243     return _builder.build_ptr_to_int(a, type)
! 5244 ;
  5245   } else if (opcode == "Load") {
  5246     Value* ptr = read_value_arg();
  5247     expect_char(','); skip_whitespace();
  5248     expect_word("type");

Lines 6346-6357

  6346           return b;
  6347         }
  6348       }
  6349 
! 6350       Bits ptr_to_int(Type to) const {
! 6351         assert(type == Type::Ptr);
! 6352         return Bits::constant(to, value);
! 6353       }
  6354 
  6355       void store(uint8_t* ptr) {
  6356         assert(!is_poison);
  6357         switch (type_size(type)) {

Lines 6517-6526

  6517       } else if (dynmatch(ResizeXInst, resize_x, _inst)) {
  6518         Bits a = at(resize_x->arg(0));
  6519         _values[_inst] = a.resize_x(resize_x->type());
  6520       } else if (dynmatch(PtrToIntInst, ptr_to_int, _inst)) {
! 6521         Bits a = at(ptr_to_int->arg(0));
! 6522         _values[_inst] = a.ptr_to_int(ptr_to_int->type());
  6523       } else if (dynmatch(FreezeInst, freeze, _inst)) {
  6524         Bits a = at(freeze->arg(0));
  6525         // Poison is refined to a non-poison value, we choose zero in this case
  6526         if (a.is_poison) {

Lines 8540-8551

  8540 if (dynamic_cast<FloatToIntSInst*>(inst)) {
  8541   FloatToIntSInst* clone = builder.build_float_to_int_s(clone_arg(inst->arg(0), builder, values), ((FloatToIntSInst*) inst)->type());
  8542   return clone;
  8543 }
! 8544 if (dynamic_cast<PtrToIntInst*>(inst)) {
! 8545   PtrToIntInst* clone = builder.build_ptr_to_int(clone_arg(inst->arg(0), builder, values), ((PtrToIntInst*) inst)->type());
! 8546   return clone;
! 8547 }
  8548 if (dynamic_cast<LoadInst*>(inst)) {
  8549   LoadInst* clone = builder.build_load(clone_arg(inst->arg(0), builder, values), ((LoadInst*) inst)->type(), ((LoadInst*) inst)->flags(), ((LoadInst*) inst)->aliasing(), ((LoadInst*) inst)->offset());
  8550   return clone;
  8551 }

jitir_llvmapi.hpp

Lines 632-648

  632     assert(build_args.size() == 3);
  633     llvm::Value* built = builder.CreateCall(api.build_float_to_int_s, build_args);
  634     return built;
  635   }
! 636   if (PtrToIntInst* i = dynamic_cast<PtrToIntInst*>(inst)) {
! 637     std::vector<llvm::Value*> build_args;
! 638     build_args.push_back(jitir_builder);
! 639     build_args.push_back(args[0]);
! 640     build_args.push_back(llvm::ConstantInt::get(llvm::Type::getInt32Ty(context), (uint64_t)i->type(), false));
! 641     assert(build_args.size() == 3);
! 642     llvm::Value* built = builder.CreateCall(api.build_ptr_to_int, build_args);
! 643     return built;
! 644   }
  645   if (LoadInst* i = dynamic_cast<LoadInst*>(inst)) {
  646     std::vector<llvm::Value*> build_args;
  647     build_args.push_back(jitir_builder);
  648     build_args.push_back(args[0]);

@github-actions

github-actions Bot commented Jun 2, 2026

Copy link
Copy Markdown

Coverage

File Lines Functions Regions Branches
genext.hpp 🔴 54.42% 🟡 83.33% 🟡 76.14% 🟡 76.81%
jitir.hpp 🔴 49.18% 🔴 59.29% 🔴 54.41% 🔴 53.67%
jitir_llvmapi.hpp 🔴 56.19% 🔴 66.67% 🟢 92.98% 🔴 66.67%
llvmgen.hpp 🔴 62.94% 🟡 70.00% 🟡 76.55% 🟡 76.32%
lowerllvm.hpp 🔴 63.60% 🟡 75.00% 🔴 41.32% 🔴 56.49%
x86gen.hpp 🟡 74.12% 🟡 81.82% 🟡 75.78% 🟡 83.30%
x86insts.inc.hpp - - - -
TOTAL 🔴 54.96% 🔴 64.10% 🔴 63.38% 🔴 64.70%
Diff Coverage

Diff Coverage

Diff: origin/main...HEAD, staged and unstaged changes

  • genext.hpp (66.2%): Missing lines 50-51,59-60,91,93,129,570-577,1431,1436-1441
  • jitir.hpp (41.8%): Missing lines 1419-1444,4782-4784,5238-5244,6350-6353,6521-6522,8544-8547
  • jitir_llvmapi.hpp (52.6%): Missing lines 636-644
  • llvmgen.hpp (100%)

Summary

  • Total: 168 lines
  • Missing: 77 lines
  • Coverage: 54%

genext.hpp

Lines 46-55

  46           if (dynmatch(LoadInst, load, inst)) {
  47             if (_config.has(load->aliasing())) {
  48               size_t load_size = std::max(_config.min_align, type_size(load->type()));
  49               if (size % load_size != 0) {
! 50                 size += load_size - (size % load_size);
! 51               }
  52               size += load_size;
  53               max_load_size = std::max(max_load_size, load_size);
  54             }
  55           }

Lines 55-64

  55           }
  56         }
  57 
  58         for (Block* succ : block->successors()) {
! 59           max_entry_sizes[succ] = std::max(max_entry_sizes[succ], size);
! 60         }
  61 
  62         _max_write_size = std::max(_max_write_size, size);
  63       }

Lines 87-97

  87     AddRecord(Section* section, Config config):
  88         Pass(section),
  89         _section(section),
  90         _builder(section),
! 91         _config(config) {
  92       
! 93       find_max_write_size();
  94       apply();
  95     }
  96 
  97     AddRecord(Section* section, size_t* max_write_size, Config config):

Lines 125-133

  125 
  126       return aligned_ptr;
  127     }
  128 
! 129     size_t max_write_size() const { return _max_write_size; }
  130   };
  131 
  132   // Codegen for the generating extension uses topological sorting.
  133   // Cycles are broken by selecting an overapproximation.

Lines 566-581

  566     build_args.push_back(builder.build_const(Type::Int32, (uint64_t)i->type()));
  567     Value* built = builder.build_call(syms.build_float_to_int_s, Type::Ptr, build_args);
  568     return built;
  569   }
! 570   if (PtrToIntInst* i = dynamic_cast<PtrToIntInst*>(inst)) {
! 571     std::vector<Value*> build_args;
! 572     build_args.push_back(jitir_builder);
! 573     build_args.push_back(args[0]);
! 574     build_args.push_back(builder.build_const(Type::Int32, (uint64_t)i->type()));
! 575     Value* built = builder.build_call(syms.build_ptr_to_int, Type::Ptr, build_args);
! 576     return built;
! 577   }
  578   if (LoadInst* i = dynamic_cast<LoadInst*>(inst)) {
  579     std::vector<Value*> build_args;
  580     build_args.push_back(jitir_builder);
  581     build_args.push_back(args[0]);

Lines 1427-1445

  1427       for (Arg* arg : section->entry()->args()) {
  1428         entry_arg_types.push_back(arg->type());
  1429       }
  1430       entry_arg_types.push_back(Type::Ptr);
! 1431       if (_config.record.has_value()) {
  1432         entry_arg_types.push_back(Type::Ptr);
  1433       }
  1434       _builder.move_to_end(_builder.build_block(entry_arg_types));
  1435 
! 1436       size_t builder_index = _section->entry()->args().size();
! 1437       _jitir_builder = _genext_section->entry()->arg(builder_index);
! 1438       if (_config.record.has_value()) {
! 1439         _tape_ptr = _genext_section->entry()->arg(builder_index + 1);
! 1440       }
! 1441 
  1442       for (Block* block : *section) {
  1443         std::vector<Type> arg_types;
  1444         for (Arg* arg : block->args()) {
  1445           arg_types.push_back(arg->type()); // values

jitir.hpp

Lines 1415-1448

  1415     write_args(stream, is_first);
  1416     if (!is_first) { stream << ", "; } else { is_first = false; }
  1417     stream << Highlight::ArgName << "type=" << Highlight::None; stream << Highlight::Type << _type << Highlight::None;;
  1418   }
! 1419   void write_json(std::ostream& stream) const override {
! 1420     stream << "{";
! 1421     stream << "\"kind\": ";
! 1422     stream << "\"PtrToInt\"";
! 1423     stream << ", ";
! 1424     stream << "\"args\": ";
! 1425     write_args_json(stream);
! 1426     stream << ", ";
! 1427     stream << "\"name\": ";
! 1428     stream << name();
! 1429     stream << ", ";
! 1430     stream << "\"type\": ";
! 1431     stream << "\"" << _type << "\"";
! 1432     stream << "}";
! 1433   }  bool equals(const Value* other) const override {
! 1434     if (this == other) { return true; }
! 1435     if (other == nullptr) { return false; }
! 1436     if (typeid(*this) != typeid(*other)) { return false; }
! 1437     const PtrToIntInst* other_inst = (const PtrToIntInst*) other;
! 1438     if (arg_count() != other_inst->arg_count()) { return false; }
! 1439     for (size_t it = 0; it < arg_count(); it++) {
! 1440       if (arg(it) != other_inst->arg(it)) { return false; }
! 1441     }
! 1442     if (_type != other_inst->_type) { return false; }
! 1443     return true;
! 1444   }
  1445   size_t hash() const override {
  1446     size_t hash = 1926102241188748124ULL;
  1447     hash ^= std::hash<size_t>()(arg_count());
  1448     for (size_t it = 0; it < arg_count(); it++) {

Lines 4778-4788

  4778 }
  4779 void* jitir_build_float_to_int_s(void* builder, void* a, uint32_t type) {
  4780   return (void*)((::metajit::TraceBuilder*)builder)->build_float_to_int_s((Value*) a, (Type) type);
  4781 }
! 4782 void* jitir_build_ptr_to_int(void* builder, void* a, uint32_t type) {
! 4783   return (void*)((::metajit::TraceBuilder*)builder)->build_ptr_to_int((Value*) a, (Type) type);
! 4784 }
  4785 void* jitir_build_load(void* builder, void* ptr, uint32_t type, uint32_t flags, uint32_t aliasing, uint64_t offset) {
  4786   return (void*)((::metajit::TraceBuilder*)builder)->build_load((Value*) ptr, (Type) type, (LoadFlags) flags, (AliasingGroup) aliasing, (uint64_t) offset);
  4787 }
  4788 void* jitir_build_store(void* builder, void* ptr, void* value, uint32_t aliasing, uint64_t offset) {

Lines 5234-5248

  5234     Type type = read_type();
  5235     return _builder.build_float_to_int_s(a, type)
  5236 ;
  5237   } else if (opcode == "PtrToInt") {
! 5238     Value* a = read_value_arg();
! 5239     expect_char(','); skip_whitespace();
! 5240     expect_word("type");
! 5241     expect_char('=');
! 5242     Type type = read_type();
! 5243     return _builder.build_ptr_to_int(a, type)
! 5244 ;
  5245   } else if (opcode == "Load") {
  5246     Value* ptr = read_value_arg();
  5247     expect_char(','); skip_whitespace();
  5248     expect_word("type");

Lines 6346-6357

  6346           return b;
  6347         }
  6348       }
  6349 
! 6350       Bits ptr_to_int(Type to) const {
! 6351         assert(type == Type::Ptr);
! 6352         return Bits::constant(to, value);
! 6353       }
  6354 
  6355       void store(uint8_t* ptr) {
  6356         assert(!is_poison);
  6357         switch (type_size(type)) {

Lines 6517-6526

  6517       } else if (dynmatch(ResizeXInst, resize_x, _inst)) {
  6518         Bits a = at(resize_x->arg(0));
  6519         _values[_inst] = a.resize_x(resize_x->type());
  6520       } else if (dynmatch(PtrToIntInst, ptr_to_int, _inst)) {
! 6521         Bits a = at(ptr_to_int->arg(0));
! 6522         _values[_inst] = a.ptr_to_int(ptr_to_int->type());
  6523       } else if (dynmatch(FreezeInst, freeze, _inst)) {
  6524         Bits a = at(freeze->arg(0));
  6525         // Poison is refined to a non-poison value, we choose zero in this case
  6526         if (a.is_poison) {

Lines 8540-8551

  8540 if (dynamic_cast<FloatToIntSInst*>(inst)) {
  8541   FloatToIntSInst* clone = builder.build_float_to_int_s(clone_arg(inst->arg(0), builder, values), ((FloatToIntSInst*) inst)->type());
  8542   return clone;
  8543 }
! 8544 if (dynamic_cast<PtrToIntInst*>(inst)) {
! 8545   PtrToIntInst* clone = builder.build_ptr_to_int(clone_arg(inst->arg(0), builder, values), ((PtrToIntInst*) inst)->type());
! 8546   return clone;
! 8547 }
  8548 if (dynamic_cast<LoadInst*>(inst)) {
  8549   LoadInst* clone = builder.build_load(clone_arg(inst->arg(0), builder, values), ((LoadInst*) inst)->type(), ((LoadInst*) inst)->flags(), ((LoadInst*) inst)->aliasing(), ((LoadInst*) inst)->offset());
  8550   return clone;
  8551 }

jitir_llvmapi.hpp

Lines 632-648

  632     assert(build_args.size() == 3);
  633     llvm::Value* built = builder.CreateCall(api.build_float_to_int_s, build_args);
  634     return built;
  635   }
! 636   if (PtrToIntInst* i = dynamic_cast<PtrToIntInst*>(inst)) {
! 637     std::vector<llvm::Value*> build_args;
! 638     build_args.push_back(jitir_builder);
! 639     build_args.push_back(args[0]);
! 640     build_args.push_back(llvm::ConstantInt::get(llvm::Type::getInt32Ty(context), (uint64_t)i->type(), false));
! 641     assert(build_args.size() == 3);
! 642     llvm::Value* built = builder.CreateCall(api.build_ptr_to_int, build_args);
! 643     return built;
! 644   }
  645   if (LoadInst* i = dynamic_cast<LoadInst*>(inst)) {
  646     std::vector<llvm::Value*> build_args;
  647     build_args.push_back(jitir_builder);
  648     build_args.push_back(args[0]);

@github-actions

github-actions Bot commented Jun 2, 2026

Copy link
Copy Markdown

Coverage

File Lines Functions Regions Branches
genext.hpp 🔴 54.42% 🟡 83.33% 🟡 76.14% 🟡 76.81%
jitir.hpp 🔴 49.23% 🔴 59.41% 🔴 54.64% 🔴 53.84%
jitir_llvmapi.hpp 🔴 56.19% 🔴 66.67% 🟢 92.98% 🔴 66.67%
llvmgen.hpp 🔴 62.94% 🟡 70.00% 🟡 76.55% 🟡 76.32%
lowerllvm.hpp 🔴 63.60% 🟡 75.00% 🔴 41.32% 🔴 56.49%
x86gen.hpp 🟡 74.12% 🟡 81.82% 🟡 75.78% 🟡 83.30%
x86insts.inc.hpp - - - -
TOTAL 🔴 54.98% 🔴 64.18% 🔴 63.50% 🔴 64.79%
Diff Coverage

Diff Coverage

Diff: origin/main...HEAD, staged and unstaged changes

  • genext.hpp (66.2%): Missing lines 50-51,59-60,91,93,129,570-577,1431,1436-1441
  • jitir.hpp (42.0%): Missing lines 1419-1444,4782-4784,5238-5244,6350-6353,6521-6522,6566,8546-8549
  • jitir_llvmapi.hpp (52.6%): Missing lines 636-644
  • llvmgen.hpp (100%)

Summary

  • Total: 170 lines
  • Missing: 78 lines
  • Coverage: 54%

genext.hpp

Lines 46-55

  46           if (dynmatch(LoadInst, load, inst)) {
  47             if (_config.has(load->aliasing())) {
  48               size_t load_size = std::max(_config.min_align, type_size(load->type()));
  49               if (size % load_size != 0) {
! 50                 size += load_size - (size % load_size);
! 51               }
  52               size += load_size;
  53               max_load_size = std::max(max_load_size, load_size);
  54             }
  55           }

Lines 55-64

  55           }
  56         }
  57 
  58         for (Block* succ : block->successors()) {
! 59           max_entry_sizes[succ] = std::max(max_entry_sizes[succ], size);
! 60         }
  61 
  62         _max_write_size = std::max(_max_write_size, size);
  63       }

Lines 87-97

  87     AddRecord(Section* section, Config config):
  88         Pass(section),
  89         _section(section),
  90         _builder(section),
! 91         _config(config) {
  92       
! 93       find_max_write_size();
  94       apply();
  95     }
  96 
  97     AddRecord(Section* section, size_t* max_write_size, Config config):

Lines 125-133

  125 
  126       return aligned_ptr;
  127     }
  128 
! 129     size_t max_write_size() const { return _max_write_size; }
  130   };
  131 
  132   // Codegen for the generating extension uses topological sorting.
  133   // Cycles are broken by selecting an overapproximation.

Lines 566-581

  566     build_args.push_back(builder.build_const(Type::Int32, (uint64_t)i->type()));
  567     Value* built = builder.build_call(syms.build_float_to_int_s, Type::Ptr, build_args);
  568     return built;
  569   }
! 570   if (PtrToIntInst* i = dynamic_cast<PtrToIntInst*>(inst)) {
! 571     std::vector<Value*> build_args;
! 572     build_args.push_back(jitir_builder);
! 573     build_args.push_back(args[0]);
! 574     build_args.push_back(builder.build_const(Type::Int32, (uint64_t)i->type()));
! 575     Value* built = builder.build_call(syms.build_ptr_to_int, Type::Ptr, build_args);
! 576     return built;
! 577   }
  578   if (LoadInst* i = dynamic_cast<LoadInst*>(inst)) {
  579     std::vector<Value*> build_args;
  580     build_args.push_back(jitir_builder);
  581     build_args.push_back(args[0]);

Lines 1427-1445

  1427       for (Arg* arg : section->entry()->args()) {
  1428         entry_arg_types.push_back(arg->type());
  1429       }
  1430       entry_arg_types.push_back(Type::Ptr);
! 1431       if (_config.record.has_value()) {
  1432         entry_arg_types.push_back(Type::Ptr);
  1433       }
  1434       _builder.move_to_end(_builder.build_block(entry_arg_types));
  1435 
! 1436       size_t builder_index = _section->entry()->args().size();
! 1437       _jitir_builder = _genext_section->entry()->arg(builder_index);
! 1438       if (_config.record.has_value()) {
! 1439         _tape_ptr = _genext_section->entry()->arg(builder_index + 1);
! 1440       }
! 1441 
  1442       for (Block* block : *section) {
  1443         std::vector<Type> arg_types;
  1444         for (Arg* arg : block->args()) {
  1445           arg_types.push_back(arg->type()); // values

jitir.hpp

Lines 1415-1448

  1415     write_args(stream, is_first);
  1416     if (!is_first) { stream << ", "; } else { is_first = false; }
  1417     stream << Highlight::ArgName << "type=" << Highlight::None; stream << Highlight::Type << _type << Highlight::None;;
  1418   }
! 1419   void write_json(std::ostream& stream) const override {
! 1420     stream << "{";
! 1421     stream << "\"kind\": ";
! 1422     stream << "\"PtrToInt\"";
! 1423     stream << ", ";
! 1424     stream << "\"args\": ";
! 1425     write_args_json(stream);
! 1426     stream << ", ";
! 1427     stream << "\"name\": ";
! 1428     stream << name();
! 1429     stream << ", ";
! 1430     stream << "\"type\": ";
! 1431     stream << "\"" << _type << "\"";
! 1432     stream << "}";
! 1433   }  bool equals(const Value* other) const override {
! 1434     if (this == other) { return true; }
! 1435     if (other == nullptr) { return false; }
! 1436     if (typeid(*this) != typeid(*other)) { return false; }
! 1437     const PtrToIntInst* other_inst = (const PtrToIntInst*) other;
! 1438     if (arg_count() != other_inst->arg_count()) { return false; }
! 1439     for (size_t it = 0; it < arg_count(); it++) {
! 1440       if (arg(it) != other_inst->arg(it)) { return false; }
! 1441     }
! 1442     if (_type != other_inst->_type) { return false; }
! 1443     return true;
! 1444   }
  1445   size_t hash() const override {
  1446     size_t hash = 1926102241188748124ULL;
  1447     hash ^= std::hash<size_t>()(arg_count());
  1448     for (size_t it = 0; it < arg_count(); it++) {

Lines 4778-4788

  4778 }
  4779 void* jitir_build_float_to_int_s(void* builder, void* a, uint32_t type) {
  4780   return (void*)((::metajit::TraceBuilder*)builder)->build_float_to_int_s((Value*) a, (Type) type);
  4781 }
! 4782 void* jitir_build_ptr_to_int(void* builder, void* a, uint32_t type) {
! 4783   return (void*)((::metajit::TraceBuilder*)builder)->build_ptr_to_int((Value*) a, (Type) type);
! 4784 }
  4785 void* jitir_build_load(void* builder, void* ptr, uint32_t type, uint32_t flags, uint32_t aliasing, uint64_t offset) {
  4786   return (void*)((::metajit::TraceBuilder*)builder)->build_load((Value*) ptr, (Type) type, (LoadFlags) flags, (AliasingGroup) aliasing, (uint64_t) offset);
  4787 }
  4788 void* jitir_build_store(void* builder, void* ptr, void* value, uint32_t aliasing, uint64_t offset) {

Lines 5234-5248

  5234     Type type = read_type();
  5235     return _builder.build_float_to_int_s(a, type)
  5236 ;
  5237   } else if (opcode == "PtrToInt") {
! 5238     Value* a = read_value_arg();
! 5239     expect_char(','); skip_whitespace();
! 5240     expect_word("type");
! 5241     expect_char('=');
! 5242     Type type = read_type();
! 5243     return _builder.build_ptr_to_int(a, type)
! 5244 ;
  5245   } else if (opcode == "Load") {
  5246     Value* ptr = read_value_arg();
  5247     expect_char(','); skip_whitespace();
  5248     expect_word("type");

Lines 6346-6357

  6346           return b;
  6347         }
  6348       }
  6349 
! 6350       Bits ptr_to_int(Type to) const {
! 6351         assert(type == Type::Ptr);
! 6352         return Bits::constant(to, value);
! 6353       }
  6354 
  6355       void store(uint8_t* ptr) {
  6356         assert(!is_poison);
  6357         switch (type_size(type)) {

Lines 6517-6526

  6517       } else if (dynmatch(ResizeXInst, resize_x, _inst)) {
  6518         Bits a = at(resize_x->arg(0));
  6519         _values[_inst] = a.resize_x(resize_x->type());
  6520       } else if (dynmatch(PtrToIntInst, ptr_to_int, _inst)) {
! 6521         Bits a = at(ptr_to_int->arg(0));
! 6522         _values[_inst] = a.ptr_to_int(ptr_to_int->type());
  6523       } else if (dynmatch(FreezeInst, freeze, _inst)) {
  6524         Bits a = at(freeze->arg(0));
  6525         // Poison is refined to a non-poison value, we choose zero in this case
  6526         if (a.is_poison) {

Lines 6562-6570

  6562 
  6563       #undef binop
  6564     
  6565       else {
! 6566         assert(false && "Unsupported instruction in interpreter");
  6567       }
  6568 
  6569       _inst = _inst->next();
  6570       return Event::None;

Lines 8542-8553

  8542 if (dynamic_cast<FloatToIntSInst*>(inst)) {
  8543   FloatToIntSInst* clone = builder.build_float_to_int_s(clone_arg(inst->arg(0), builder, values), ((FloatToIntSInst*) inst)->type());
  8544   return clone;
  8545 }
! 8546 if (dynamic_cast<PtrToIntInst*>(inst)) {
! 8547   PtrToIntInst* clone = builder.build_ptr_to_int(clone_arg(inst->arg(0), builder, values), ((PtrToIntInst*) inst)->type());
! 8548   return clone;
! 8549 }
  8550 if (dynamic_cast<LoadInst*>(inst)) {
  8551   LoadInst* clone = builder.build_load(clone_arg(inst->arg(0), builder, values), ((LoadInst*) inst)->type(), ((LoadInst*) inst)->flags(), ((LoadInst*) inst)->aliasing(), ((LoadInst*) inst)->offset());
  8552   return clone;
  8553 }

jitir_llvmapi.hpp

Lines 632-648

  632     assert(build_args.size() == 3);
  633     llvm::Value* built = builder.CreateCall(api.build_float_to_int_s, build_args);
  634     return built;
  635   }
! 636   if (PtrToIntInst* i = dynamic_cast<PtrToIntInst*>(inst)) {
! 637     std::vector<llvm::Value*> build_args;
! 638     build_args.push_back(jitir_builder);
! 639     build_args.push_back(args[0]);
! 640     build_args.push_back(llvm::ConstantInt::get(llvm::Type::getInt32Ty(context), (uint64_t)i->type(), false));
! 641     assert(build_args.size() == 3);
! 642     llvm::Value* built = builder.CreateCall(api.build_ptr_to_int, build_args);
! 643     return built;
! 644   }
  645   if (LoadInst* i = dynamic_cast<LoadInst*>(inst)) {
  646     std::vector<llvm::Value*> build_args;
  647     build_args.push_back(jitir_builder);
  648     build_args.push_back(args[0]);

@can-lehmann
can-lehmann merged commit 1182189 into main Jun 3, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant