About porting llvm-gcc frontend.

I am porting llvm-gcc frontend. We have ported GCC4.2 for our target. So I move .h .md and .c to llvm-gcc. I do not implement any LLVM MACRO, and use default action of llvm-gcc. I get a new llvm-gcc for our target. But I get a bug.

/
/
//#include <stdio.h>
union MYunion {
unsigned char uc ;
int ui;
} myunion;

void vfu1(union MYunion u) {
u.ui = 99;
}

void unions() {
myunion.ui = 0;
vfu1(myunion);
iequals(244, myunion.ui, 0);
}

int iequals( int line, int val1, int val2) {
printf(“in iequals: line = %d, val1 = %d, val2 = %d\n”, line, val1, val2);
if(val1 == val2) {
printf(“val1 == val2\n”);
} else {
printf(“val1 != val2\n”);
}
return 1;
}

int main() {
unions();
return 0;
}
/1. I get IR from my llvm-gcc.
**/
%struct.MYunion = type { i32 }
@myunion = common global %struct.MYunion zeroinitializer ; <%struct.MYunion
> [#uses=2]
@.str = internal constant [45 x i8] c"in iequals: line = %d, val1 = %d, val2 = %d\0A\00" ; <[45 x i8]
> [#uses=1]
@.str1 = internal constant [13 x i8] c"val1 == val2\00" ; <[13 x i8]
> [#uses=1]
@.str2 = internal constant [13 x i8] c"val1 != val2\00" ; <[13 x i8]> [#uses=1]

define void @vfu1(%struct.MYunion byval align 4 %u) nounwind {
entry:
%0 = getelementptr %struct.MYunion %u, i32 0, i32 0 ; <i32> [#uses=1]
store i32 99, i32 %0, align 4
br label %return

return: ; preds = %entry
ret void
}

define void @unions() nounwind {
entry:
store i32 0, i32 getelementptr (%struct.MYunion @myunion, i32 0, i32 0), align 4
call void @vfu1(%struct.MYunion byval align 4 @myunion) nounwind
%0 = load i32 getelementptr (%struct.MYunion @myunion, i32 0, i32 0), align 4 ; [#uses=1]
%1 = call i32 (…) bitcast (i32 (i32, i32, i32) @iequals to i32 (…))(i32 244, i32 %0, i32 0) nounwind ; [#uses=0]
br label %return

return: ; preds = %entry
ret void
}
/2. ***********After llvm optimize pass. I get *********/
declare i32 @printf(i8
, …) nounwind

declare i32 @puts(i8
)

define i32 @main() nounwind {
return:
%0 = call i32 (i8
, …)
@printf(i8
getelementptr ([45 x i8]
@.str, i32 0, i32 0), i32 244, i32 99, i32 0) nounwind ; [#uses=0]
%1 = call i32 @puts(i8
getelementptr ([13 x i8]
@.str2, i32 0, i32 0)) nounwind ; [#uses=0]
ret i32 0
}
/3. **My question/
It means that function “void vfu1(union MYunion u)” modifies global varible myunion. But llvm-gcc of X86 will not do that. So my llvm-gcc has a bug.

1) Which function or Macro changes “vfu1” function’s arguments type?
2) Which Macro of GCC or LLVM does I implement to control this arguments type convert?



|

Hi 任坤,

void vfu1(union MYunion u) {
    u.ui = 99;
}

here u is passed by copy, so vfu1 has no externally
visible effect. I think you meant: union MYunion *u

define void @vfu1(%struct.MYunion* byval align 4 %u) nounwind {

Here "byval" means that a pointer to a temporary copy of u is being
passed, not u itself. Thus any writes to the %u parameter have no
effect outside this function.

/3. ***********My question*********/
It means that function "void vfu1(union MYunion u)" modifies global varible myunion.

This call
   vfu1(myunion);
does not result in myunion being modified.

Ciao,

Duncan.

Dear Duncan Sands:

Yes, you are right. This IR is correct. This bug is caused by llvm-ld.
Edwin has fixed it. Please refer to:

Edwin <edwintorok@gmail.com> changed:

What |Removed |Added