Closed rarris closed 2 years ago
It compiles, but does not run, on linux it's an invalid memory reference, on windows an access violation.
It seems to be related to the global array
If I compile the code with -c and then pass it to clang, clang complains about a missing symbol gX
It compiles, but does not run, on linux it's an invalid memory reference, on windows an access violation. It seems to be related to the global array If I compile the code with -c and then pass it to clang, clang complains about a missing symbol
gX
can you post the resulting ir?
Did not investigate much yet, here's the IR
; ModuleID = 'main'
source_filename = "main"
%main_interface = type { i16, i16, i16 }
@gX = external global [3 x i16]
@gZ = global i16 0
define float @main(%main_interface* %0) {
entry:
%x = getelementptr inbounds %main_interface, %main_interface* %0, i32 0, i32 0
%y = getelementptr inbounds %main_interface, %main_interface* %0, i32 0, i32 1
%z = getelementptr inbounds %main_interface, %main_interface* %0, i32 0, i32 2
%main = alloca float, align 4
store i16 10, i16* getelementptr inbounds ([3 x i16], [3 x i16]* @gX, i32 0, i32 0), align 2
store i16 21, i16* getelementptr inbounds ([3 x i16], [3 x i16]* @gX, i32 0, i32 1), align 2
store i16 5, i16* @gZ, align 2
%load_tmpVar = load i16, i16* getelementptr inbounds ([3 x i16], [3 x i16]* @gX, i32 0, i32 0), align 2
store i16 %load_tmpVar, i16* %x, align 2
%load_tmpVar1 = load i16, i16* getelementptr inbounds ([3 x i16], [3 x i16]* @gX, i32 0, i32 1), align 2
store i16 %load_tmpVar1, i16* %y, align 2
%load_gZ = load i16, i16* @gZ, align 2
store i16 %load_gZ, i16* %z, align 2
%load_x = load i16, i16* %x, align 2
%1 = sext i16 %load_x to i32
%load_y = load i16, i16* %y, align 2
%2 = sext i16 %load_y to i32
%tmpVar = add i32 %1, %2
%load_z = load i16, i16* %z, align 2
%3 = sext i16 %load_z to i32
%tmpVar2 = sdiv i32 %tmpVar, %3
%4 = sitofp i32 %tmpVar2 to float
store float %4, float* %main, align 4
%main_ret = load float, float* %main, align 4
ret float %main_ret
}
@gX = external global [3 x i16]
external means that it is defined somewhere else ... why would this be external? maybe we have an initialization problem? like we don't provide a default value for arrays?
Turns out that we can't handle uninitialized arrays. I guess inside POUs this problem doesn't happen, because the whole POU's memory gets zero-initialized. With a global, llvm turns it into an extern (forward-declaration) if no initializer is provided.
If you initialize the array the code compiles.
VAR_GLOBAL
gX : ARRAY[0..2] OF INT := [0, 0, 0];
gZ : INT;
END_VAR
FUNCTION main : REAL
VAR
x,y : INT;
z : INT;
END_VAR
gX[0] := 10;
gX[1] := 21;
gZ := 5;
x := gX[0];
y := gX[1];
z := gZ;
main := (x + y) / z;
END_FUNCTION
Branch issue-361-GLOBAL_VARIABLES_array_problem created!
the following test is not compiled
(exit code: 0xc0000005, STATUS_ACCESS_VIOLATION)