array in subroutine LLVM verify fails
program expr2
implicit none
integer :: x(3), y(3), z(3)
x = 3
call f(x, y)
print *, y
contains
subroutine f(x, y)
integer, intent(in) :: x(:)
integer, intent(out) :: y(:)
y = x
end subroutine
end program
Error
The error is:
$ lfortran expr2.f90
; ModuleID = 'LFortran'
source_filename = "LFortran"
%array = type { i32*, i32, [1 x %dimension_descriptor] }
%dimension_descriptor = type { i32, i32, i32, i32 }
%size_arg = type { %dimension_descriptor*, i32 }
%array_call = type { i32*, i32, [1 x %dimension_descriptor] }
%array_call.0 = type { i32*, i32, [1 x %dimension_descriptor] }
%array.1 = type { [3 x i32], i32, [1 x %dimension_descriptor] }
@0 = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1
@1 = private unnamed_addr constant [2 x i8] c"\0A\00", align 1
declare i32 @__module_lfortran_intrinsic_array_abs(%array*)
declare i1 @__module_lfortran_intrinsic_array_allocated(%array*)
define i32 @__module_lfortran_intrinsic_array_lbound(%dimension_descriptor** %x, i32* %dim) {
.entry:
%lbound = alloca i32, align 4
%0 = load %dimension_descriptor*, %dimension_descriptor** %x, align 8
%1 = load i32, i32* %dim, align 4
%2 = sub i32 %1, 1
%3 = getelementptr inbounds %dimension_descriptor, %dimension_descriptor* %0, i32 %2
%4 = getelementptr %dimension_descriptor, %dimension_descriptor* %3, i32 0, i32 1
%5 = load i32, i32* %4, align 4
store i32 %5, i32* %lbound, align 4
%6 = load i32, i32* %lbound, align 4
ret i32 %6
}
declare i32 @__module_lfortran_intrinsic_array_max(i32*, i32*)
declare i32 @__module_lfortran_intrinsic_array_maxval(%array*)
declare i32 @__module_lfortran_intrinsic_array_min(i32*, i32*)
declare i32 @__module_lfortran_intrinsic_array_minval(%array*)
declare i32 @__module_lfortran_intrinsic_array_real(%array*, i32*)
define i32 @__module_lfortran_intrinsic_array_size(%size_arg* %x) {
.entry:
%size = alloca i32, align 4
%0 = getelementptr %size_arg, %size_arg* %x, i32 0, i32 0
%1 = load %dimension_descriptor*, %dimension_descriptor** %0, align 8
%2 = getelementptr %size_arg, %size_arg* %x, i32 0, i32 1
%3 = load i32, i32* %2, align 4
store i32 1, i32* %size, align 4
%4 = alloca i32, align 4
store i32 0, i32* %4, align 4
br label %loop.head
loop.head: ; preds = %loop.body, %.entry
%5 = load i32, i32* %4, align 4
%6 = icmp slt i32 %5, %3
br i1 %6, label %loop.body, label %loop.end
loop.body: ; preds = %loop.head
%7 = load i32, i32* %4, align 4
%8 = load i32, i32* %size, align 4
%9 = getelementptr inbounds %dimension_descriptor, %dimension_descriptor* %1, i32 %7
%10 = getelementptr %dimension_descriptor, %dimension_descriptor* %9, i32 0, i32 3
%11 = load i32, i32* %10, align 4
%12 = mul i32 %8, %11
store i32 %12, i32* %size, align 4
%13 = add i32 %7, 1
store i32 %13, i32* %4, align 4
br label %loop.head
loop.end: ; preds = %loop.head
%14 = load i32, i32* %size, align 4
ret i32 %14
}
declare i32 @__module_lfortran_intrinsic_array_sum(%array*)
define i32 @__module_lfortran_intrinsic_array_ubound(%dimension_descriptor** %x, i32* %dim) {
.entry:
%ubound = alloca i32, align 4
%0 = load %dimension_descriptor*, %dimension_descriptor** %x, align 8
%1 = load i32, i32* %dim, align 4
%2 = sub i32 %1, 1
%3 = getelementptr inbounds %dimension_descriptor, %dimension_descriptor* %0, i32 %2
%4 = getelementptr %dimension_descriptor, %dimension_descriptor* %3, i32 0, i32 2
%5 = load i32, i32* %4, align 4
store i32 %5, i32* %ubound, align 4
%6 = load i32, i32* %ubound, align 4
ret i32 %6
}
define void @f(%array_call* %x, %array_call.0* %y) {
.entry:
%0 = load %array_call, %array_call* %x, align 8
store %array_call* %x, %array_call.0* %y, align 8
ret void
}
define i32 @main() {
.entry:
%"1_k" = alloca i32, align 4
%x = alloca %array.1, align 8
%0 = getelementptr %array.1, %array.1* %x, i32 0, i32 1
store i32 0, i32* %0, align 4
%1 = getelementptr %array.1, %array.1* %x, i32 0, i32 2
%2 = getelementptr [1 x %dimension_descriptor], [1 x %dimension_descriptor]* %1, i32 0, i32 0
%3 = getelementptr %dimension_descriptor, %dimension_descriptor* %2, i32 0, i32 0
%4 = getelementptr %dimension_descriptor, %dimension_descriptor* %2, i32 0, i32 1
%5 = getelementptr %dimension_descriptor, %dimension_descriptor* %2, i32 0, i32 2
%6 = getelementptr %dimension_descriptor, %dimension_descriptor* %2, i32 0, i32 3
store i32 1, i32* %3, align 4
store i32 1, i32* %4, align 4
store i32 3, i32* %5, align 4
%7 = load i32, i32* %5, align 4
%8 = load i32, i32* %4, align 4
%9 = sub i32 %7, %8
%10 = add i32 %9, 1
store i32 %10, i32* %6, align 4
%y = alloca %array.1, align 8
%11 = getelementptr %array.1, %array.1* %y, i32 0, i32 1
store i32 0, i32* %11, align 4
%12 = getelementptr %array.1, %array.1* %y, i32 0, i32 2
%13 = getelementptr [1 x %dimension_descriptor], [1 x %dimension_descriptor]* %12, i32 0, i32 0
%14 = getelementptr %dimension_descriptor, %dimension_descriptor* %13, i32 0, i32 0
%15 = getelementptr %dimension_descriptor, %dimension_descriptor* %13, i32 0, i32 1
%16 = getelementptr %dimension_descriptor, %dimension_descriptor* %13, i32 0, i32 2
%17 = getelementptr %dimension_descriptor, %dimension_descriptor* %13, i32 0, i32 3
store i32 1, i32* %14, align 4
store i32 1, i32* %15, align 4
store i32 3, i32* %16, align 4
%18 = load i32, i32* %16, align 4
%19 = load i32, i32* %15, align 4
%20 = sub i32 %18, %19
%21 = add i32 %20, 1
store i32 %21, i32* %17, align 4
%z = alloca %array.1, align 8
%22 = getelementptr %array.1, %array.1* %z, i32 0, i32 1
store i32 0, i32* %22, align 4
%23 = getelementptr %array.1, %array.1* %z, i32 0, i32 2
%24 = getelementptr [1 x %dimension_descriptor], [1 x %dimension_descriptor]* %23, i32 0, i32 0
%25 = getelementptr %dimension_descriptor, %dimension_descriptor* %24, i32 0, i32 0
%26 = getelementptr %dimension_descriptor, %dimension_descriptor* %24, i32 0, i32 1
%27 = getelementptr %dimension_descriptor, %dimension_descriptor* %24, i32 0, i32 2
%28 = getelementptr %dimension_descriptor, %dimension_descriptor* %24, i32 0, i32 3
store i32 1, i32* %25, align 4
store i32 1, i32* %26, align 4
store i32 3, i32* %27, align 4
%29 = load i32, i32* %27, align 4
%30 = load i32, i32* %26, align 4
%31 = sub i32 %29, %30
%32 = add i32 %31, 1
store i32 %32, i32* %28, align 4
%33 = alloca %dimension_descriptor*, align 8
%34 = getelementptr %array.1, %array.1* %x, i32 0, i32 2
%35 = getelementptr [1 x %dimension_descriptor], [1 x %dimension_descriptor]* %34, i32 0, i32 0
store %dimension_descriptor* %35, %dimension_descriptor** %33, align 8
%36 = alloca i32, align 4
store i32 1, i32* %36, align 4
%37 = call i32 @__module_lfortran_intrinsic_array_lbound(%dimension_descriptor** %33, i32* %36)
%38 = sub i32 %37, 1
store i32 %38, i32* %"1_k", align 4
br label %loop.head
loop.head: ; preds = %loop.body, %.entry
%39 = load i32, i32* %"1_k", align 4
%40 = add i32 %39, 1
%41 = alloca %dimension_descriptor*, align 8
%42 = getelementptr %array.1, %array.1* %x, i32 0, i32 2
%43 = getelementptr [1 x %dimension_descriptor], [1 x %dimension_descriptor]* %42, i32 0, i32 0
store %dimension_descriptor* %43, %dimension_descriptor** %41, align 8
%44 = alloca i32, align 4
store i32 1, i32* %44, align 4
%45 = call i32 @__module_lfortran_intrinsic_array_ubound(%dimension_descriptor** %41, i32* %44)
%46 = icmp sle i32 %40, %45
br i1 %46, label %loop.body, label %loop.end
loop.body: ; preds = %loop.head
%47 = load i32, i32* %"1_k", align 4
%48 = add i32 %47, 1
store i32 %48, i32* %"1_k", align 4
%49 = load i32, i32* %"1_k", align 4
%50 = getelementptr %array.1, %array.1* %x, i32 0, i32 2
%51 = getelementptr [1 x %dimension_descriptor], [1 x %dimension_descriptor]* %50, i32 0, i32 0
%52 = getelementptr %dimension_descriptor, %dimension_descriptor* %51, i32 0, i32 1
%53 = load i32, i32* %52, align 4
%54 = sub i32 %49, %53
%55 = mul i32 1, %54
%56 = add i32 0, %55
%57 = getelementptr %dimension_descriptor, %dimension_descriptor* %51, i32 0, i32 3
%58 = load i32, i32* %57, align 4
%59 = mul i32 1, %58
%60 = getelementptr %array.1, %array.1* %x, i32 0, i32 0
%61 = getelementptr [3 x i32], [3 x i32]* %60, i32 0, i32 %56
store i32 3, i32* %61, align 4
br label %loop.head
loop.end: ; preds = %loop.head
%62 = alloca %array_call, align 8
%63 = getelementptr %array.1, %array.1* %x, i32 0, i32 0
%64 = getelementptr [3 x i32], [3 x i32]* %63, i32 0, i32 0
%65 = getelementptr %array_call, %array_call* %62, i32 0, i32 0
store i32* %64, i32** %65, align 8
%66 = getelementptr %array.1, %array.1* %x, i32 0, i32 1
%67 = load i32, i32* %66, align 4
%68 = getelementptr %array_call, %array_call* %62, i32 0, i32 1
store i32 %67, i32* %68, align 4
%69 = getelementptr %array.1, %array.1* %x, i32 0, i32 2
%70 = load [1 x %dimension_descriptor], [1 x %dimension_descriptor]* %69, align 4
%71 = getelementptr %array_call, %array_call* %62, i32 0, i32 2
store [1 x %dimension_descriptor] %70, [1 x %dimension_descriptor]* %71, align 4
%72 = alloca %array_call.0, align 8
%73 = getelementptr %array.1, %array.1* %y, i32 0, i32 0
%74 = getelementptr [3 x i32], [3 x i32]* %73, i32 0, i32 0
%75 = getelementptr %array_call.0, %array_call.0* %72, i32 0, i32 0
store i32* %74, i32** %75, align 8
%76 = getelementptr %array.1, %array.1* %y, i32 0, i32 1
%77 = load i32, i32* %76, align 4
%78 = getelementptr %array_call.0, %array_call.0* %72, i32 0, i32 1
store i32 %77, i32* %78, align 4
%79 = getelementptr %array.1, %array.1* %y, i32 0, i32 2
%80 = load [1 x %dimension_descriptor], [1 x %dimension_descriptor]* %79, align 4
%81 = getelementptr %array_call.0, %array_call.0* %72, i32 0, i32 2
store [1 x %dimension_descriptor] %80, [1 x %dimension_descriptor]* %81, align 4
call void @f(%array_call* %62, %array_call.0* %72)
%82 = alloca %dimension_descriptor*, align 8
%83 = getelementptr %array.1, %array.1* %y, i32 0, i32 2
%84 = getelementptr [1 x %dimension_descriptor], [1 x %dimension_descriptor]* %83, i32 0, i32 0
store %dimension_descriptor* %84, %dimension_descriptor** %82, align 8
%85 = alloca i32, align 4
store i32 1, i32* %85, align 4
%86 = call i32 @__module_lfortran_intrinsic_array_lbound(%dimension_descriptor** %82, i32* %85)
%87 = sub i32 %86, 1
store i32 %87, i32* %"1_k", align 4
br label %loop.head1
loop.head1: ; preds = %loop.body2, %loop.end
%88 = load i32, i32* %"1_k", align 4
%89 = add i32 %88, 1
%90 = alloca %dimension_descriptor*, align 8
%91 = getelementptr %array.1, %array.1* %y, i32 0, i32 2
%92 = getelementptr [1 x %dimension_descriptor], [1 x %dimension_descriptor]* %91, i32 0, i32 0
store %dimension_descriptor* %92, %dimension_descriptor** %90, align 8
%93 = alloca i32, align 4
store i32 1, i32* %93, align 4
%94 = call i32 @__module_lfortran_intrinsic_array_ubound(%dimension_descriptor** %90, i32* %93)
%95 = icmp sle i32 %89, %94
br i1 %95, label %loop.body2, label %loop.end3
loop.body2: ; preds = %loop.head1
%96 = load i32, i32* %"1_k", align 4
%97 = add i32 %96, 1
store i32 %97, i32* %"1_k", align 4
%98 = load i32, i32* %"1_k", align 4
%99 = getelementptr %array.1, %array.1* %y, i32 0, i32 2
%100 = getelementptr [1 x %dimension_descriptor], [1 x %dimension_descriptor]* %99, i32 0, i32 0
%101 = getelementptr %dimension_descriptor, %dimension_descriptor* %100, i32 0, i32 1
%102 = load i32, i32* %101, align 4
%103 = sub i32 %98, %102
%104 = mul i32 1, %103
%105 = add i32 0, %104
%106 = getelementptr %dimension_descriptor, %dimension_descriptor* %100, i32 0, i32 3
%107 = load i32, i32* %106, align 4
%108 = mul i32 1, %107
%109 = getelementptr %array.1, %array.1* %y, i32 0, i32 0
%110 = getelementptr [3 x i32], [3 x i32]* %109, i32 0, i32 %105
%111 = load i32, i32* %110, align 4
call void (i8*, ...) @_lfortran_printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @0, i32 0, i32 0), i32 %111)
br label %loop.head1
loop.end3: ; preds = %loop.head1
call void (i8*, ...) @_lfortran_printf(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @1, i32 0, i32 0))
ret i32 0
}
declare void @_lfortran_printf(i8*, ...)
Code generation error: asr_to_llvm: module failed verification. Error:
Stored value type does not match pointer operand type!
store %array_call* %x, %array_call.0* %y, align 8
%array_call.0 = type { i32*, i32, [1 x %dimension_descriptor] }