mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 20:11:17 +00:00
- Regression vector ABI: npot vectors would load incorrectly from pointers and other things. #2576
228 lines
7.6 KiB
Plaintext
228 lines
7.6 KiB
Plaintext
// #target: linux-x64
|
|
module inherit;
|
|
import std::io;
|
|
|
|
interface Base
|
|
{
|
|
fn void tesT();
|
|
}
|
|
|
|
interface TestProto2 : Base
|
|
{
|
|
}
|
|
|
|
interface TestProto : Base
|
|
{
|
|
fn void hello();
|
|
}
|
|
|
|
fn void Test.tesT(&self) @dynamic
|
|
{
|
|
}
|
|
|
|
fn void Test.hello(&self) @dynamic
|
|
{
|
|
}
|
|
|
|
struct Test (TestProto, TestProto2)
|
|
{
|
|
void* abc;
|
|
}
|
|
|
|
fn void main()
|
|
{
|
|
TestProto z = mem::alloc(Test);
|
|
z.tesT();
|
|
Base w = z;
|
|
w.tesT();
|
|
}
|
|
|
|
/* #expect: inherit.ll
|
|
|
|
%.introspect = type { i8, i64, ptr, i64, i64, i64, [0 x i64] }
|
|
%any = type { ptr, i64 }
|
|
$.dyn_search = comdat any
|
|
$"$ct.inherit.Test" = comdat any
|
|
$"$sel.tesT" = comdat any
|
|
$"$sel.hello" = comdat any
|
|
@"$ct.inherit.Test" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 8, i64 0, i64 1, [0 x i64] zeroinitializer }, comdat, align 8
|
|
@"$sel.tesT" = linkonce_odr constant [5 x i8] c"tesT\00", comdat, align 1
|
|
@.panic_msg = internal constant [42 x i8] c"No method 'tesT' could be found on target\00", align 1
|
|
@.func = internal constant [5 x i8] c"main\00", align 1
|
|
@std.core.builtin.panic = extern_weak global ptr, align 8
|
|
@"$ct.dyn.inherit.Test.tesT" = weak global { ptr, ptr, ptr } { ptr @inherit.Test.tesT, ptr @"$sel.tesT", ptr inttoptr (i64 -1 to ptr) }, comdat, align 8
|
|
@"$ct.dyn.inherit.Test.hello" = weak global { ptr, ptr, ptr } { ptr @inherit.Test.hello, ptr @"$sel.hello", ptr inttoptr (i64 -1 to ptr) }, comdat, align 8
|
|
@"$sel.hello" = linkonce_odr constant [6 x i8] c"hello\00", comdat, align 1
|
|
@llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 1, ptr @.c3_dynamic_register, ptr null }]
|
|
define void @inherit.Test.tesT(ptr %0) #0 {
|
|
entry:
|
|
ret void
|
|
}
|
|
define void @inherit.Test.hello(ptr %0) #0 {
|
|
entry:
|
|
ret void
|
|
}
|
|
|
|
define void @inherit.main() #0 {
|
|
entry:
|
|
%z = alloca %any, align 8
|
|
%.inlinecache = alloca ptr, align 8
|
|
%.cachedtype = alloca ptr, align 8
|
|
%w = alloca %any, align 8
|
|
%.inlinecache2 = alloca ptr, align 8
|
|
%.cachedtype3 = alloca ptr, align 8
|
|
store ptr null, ptr %.cachedtype3, align 8
|
|
store ptr null, ptr %.cachedtype, align 8
|
|
%0 = call ptr @std.core.mem.malloc(i64 8) #1
|
|
%1 = insertvalue %any undef, ptr %0, 0
|
|
%2 = insertvalue %any %1, i64 ptrtoint (ptr @"$ct.inherit.Test" to i64), 1
|
|
store %any %2, ptr %z, align 8
|
|
%ptradd = getelementptr inbounds i8, ptr %z, i64 8
|
|
%3 = load i64, ptr %ptradd, align 8
|
|
%4 = inttoptr i64 %3 to ptr
|
|
%5 = load ptr, ptr %.cachedtype, align 8
|
|
%6 = icmp eq ptr %4, %5
|
|
br i1 %6, label %cache_hit, label %cache_miss
|
|
|
|
cache_miss: ; preds = %entry
|
|
%7 = call ptr @.dyn_search(ptr %4, ptr @"$sel.tesT")
|
|
store ptr %7, ptr %.inlinecache, align 8
|
|
store ptr %4, ptr %.cachedtype, align 8
|
|
br label %9
|
|
|
|
cache_hit: ; preds = %entry
|
|
%8 = load ptr, ptr %.inlinecache, align 8
|
|
br label %9
|
|
|
|
9: ; preds = %cache_hit, %cache_miss
|
|
%fn_phi = phi ptr [ %8, %cache_hit ], [ %7, %cache_miss ]
|
|
%10 = icmp eq ptr %fn_phi, null
|
|
br i1 %10, label %missing_function, label %match
|
|
|
|
missing_function: ; preds = %9
|
|
%11 = load ptr, ptr @std.core.builtin.panic, align 8
|
|
call void %11(ptr @.panic_msg, i64 41, ptr @.file
|
|
unreachable
|
|
|
|
match: ; preds = %9
|
|
%12 = load ptr, ptr %z, align 8
|
|
call void %fn_phi(ptr %12)
|
|
%13 = load %any, ptr %z, align 8
|
|
store %any %13, ptr %w, align 8
|
|
%ptradd1 = getelementptr inbounds i8, ptr %w, i64 8
|
|
%14 = load i64, ptr %ptradd1, align 8
|
|
%15 = inttoptr i64 %14 to ptr
|
|
%16 = load ptr, ptr %.cachedtype3, align 8
|
|
%17 = icmp eq ptr %15, %16
|
|
br i1 %17, label %cache_hit5, label %cache_miss4
|
|
|
|
cache_miss4: ; preds = %match
|
|
%18 = call ptr @.dyn_search(ptr %15, ptr @"$sel.tesT")
|
|
store ptr %18, ptr %.inlinecache2, align 8
|
|
store ptr %15, ptr %.cachedtype3, align 8
|
|
br label %20
|
|
|
|
cache_hit5: ; preds = %match
|
|
%19 = load ptr, ptr %.inlinecache2, align 8
|
|
br label %20
|
|
|
|
20: ; preds = %cache_hit5, %cache_miss4
|
|
%fn_phi6 = phi ptr [ %19, %cache_hit5 ], [ %18, %cache_miss4 ]
|
|
%21 = icmp eq ptr %fn_phi6, null
|
|
br i1 %21, label %missing_function7, label %match8
|
|
|
|
missing_function7: ; preds = %20
|
|
%22 = load ptr, ptr @std.core.builtin.panic, align 8
|
|
call void %22(ptr @.panic_msg, i64 41, ptr @.file, i64 16, ptr @.func, i64 4, i32 36) #2
|
|
unreachable
|
|
|
|
match8: ; preds = %20
|
|
%23 = load ptr, ptr %w, align 8
|
|
call void %fn_phi6(ptr %23)
|
|
ret void
|
|
}
|
|
define i32 @main(i32 %0, ptr %1) #0 {
|
|
entry:
|
|
call void @inherit.main()
|
|
ret i32 0
|
|
}
|
|
|
|
define weak ptr @.dyn_search(ptr %0, ptr %1) unnamed_addr comdat {
|
|
entry:
|
|
br label %get_dtable
|
|
|
|
get_dtable: ; preds = %next_parent, %entry
|
|
%typeid = phi ptr [ %0, %entry ], [ %parent_ptr, %next_parent ]
|
|
%dtable_ref = getelementptr inbounds
|
|
%dtable = load ptr, ptr %dtable_ref, align 8
|
|
br label %check
|
|
|
|
check: ; preds = %no_match, %get_dtable
|
|
%2 = phi ptr [ %dtable, %get_dtable ], [ %10, %no_match ]
|
|
%3 = icmp eq ptr %2, null
|
|
br i1 %3, label %next_parent, label %compare
|
|
|
|
next_parent: ; preds = %check
|
|
%parent_ref = getelementptr inbounds
|
|
%parent = load i64, ptr %parent_ref, align 8
|
|
%parent_ptr = inttoptr i64 %parent to ptr
|
|
%4 = icmp eq ptr %parent_ptr, null
|
|
br i1 %4, label %missing_function, label %get_dtable
|
|
|
|
missing_function: ; preds = %next_parent
|
|
ret ptr null
|
|
|
|
compare: ; preds = %check
|
|
%5 = getelementptr inbounds
|
|
%6 = load ptr, ptr %5, align 8
|
|
%7 = icmp eq ptr %6, %1
|
|
br i1 %7, label %match, label %no_match
|
|
|
|
match: ; preds = %compare
|
|
%8 = load ptr, ptr %2, align 8
|
|
ret ptr %8
|
|
|
|
no_match: ; preds = %compare
|
|
%9 = getelementptr inbounds
|
|
%10 = load ptr, ptr %9, align 8
|
|
br label %check
|
|
}
|
|
|
|
define internal void @.c3_dynamic_register() align 8 {
|
|
entry:
|
|
%next_val = load ptr, ptr getelementptr inbounds
|
|
%0 = icmp eq ptr %next_val, inttoptr (i64 -1 to ptr)
|
|
br i1 %0, label %dtable_check, label %dtable_skip
|
|
|
|
dtable_check: ; preds = %dtable_check, %entry
|
|
%dtable_ref = phi ptr [ getelementptr inbounds
|
|
%dtable_ptr = load ptr, ptr %dtable_ref, align 8
|
|
%1 = icmp eq ptr %dtable_ptr, null
|
|
%next_dtable_ref = getelementptr inbounds
|
|
br i1 %1, label %dtable_found, label %dtable_check
|
|
|
|
dtable_found: ; preds = %dtable_check
|
|
store ptr @"$ct.dyn.inherit.Test.tesT", ptr %dtable_ref, align 8
|
|
store ptr null, ptr getelementptr inbounds
|
|
br label %dtable_skip
|
|
|
|
dtable_skip: ; preds = %dtable_found, %entry
|
|
%next_val1 = load ptr, ptr getelementptr inbounds
|
|
%2 = icmp eq ptr %next_val1, inttoptr (i64 -1 to ptr)
|
|
br i1 %2, label %dtable_check2, label %dtable_skip7
|
|
|
|
dtable_check2: ; preds = %dtable_check2, %dtable_skip
|
|
%dtable_ref3 = phi ptr [ getelementptr inbounds
|
|
%dtable_ptr4 = load ptr, ptr %dtable_ref3, align 8
|
|
%3 = icmp eq ptr %dtable_ptr4, null
|
|
%next_dtable_ref5 = getelementptr inbounds
|
|
br i1 %3, label %dtable_found6, label %dtable_check2
|
|
|
|
dtable_found6: ; preds = %dtable_check2
|
|
store ptr @"$ct.dyn.inherit.Test.hello", ptr %dtable_ref3, align 8
|
|
store ptr null, ptr getelementptr inbounds
|
|
br label %dtable_skip7
|
|
|
|
dtable_skip7: ; preds = %dtable_found6, %dtable_skip
|
|
ret void
|
|
} |