mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
* Require parenthesized assignment expressions in condition of 'if' statements #2716 * Move analysis to semantic checker and also check while. And update tests and release notes. --------- Co-authored-by: Christoffer Lerno <christoffer@aegik.com>
1018 lines
29 KiB
Plaintext
1018 lines
29 KiB
Plaintext
// #target: macos-x64
|
|
module foo;
|
|
|
|
extern fn void* malloc(uint);
|
|
|
|
struct List
|
|
{
|
|
int data;
|
|
List* next;
|
|
}
|
|
|
|
fn List* passThroughList(List* l) {
|
|
return l;
|
|
}
|
|
|
|
// Recursive data structure tests...
|
|
|
|
List* data;
|
|
|
|
fn void foo()
|
|
{
|
|
static int foo = 0; // Test static local variable
|
|
foo += 1; // Increment static variable
|
|
|
|
data = (List*)malloc(12); // This is not a proper list allocation
|
|
}
|
|
|
|
List listNode3 = { 4, null };
|
|
List listNode2 = { 3, &listNode3 };
|
|
List listNode0 = { 1, &listNode1 };
|
|
List listNode1 = { 2, &listNode2 };
|
|
|
|
|
|
List[10] listArray;
|
|
|
|
// Iterative insert fn
|
|
fn void insertIntoListTail(List **l, int data) {
|
|
while (*l) l = &(*l).next;
|
|
*l = (List*)malloc(List.sizeof);
|
|
(*l).data = data;
|
|
(*l).next = null;
|
|
}
|
|
|
|
// Recursive list search fn
|
|
fn List *findData(List *l, int data) {
|
|
if (!l) return null;
|
|
if (l.data == data) return l;
|
|
return findData(l.next, data);
|
|
}
|
|
|
|
extern fn void foundIt();
|
|
|
|
// Driver fn...
|
|
fn void doListStuff() {
|
|
List* myList = null;
|
|
insertIntoListTail(&myList, 100);
|
|
insertIntoListTail(&myList, 12);
|
|
insertIntoListTail(&myList, 42);
|
|
insertIntoListTail(&myList, 1123);
|
|
insertIntoListTail(&myList, 1213);
|
|
|
|
if (findData(myList, 75)) foundIt();
|
|
if (findData(myList, 42)) foundIt();
|
|
if (findData(myList, 700)) foundIt();
|
|
}
|
|
|
|
|
|
fn int floatcomptest(double *x, double *y, float *x1, float *y1) {
|
|
return (int)(*x < *y || *x1 < *y1);
|
|
}
|
|
|
|
// Exposed a bug
|
|
fn void* memset_impl(void* dstpp, int c, uint len)
|
|
{
|
|
iptr dstp = (iptr)dstpp;
|
|
|
|
while (dstp % 4 != 0)
|
|
{
|
|
((char*)dstp)[0] = (char)c;
|
|
dstp += 1;
|
|
len -= 1;
|
|
}
|
|
return dstpp;
|
|
}
|
|
|
|
// TEST problem with signed/unsigned versions of the same constants being shared
|
|
// incorrectly!
|
|
char* temp @private;
|
|
int remaining @private;
|
|
fn char* localmalloc(int size) @private {
|
|
char* blah;
|
|
|
|
if (size>remaining)
|
|
{
|
|
temp = (char*) malloc(32768);
|
|
remaining = 32768;
|
|
return temp;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
|
|
struct PBVTest { double x; double y; int z; }
|
|
|
|
fn PBVTest testRetStruct(float x, double y, int z) {
|
|
PBVTest t = { x, y, z };
|
|
return t;
|
|
}
|
|
extern fn PBVTest testRetStruct2(); // external func no inlining
|
|
|
|
|
|
fn double callRetStruct(float x, double y, int z) {
|
|
PBVTest t = testRetStruct2();
|
|
return t.x+x+y+z;
|
|
}
|
|
|
|
extern fn int fp(int, char*);
|
|
char *ext;
|
|
fn void __bb_exit_func()
|
|
{
|
|
fp(12, ext ? ext : "<none>");
|
|
}
|
|
|
|
extern fn int puts(char* s);
|
|
|
|
struct FunStructTest
|
|
{
|
|
int test1;
|
|
char* pointer;
|
|
int[12] array;
|
|
}
|
|
|
|
struct SubStruct {
|
|
short x, y;
|
|
}
|
|
|
|
struct Quad {
|
|
int w;
|
|
SubStruct ss;
|
|
SubStruct *ssp;
|
|
char c;
|
|
int y;
|
|
}
|
|
|
|
Quad globalQuad = { 4, {1, 2}, null, 3, 156 };
|
|
|
|
alias FuncPtr = fn int(int);
|
|
|
|
fn uint ptrFunc(FuncPtr func, int x) {
|
|
return func(x);
|
|
}
|
|
|
|
fn char ptrFunc2(FuncPtr[30] funcTab, int num) {
|
|
return (char)funcTab[num]('b');
|
|
}
|
|
|
|
extern fn char smallArgs2(char w, char x, long zrrk, char y, char z);
|
|
extern fn int someFuncA();
|
|
fn char smallArgs(char w, char x, char y, char z) {
|
|
someFuncA();
|
|
return smallArgs2(w-1, x+1, y, z, w);
|
|
}
|
|
|
|
fn int f0(Quad q, int i) @private { /* Pass Q by value */
|
|
Quad r @noinit;
|
|
if (i) r.ss = q.ss;
|
|
q.ssp = &r.ss;
|
|
q.w = q.y = q.c = 1;
|
|
return q.ss.y + i + r.y - q.c;
|
|
}
|
|
|
|
fn int f1(Quad *q, int i) { /* Pass Q by address */
|
|
Quad r @noinit;
|
|
if (i) r = *q;
|
|
q.w = q.y = q.c = 1;
|
|
return q.ss.y+i+r.y-q.c;
|
|
}
|
|
|
|
|
|
fn int badFunc(float val) {
|
|
int result @noinit;
|
|
if (val > 12.345) result = 4;
|
|
return result; /* Test use of undefined value */
|
|
}
|
|
|
|
extern fn int ef1(int *, char *, int *);
|
|
|
|
fn int func(int param, long param2) {
|
|
int result = param;
|
|
|
|
{{{{
|
|
char c @noinit; int x @noinit;
|
|
ef1(&result, &c, &x);
|
|
}}}
|
|
|
|
{ // c & X are duplicate names!
|
|
char c; int x;
|
|
ef1(&result, &c, &x);
|
|
}
|
|
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
fn short funFunc(long x, char z) {
|
|
return (short)(x+z);
|
|
}
|
|
|
|
fn uint castTest(int x) { return x; }
|
|
|
|
fn double testAdd(double x, float y) {
|
|
return x+y+0.5;
|
|
}
|
|
|
|
fn int funcZ(int i, int j) {
|
|
while (i != 20) i += 2;
|
|
|
|
j += funcZ(2, i);
|
|
return (i * 3 + j*2)*j;
|
|
}
|
|
|
|
fn int sumArray(int* array, int num) {
|
|
int i @noinit;
|
|
int result = 0;
|
|
for (i = 0; i < num; ++i) result += array[i];
|
|
return result;
|
|
}
|
|
|
|
fn int arrayParam(int* values) {
|
|
return ef1((int*)(iptr)values[50], (char*)1, &values[50]);
|
|
}
|
|
|
|
fn int arrayToSum() {
|
|
int[100] a @noinit;
|
|
int i;
|
|
for (i = 0; i < 100; ++i) a[i] = i*4;
|
|
|
|
return a[a[0]]; //SumArray(A, 100);
|
|
}
|
|
|
|
|
|
extern fn int externFunc(long, uint*, short, char);
|
|
|
|
fn int main(int argc, char **argv)
|
|
{
|
|
uint i @noinit;
|
|
puts("Hello world!\n");
|
|
|
|
externFunc(-1, null, (short)argc, 2);
|
|
//func(argc, argc);
|
|
|
|
for (i = 0; i < 10; i++) puts(argv[3]);
|
|
return 0;
|
|
}
|
|
|
|
fn double mathFunc(double x, double y, double z,
|
|
double aa, double bb, double cc, double dd,
|
|
double ee, double ff, double gg, double hh,
|
|
double aaa, double abb, double acc, double add,
|
|
double aee, double aff) {
|
|
return x + y + z + aa + bb + cc + dd + ee + ff + gg + hh
|
|
+ aaa + abb + acc + add + aee + aff;
|
|
}
|
|
|
|
|
|
|
|
fn void strcpy(char *s1, char *s2) {
|
|
while ((*s1++ = *s2++));
|
|
}
|
|
|
|
fn void strcat(char *s1, char *s2) {
|
|
while (*s1++);
|
|
s1--;
|
|
while ((*s1++ = *s2++));
|
|
}
|
|
|
|
fn int strcmp(char *s1, char *s2) {
|
|
while (*s1++ == *s2++);
|
|
if (*s1 == 0) {
|
|
if (*s2 == 0) {
|
|
return 0;
|
|
} else {
|
|
return -1;
|
|
}
|
|
} else {
|
|
if (*s2 == 0) {
|
|
return 1;
|
|
} else {
|
|
return (*(--s1) - *(--s2));
|
|
}
|
|
}
|
|
}
|
|
|
|
/* #expect: foo.ll
|
|
|
|
%.introspect = type { i8, i64, ptr, i64, i64, i64, [0 x i64] }
|
|
%List = type { i32, ptr }
|
|
%Quad = type { i32, %SubStruct, ptr, i8, i32 }
|
|
%SubStruct = type { i16, i16 }
|
|
%PBVTest = type { double, double, i32 }
|
|
|
|
@"$ct.foo.List" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 16, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8
|
|
@"$ct.foo.PBVTest" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 24, i64 0, i64 3, [0 x i64] zeroinitializer }, align 8
|
|
@"$ct.foo.FunStructTest" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 64, i64 0, i64 3, [0 x i64] zeroinitializer }, align 8
|
|
@"$ct.foo.SubStruct" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 4, i64 0, i64 2, [0 x i64] zeroinitializer }, align 8
|
|
@"$ct.foo.Quad" = linkonce global %.introspect { i8 10, i64 0, ptr null, i64 24, i64 0, i64 5, [0 x i64] zeroinitializer }, align 8
|
|
@foo.data = local_unnamed_addr global ptr null, align 8
|
|
@foo.listNode3 = global %List { i32 4, ptr null }, align 8
|
|
@foo.listNode2 = global %List { i32 3, ptr @foo.listNode3 }, align 8
|
|
@foo.listNode0 = local_unnamed_addr global %List { i32 1, ptr @foo.listNode1 }, align 8
|
|
@foo.listNode1 = global %List { i32 2, ptr @foo.listNode2 }, align 8
|
|
@foo.listArray = local_unnamed_addr global [10 x %List] zeroinitializer, align 16
|
|
@foo.temp = internal unnamed_addr global ptr null, align 8
|
|
@foo.remaining = internal unnamed_addr global i32 0, align 4
|
|
@foo.ext = local_unnamed_addr global ptr null, align 8
|
|
@foo.globalQuad = local_unnamed_addr global %Quad { i32 4, %SubStruct { i16 1, i16 2 }, ptr null, i8 3, i32 156 }, align 8
|
|
@foo.foo.10 = internal unnamed_addr global i32 0, align 4
|
|
@.str = private unnamed_addr constant [7 x i8] c"<none>\00", align 1
|
|
@.str.11 = private unnamed_addr constant [14 x i8] c"Hello world!\0A\00", align 1
|
|
|
|
declare ptr @malloc(i32) #0
|
|
|
|
define ptr @foo.passThroughList(ptr %0) #0 {
|
|
entry:
|
|
ret ptr %0
|
|
}
|
|
|
|
define void @foo.foo() #0 {
|
|
entry:
|
|
%0 = load i32, ptr @foo.foo.10, align 4
|
|
%add = add i32 %0, 1
|
|
store i32 %add, ptr @foo.foo.10, align 4
|
|
%1 = call ptr @malloc(i32 12)
|
|
store ptr %1, ptr @foo.data, align 8
|
|
ret void
|
|
}
|
|
|
|
define void @foo.insertIntoListTail(ptr %0, i32 %1) #0 {
|
|
entry:
|
|
%l = alloca ptr, align 8
|
|
store ptr %0, ptr %l, align 8
|
|
br label %loop.cond
|
|
|
|
loop.cond: ; preds = %loop.body, %entry
|
|
%2 = load ptr, ptr %l, align 8
|
|
%3 = load ptr, ptr %2, align 8
|
|
%i2b = icmp ne ptr %3, null
|
|
br i1 %i2b, label %loop.body, label %loop.exit
|
|
|
|
loop.body: ; preds = %loop.cond
|
|
%4 = load ptr, ptr %l, align 8
|
|
%5 = load ptr, ptr %4, align 8
|
|
%ptradd = getelementptr inbounds i8, ptr %5, i64 8
|
|
store ptr %ptradd, ptr %l, align 8
|
|
br label %loop.cond
|
|
|
|
loop.exit: ; preds = %loop.cond
|
|
%6 = call ptr @malloc(i32 16)
|
|
%7 = load ptr, ptr %l, align 8
|
|
store ptr %6, ptr %7, align 8
|
|
%8 = load ptr, ptr %l, align 8
|
|
%9 = load ptr, ptr %8, align 8
|
|
store i32 %1, ptr %9, align 8
|
|
%10 = load ptr, ptr %l, align 8
|
|
%11 = load ptr, ptr %10, align 8
|
|
%ptradd1 = getelementptr inbounds i8, ptr %11, i64 8
|
|
store ptr null, ptr %ptradd1, align 8
|
|
ret void
|
|
}
|
|
|
|
define ptr @foo.findData(ptr %0, i32 %1) #0 {
|
|
entry:
|
|
%i2nb = icmp eq ptr %0, null
|
|
br i1 %i2nb, label %if.then, label %if.exit
|
|
|
|
if.then: ; preds = %entry
|
|
ret ptr null
|
|
|
|
if.exit: ; preds = %entry
|
|
%2 = load i32, ptr %0, align 8
|
|
%eq = icmp eq i32 %2, %1
|
|
br i1 %eq, label %if.then1, label %if.exit2
|
|
|
|
if.then1: ; preds = %if.exit
|
|
ret ptr %0
|
|
|
|
if.exit2: ; preds = %if.exit
|
|
%ptradd = getelementptr inbounds i8, ptr %0, i64 8
|
|
%3 = load ptr, ptr %ptradd, align 8
|
|
%4 = call ptr @foo.findData(ptr %3, i32 %1)
|
|
ret ptr %4
|
|
}
|
|
|
|
declare void @foundIt() #0
|
|
|
|
define void @foo.doListStuff() #0 {
|
|
entry:
|
|
%myList = alloca ptr, align 8
|
|
store ptr null, ptr %myList, align 8
|
|
call void @foo.insertIntoListTail(ptr %myList, i32 100)
|
|
call void @foo.insertIntoListTail(ptr %myList, i32 12)
|
|
call void @foo.insertIntoListTail(ptr %myList, i32 42)
|
|
call void @foo.insertIntoListTail(ptr %myList, i32 1123)
|
|
call void @foo.insertIntoListTail(ptr %myList, i32 1213)
|
|
%0 = load ptr, ptr %myList, align 8
|
|
%1 = call ptr @foo.findData(ptr %0, i32 75)
|
|
%i2b = icmp ne ptr %1, null
|
|
br i1 %i2b, label %if.then, label %if.exit
|
|
|
|
if.then: ; preds = %entry
|
|
call void @foundIt()
|
|
br label %if.exit
|
|
|
|
if.exit: ; preds = %if.then, %entry
|
|
%2 = load ptr, ptr %myList, align 8
|
|
%3 = call ptr @foo.findData(ptr %2, i32 42)
|
|
%i2b1 = icmp ne ptr %3, null
|
|
br i1 %i2b1, label %if.then2, label %if.exit3
|
|
|
|
if.then2: ; preds = %if.exit
|
|
call void @foundIt()
|
|
br label %if.exit3
|
|
|
|
if.exit3: ; preds = %if.then2, %if.exit
|
|
%4 = load ptr, ptr %myList, align 8
|
|
%5 = call ptr @foo.findData(ptr %4, i32 700)
|
|
%i2b4 = icmp ne ptr %5, null
|
|
br i1 %i2b4, label %if.then5, label %if.exit6
|
|
|
|
if.then5: ; preds = %if.exit3
|
|
call void @foundIt()
|
|
br label %if.exit6
|
|
|
|
if.exit6: ; preds = %if.then5, %if.exit3
|
|
ret void
|
|
}
|
|
|
|
define i32 @foo.floatcomptest(ptr %0, ptr %1, ptr %2, ptr %3) #0 {
|
|
entry:
|
|
%4 = load double, ptr %0, align 8
|
|
%5 = load double, ptr %1, align 8
|
|
%lt = fcmp olt double %4, %5
|
|
br i1 %lt, label %or.phi, label %or.rhs
|
|
|
|
or.rhs: ; preds = %entry
|
|
%6 = load float, ptr %2, align 4
|
|
%7 = load float, ptr %3, align 4
|
|
%lt1 = fcmp olt float %6, %7
|
|
br label %or.phi
|
|
|
|
or.phi: ; preds = %or.rhs, %entry
|
|
%val = phi i1 [ true, %entry ], [ %lt1, %or.rhs ]
|
|
%zext = zext i1 %val to i32
|
|
ret i32 %zext
|
|
}
|
|
|
|
define ptr @foo.memset_impl(ptr %0, i32 %1, i32 %2) #0 {
|
|
entry:
|
|
%len = alloca i32, align 4
|
|
%dstp = alloca i64, align 8
|
|
store i32 %2, ptr %len, align 4
|
|
%ptrxi = ptrtoint ptr %0 to i64
|
|
store i64 %ptrxi, ptr %dstp, align 8
|
|
br label %loop.cond
|
|
|
|
loop.cond: ; preds = %loop.body, %entry
|
|
%3 = load i64, ptr %dstp, align 8
|
|
%smod = srem i64 %3, 4
|
|
%neq = icmp ne i64 %smod, 0
|
|
br i1 %neq, label %loop.body, label %loop.exit
|
|
|
|
loop.body: ; preds = %loop.cond
|
|
%trunc = trunc i32 %1 to i8
|
|
%4 = load i64, ptr %dstp, align 8
|
|
%intptr = inttoptr i64 %4 to ptr
|
|
store i8 %trunc, ptr %intptr, align 1
|
|
%5 = load i64, ptr %dstp, align 8
|
|
%add = add i64 %5, 1
|
|
store i64 %add, ptr %dstp, align 8
|
|
%6 = load i32, ptr %len, align 4
|
|
%sub = sub i32 %6, 1
|
|
store i32 %sub, ptr %len, align 4
|
|
br label %loop.cond
|
|
|
|
loop.exit: ; preds = %loop.cond
|
|
ret ptr %0
|
|
}
|
|
|
|
define internal ptr @foo.localmalloc(i32 %0) #0 {
|
|
entry:
|
|
%blah = alloca ptr, align 8
|
|
store ptr null, ptr %blah, align 8
|
|
%1 = load i32, ptr @foo.remaining, align 4
|
|
%gt = icmp sgt i32 %0, %1
|
|
br i1 %gt, label %if.then, label %if.exit
|
|
|
|
if.then: ; preds = %entry
|
|
%2 = call ptr @malloc(i32 32768)
|
|
store ptr %2, ptr @foo.temp, align 8
|
|
store i32 32768, ptr @foo.remaining, align 4
|
|
%3 = load ptr, ptr @foo.temp, align 8
|
|
ret ptr %3
|
|
|
|
if.exit: ; preds = %entry
|
|
ret ptr null
|
|
}
|
|
|
|
define void @foo.testRetStruct(ptr noalias sret(%PBVTest) align 8 %0, float %1, double %2, i32 %3) #0 {
|
|
entry:
|
|
%t = alloca %PBVTest, align 8
|
|
%fpfpext = fpext float %1 to double
|
|
store double %fpfpext, ptr %t, align 8
|
|
%ptradd = getelementptr inbounds i8, ptr %t, i64 8
|
|
store double %2, ptr %ptradd, align 8
|
|
%ptradd1 = getelementptr inbounds i8, ptr %t, i64 16
|
|
store i32 %3, ptr %ptradd1, align 8
|
|
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %0, ptr align 8 %t, i32 24, i1 false)
|
|
ret void
|
|
}
|
|
|
|
declare void @testRetStruct2(ptr noalias sret(%PBVTest) align 8) #0
|
|
|
|
define double @foo.callRetStruct(float %0, double %1, i32 %2) #0 {
|
|
entry:
|
|
%t = alloca %PBVTest, align 8
|
|
call void @testRetStruct2(ptr sret(%PBVTest) align 8 %t)
|
|
%3 = load double, ptr %t, align 8
|
|
%fpfpext = fpext float %0 to double
|
|
%fadd = fadd double %3, %fpfpext
|
|
%fadd1 = fadd double %fadd, %1
|
|
%sifp = sitofp i32 %2 to double
|
|
%fadd2 = fadd double %fadd1, %sifp
|
|
ret double %fadd2
|
|
}
|
|
|
|
declare i32 @fp(i32, ptr) #0
|
|
|
|
define void @foo.__bb_exit_func() #0 {
|
|
entry:
|
|
%0 = load ptr, ptr @foo.ext, align 8
|
|
%i2b = icmp ne ptr %0, null
|
|
br i1 %i2b, label %cond.lhs, label %cond.rhs
|
|
|
|
cond.lhs: ; preds = %entry
|
|
%1 = load ptr, ptr @foo.ext, align 8
|
|
br label %cond.phi
|
|
|
|
cond.rhs: ; preds = %entry
|
|
br label %cond.phi
|
|
|
|
cond.phi: ; preds = %cond.rhs, %cond.lhs
|
|
%val = phi ptr [ %1, %cond.lhs ], [ @.str, %cond.rhs ]
|
|
%2 = call i32 @fp(i32 12, ptr %val)
|
|
ret void
|
|
}
|
|
|
|
declare i32 @puts(ptr) #0
|
|
|
|
define i32 @foo.ptrFunc(ptr %0, i32 %1) #0 {
|
|
entry:
|
|
%2 = call i32 %0(i32 %1)
|
|
ret i32 %2
|
|
}
|
|
|
|
define zeroext i8 @foo.ptrFunc2(ptr byval([30 x ptr]) align 8 %0, i32 %1) #0 {
|
|
entry:
|
|
%sext = sext i32 %1 to i64
|
|
%ptroffset = getelementptr inbounds [8 x i8], ptr %0, i64 %sext
|
|
%2 = load ptr, ptr %ptroffset, align 8
|
|
%3 = call i32 %2(i32 98)
|
|
%trunc = trunc i32 %3 to i8
|
|
ret i8 %trunc
|
|
}
|
|
|
|
declare zeroext i8 @smallArgs2(i8 zeroext, i8 zeroext, i64, i8 zeroext, i8 zeroext) #0
|
|
|
|
declare i32 @someFuncA() #0
|
|
|
|
define zeroext i8 @foo.smallArgs(i8 zeroext %0, i8 zeroext %1, i8 zeroext %2, i8 zeroext %3) #0 {
|
|
entry:
|
|
%4 = call i32 @someFuncA()
|
|
%zext = zext i8 %0 to i32
|
|
%sub = sub i32 %zext, 1
|
|
%trunc = trunc i32 %sub to i8
|
|
%zext1 = zext i8 %1 to i32
|
|
%add = add i32 %zext1, 1
|
|
%trunc2 = trunc i32 %add to i8
|
|
%zext3 = zext i8 %2 to i64
|
|
%5 = call i8 @smallArgs2(i8 zeroext %trunc, i8 zeroext %trunc2, i64 %zext3, i8 zeroext %3, i8 zeroext %0)
|
|
ret i8 %5
|
|
}
|
|
|
|
define internal i32 @foo.f0(ptr byval(%Quad) align 8 %0, i32 %1) #0 {
|
|
entry:
|
|
%r = alloca %Quad, align 8
|
|
%i2b = icmp ne i32 %1, 0
|
|
br i1 %i2b, label %if.then, label %if.exit
|
|
|
|
if.then: ; preds = %entry
|
|
%ptradd = getelementptr inbounds i8, ptr %0, i64 4
|
|
%ptradd1 = getelementptr inbounds i8, ptr %r, i64 4
|
|
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %ptradd1, ptr align 4 %ptradd, i32 4, i1 false)
|
|
br label %if.exit
|
|
|
|
if.exit: ; preds = %if.then, %entry
|
|
%ptradd2 = getelementptr inbounds i8, ptr %r, i64 4
|
|
%ptradd3 = getelementptr inbounds i8, ptr %0, i64 8
|
|
store ptr %ptradd2, ptr %ptradd3, align 8
|
|
%ptradd4 = getelementptr inbounds i8, ptr %0, i64 16
|
|
store i8 1, ptr %ptradd4, align 8
|
|
%ptradd5 = getelementptr inbounds i8, ptr %0, i64 20
|
|
store i32 1, ptr %ptradd5, align 4
|
|
store i32 1, ptr %0, align 8
|
|
%ptradd6 = getelementptr inbounds i8, ptr %0, i64 4
|
|
%ptradd7 = getelementptr inbounds i8, ptr %ptradd6, i64 2
|
|
%2 = load i16, ptr %ptradd7, align 2
|
|
%sext = sext i16 %2 to i32
|
|
%add = add i32 %sext, %1
|
|
%ptradd8 = getelementptr inbounds i8, ptr %r, i64 20
|
|
%3 = load i32, ptr %ptradd8, align 4
|
|
%add9 = add i32 %add, %3
|
|
%ptradd10 = getelementptr inbounds i8, ptr %0, i64 16
|
|
%4 = load i8, ptr %ptradd10, align 8
|
|
%zext = zext i8 %4 to i32
|
|
%sub = sub i32 %add9, %zext
|
|
ret i32 %sub
|
|
}
|
|
|
|
define i32 @foo.f1(ptr %0, i32 %1) #0 {
|
|
entry:
|
|
%r = alloca %Quad, align 8
|
|
%i2b = icmp ne i32 %1, 0
|
|
br i1 %i2b, label %if.then, label %if.exit
|
|
|
|
if.then: ; preds = %entry
|
|
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %r, ptr align 8 %0, i32 24, i1 false)
|
|
br label %if.exit
|
|
|
|
if.exit: ; preds = %if.then, %entry
|
|
%ptradd = getelementptr inbounds i8, ptr %0, i64 16
|
|
store i8 1, ptr %ptradd, align 8
|
|
%ptradd1 = getelementptr inbounds i8, ptr %0, i64 20
|
|
store i32 1, ptr %ptradd1, align 4
|
|
store i32 1, ptr %0, align 8
|
|
%ptradd2 = getelementptr inbounds i8, ptr %0, i64 4
|
|
%ptradd3 = getelementptr inbounds i8, ptr %ptradd2, i64 2
|
|
%2 = load i16, ptr %ptradd3, align 2
|
|
%sext = sext i16 %2 to i32
|
|
%add = add i32 %sext, %1
|
|
%ptradd4 = getelementptr inbounds i8, ptr %r, i64 20
|
|
%3 = load i32, ptr %ptradd4, align 4
|
|
%add5 = add i32 %add, %3
|
|
%ptradd6 = getelementptr inbounds i8, ptr %0, i64 16
|
|
%4 = load i8, ptr %ptradd6, align 8
|
|
%zext = zext i8 %4 to i32
|
|
%sub = sub i32 %add5, %zext
|
|
ret i32 %sub
|
|
}
|
|
|
|
define i32 @foo.badFunc(float %0) #0 {
|
|
entry:
|
|
%result = alloca i32, align 4
|
|
%fpfpext = fpext float %0 to double
|
|
%gt = fcmp ogt double %fpfpext, 1.234500e+01
|
|
br i1 %gt, label %if.then, label %if.exit
|
|
|
|
if.then: ; preds = %entry
|
|
store i32 4, ptr %result, align 4
|
|
br label %if.exit
|
|
|
|
if.exit: ; preds = %if.then, %entry
|
|
%1 = load i32, ptr %result, align 4
|
|
ret i32 %1
|
|
}
|
|
|
|
declare i32 @ef1(ptr, ptr, ptr) #0
|
|
|
|
define i32 @foo.func(i32 %0, i64 %1) #0 {
|
|
entry:
|
|
%result = alloca i32, align 4
|
|
%c = alloca i8, align 1
|
|
%x = alloca i32, align 4
|
|
%c1 = alloca i8, align 1
|
|
%x2 = alloca i32, align 4
|
|
store i32 %0, ptr %result, align 4
|
|
%2 = call i32 @ef1(ptr %result, ptr %c, ptr %x)
|
|
store i8 0, ptr %c1, align 1
|
|
store i32 0, ptr %x2, align 4
|
|
%3 = call i32 @ef1(ptr %result, ptr %c1, ptr %x2)
|
|
%4 = load i32, ptr %result, align 4
|
|
ret i32 %4
|
|
}
|
|
|
|
define signext i16 @foo.funFunc(i64 %0, i8 zeroext %1) #0 {
|
|
entry:
|
|
%zext = zext i8 %1 to i64
|
|
%add = add i64 %0, %zext
|
|
%trunc = trunc i64 %add to i16
|
|
ret i16 %trunc
|
|
}
|
|
|
|
define i32 @foo.castTest(i32 %0) #0 {
|
|
entry:
|
|
ret i32 %0
|
|
}
|
|
|
|
define double @foo.testAdd(double %0, float %1) #0 {
|
|
entry:
|
|
%fpfpext = fpext float %1 to double
|
|
%fadd = fadd double %0, %fpfpext
|
|
%fadd1 = fadd double %fadd, 5.000000e-01
|
|
ret double %fadd1
|
|
}
|
|
|
|
define i32 @foo.funcZ(i32 %0, i32 %1) #0 {
|
|
entry:
|
|
%i = alloca i32, align 4
|
|
%j = alloca i32, align 4
|
|
store i32 %0, ptr %i, align 4
|
|
store i32 %1, ptr %j, align 4
|
|
br label %loop.cond
|
|
|
|
loop.cond: ; preds = %loop.body, %entry
|
|
%2 = load i32, ptr %i, align 4
|
|
%neq = icmp ne i32 %2, 20
|
|
br i1 %neq, label %loop.body, label %loop.exit
|
|
|
|
loop.body: ; preds = %loop.cond
|
|
%3 = load i32, ptr %i, align 4
|
|
%add = add i32 %3, 2
|
|
store i32 %add, ptr %i, align 4
|
|
br label %loop.cond
|
|
|
|
loop.exit: ; preds = %loop.cond
|
|
%4 = load i32, ptr %j, align 4
|
|
%5 = load i32, ptr %i, align 4
|
|
%6 = call i32 @foo.funcZ(i32 2, i32 %5)
|
|
%add1 = add i32 %4, %6
|
|
store i32 %add1, ptr %j, align 4
|
|
%7 = load i32, ptr %i, align 4
|
|
%mul = mul i32 %7, 3
|
|
%8 = load i32, ptr %j, align 4
|
|
%mul2 = mul i32 %8, 2
|
|
%add3 = add i32 %mul, %mul2
|
|
%9 = load i32, ptr %j, align 4
|
|
%mul4 = mul i32 %add3, %9
|
|
ret i32 %mul4
|
|
}
|
|
|
|
define i32 @foo.sumArray(ptr %0, i32 %1) #0 {
|
|
entry:
|
|
%i = alloca i32, align 4
|
|
%result = alloca i32, align 4
|
|
store i32 0, ptr %result, align 4
|
|
store i32 0, ptr %i, align 4
|
|
br label %loop.cond
|
|
|
|
loop.cond: ; preds = %loop.body, %entry
|
|
%2 = load i32, ptr %i, align 4
|
|
%lt = icmp slt i32 %2, %1
|
|
br i1 %lt, label %loop.body, label %loop.exit
|
|
|
|
loop.body: ; preds = %loop.cond
|
|
%3 = load i32, ptr %result, align 4
|
|
%4 = load i32, ptr %i, align 4
|
|
%sext = sext i32 %4 to i64
|
|
%ptroffset = getelementptr inbounds [4 x i8], ptr %0, i64 %sext
|
|
%5 = load i32, ptr %ptroffset, align 4
|
|
%add = add i32 %3, %5
|
|
store i32 %add, ptr %result, align 4
|
|
%6 = load i32, ptr %i, align 4
|
|
%add1 = add i32 %6, 1
|
|
store i32 %add1, ptr %i, align 4
|
|
br label %loop.cond
|
|
|
|
loop.exit: ; preds = %loop.cond
|
|
%7 = load i32, ptr %result, align 4
|
|
ret i32 %7
|
|
}
|
|
|
|
define i32 @foo.arrayParam(ptr %0) #0 {
|
|
entry:
|
|
%ptradd = getelementptr inbounds i8, ptr %0, i64 200
|
|
%1 = load i32, ptr %ptradd, align 4
|
|
%sext = sext i32 %1 to i64
|
|
%intptr = inttoptr i64 %sext to ptr
|
|
%ptradd1 = getelementptr inbounds i8, ptr %0, i64 200
|
|
%2 = call i32 @ef1(ptr %intptr, ptr inttoptr (i64 1 to ptr), ptr %ptradd1)
|
|
ret i32 %2
|
|
}
|
|
|
|
define i32 @foo.arrayToSum() #0 {
|
|
entry:
|
|
%a = alloca [100 x i32], align 16
|
|
%i = alloca i32, align 4
|
|
store i32 0, ptr %i, align 4
|
|
store i32 0, ptr %i, align 4
|
|
br label %loop.cond
|
|
|
|
loop.cond: ; preds = %loop.body, %entry
|
|
%0 = load i32, ptr %i, align 4
|
|
%lt = icmp slt i32 %0, 100
|
|
br i1 %lt, label %loop.body, label %loop.exit
|
|
|
|
loop.body: ; preds = %loop.cond
|
|
%1 = load i32, ptr %i, align 4
|
|
%mul = mul i32 %1, 4
|
|
%2 = load i32, ptr %i, align 4
|
|
%sext = sext i32 %2 to i64
|
|
%ptroffset = getelementptr inbounds [4 x i8], ptr %a, i64 %sext
|
|
store i32 %mul, ptr %ptroffset, align 4
|
|
%3 = load i32, ptr %i, align 4
|
|
%add = add i32 %3, 1
|
|
store i32 %add, ptr %i, align 4
|
|
br label %loop.cond
|
|
|
|
loop.exit: ; preds = %loop.cond
|
|
%4 = load i32, ptr %a, align 4
|
|
%sext1 = sext i32 %4 to i64
|
|
%ptroffset2 = getelementptr inbounds [4 x i8], ptr %a, i64 %sext1
|
|
%5 = load i32, ptr %ptroffset2, align 4
|
|
ret i32 %5
|
|
}
|
|
|
|
; Function Attrs:
|
|
declare i32 @externFunc(i64, ptr, i16 signext, i8 zeroext) #0
|
|
|
|
; Function Attrs:
|
|
define i32 @main(i32 %0, ptr %1) #0 {
|
|
entry:
|
|
%i = alloca i32, align 4
|
|
%2 = call i32 @puts(ptr @.str.11)
|
|
%trunc = trunc i32 %0 to i16
|
|
%3 = call i32 @externFunc(i64 -1, ptr null, i16 signext %trunc, i8 zeroext 2)
|
|
store i32 0, ptr %i, align 4
|
|
br label %loop.cond
|
|
|
|
loop.cond: ; preds = %loop.body, %entry
|
|
%4 = load i32, ptr %i, align 4
|
|
%gt = icmp ugt i32 10, %4
|
|
br i1 %gt, label %loop.body, label %loop.exit
|
|
|
|
loop.body: ; preds = %loop.cond
|
|
%ptradd = getelementptr inbounds i8, ptr %1, i64 24
|
|
%5 = load ptr, ptr %ptradd, align 8
|
|
%6 = call i32 @puts(ptr %5)
|
|
%7 = load i32, ptr %i, align 4
|
|
%add = add i32 %7, 1
|
|
store i32 %add, ptr %i, align 4
|
|
br label %loop.cond
|
|
|
|
loop.exit: ; preds = %loop.cond
|
|
ret i32 0
|
|
}
|
|
|
|
define double @foo.mathFunc(double %0, double %1, double %2, double %3, double %4, double %5, double %6, double %7, double %8, double %9, double %10, double %11, double %12, double %13, double %14, double %15, double %16) #0 {
|
|
entry:
|
|
%fadd = fadd double %0, %1
|
|
%fadd1 = fadd double %fadd, %2
|
|
%fadd2 = fadd double %fadd1, %3
|
|
%fadd3 = fadd double %fadd2, %4
|
|
%fadd4 = fadd double %fadd3, %5
|
|
%fadd5 = fadd double %fadd4, %6
|
|
%fadd6 = fadd double %fadd5, %7
|
|
%fadd7 = fadd double %fadd6, %8
|
|
%fadd8 = fadd double %fadd7, %9
|
|
%fadd9 = fadd double %fadd8, %10
|
|
%fadd10 = fadd double %fadd9, %11
|
|
%fadd11 = fadd double %fadd10, %12
|
|
%fadd12 = fadd double %fadd11, %13
|
|
%fadd13 = fadd double %fadd12, %14
|
|
%fadd14 = fadd double %fadd13, %15
|
|
%fadd15 = fadd double %fadd14, %16
|
|
ret double %fadd15
|
|
}
|
|
|
|
define void @foo.strcpy(ptr %0, ptr %1) #0 {
|
|
entry:
|
|
%s1 = alloca ptr, align 8
|
|
%s2 = alloca ptr, align 8
|
|
store ptr %0, ptr %s1, align 8
|
|
store ptr %1, ptr %s2, align 8
|
|
br label %loop.cond
|
|
|
|
loop.cond: ; preds = %loop.body, %entry
|
|
%2 = load ptr, ptr %s2, align 8
|
|
%ptradd_any = getelementptr i8, ptr %2, i64 1
|
|
store ptr %ptradd_any, ptr %s2, align 8
|
|
%3 = load ptr, ptr %s1, align 8
|
|
%ptradd_any1 = getelementptr i8, ptr %3, i64 1
|
|
store ptr %ptradd_any1, ptr %s1, align 8
|
|
%4 = load i8, ptr %2, align 1
|
|
store i8 %4, ptr %3, align 1
|
|
%i2b = icmp ne i8 %4, 0
|
|
br i1 %i2b, label %loop.body, label %loop.exit
|
|
|
|
loop.body: ; preds = %loop.cond
|
|
br label %loop.cond
|
|
|
|
loop.exit: ; preds = %loop.cond
|
|
ret void
|
|
}
|
|
|
|
; Function Attrs: nounwind uwtable
|
|
define void @foo.strcat(ptr %0, ptr %1) #0 {
|
|
entry:
|
|
%s1 = alloca ptr, align 8
|
|
%s2 = alloca ptr, align 8
|
|
store ptr %0, ptr %s1, align 8
|
|
store ptr %1, ptr %s2, align 8
|
|
br label %loop.cond
|
|
|
|
loop.cond: ; preds = %loop.body, %entry
|
|
%2 = load ptr, ptr %s1, align 8
|
|
%ptradd_any = getelementptr i8, ptr %2, i64 1
|
|
store ptr %ptradd_any, ptr %s1, align 8
|
|
%3 = load i8, ptr %2, align 1
|
|
%i2b = icmp ne i8 %3, 0
|
|
br i1 %i2b, label %loop.body, label %loop.exit
|
|
|
|
loop.body: ; preds = %loop.cond
|
|
br label %loop.cond
|
|
|
|
loop.exit: ; preds = %loop.cond
|
|
%4 = load ptr, ptr %s1, align 8
|
|
%ptradd_any1 = getelementptr i8, ptr %4, i64 -1
|
|
store ptr %ptradd_any1, ptr %s1, align 8
|
|
br label %loop.cond2
|
|
|
|
loop.cond2: ; preds = %loop.body6, %loop.exit
|
|
%5 = load ptr, ptr %s2, align 8
|
|
%ptradd_any3 = getelementptr i8, ptr %5, i64 1
|
|
store ptr %ptradd_any3, ptr %s2, align 8
|
|
%6 = load ptr, ptr %s1, align 8
|
|
%ptradd_any4 = getelementptr i8, ptr %6, i64 1
|
|
store ptr %ptradd_any4, ptr %s1, align 8
|
|
%7 = load i8, ptr %5, align 1
|
|
store i8 %7, ptr %6, align 1
|
|
%i2b5 = icmp ne i8 %7, 0
|
|
br i1 %i2b5, label %loop.body6, label %loop.exit7
|
|
|
|
loop.body6: ; preds = %loop.cond2
|
|
br label %loop.cond2
|
|
|
|
loop.exit7: ; preds = %loop.cond2
|
|
ret void
|
|
}
|
|
|
|
; Function Attrs: nounwind uwtable
|
|
define i32 @foo.strcmp(ptr %0, ptr %1) #0 {
|
|
entry:
|
|
%s1 = alloca ptr, align 8
|
|
%s2 = alloca ptr, align 8
|
|
store ptr %0, ptr %s1, align 8
|
|
store ptr %1, ptr %s2, align 8
|
|
br label %loop.cond
|
|
|
|
loop.cond: ; preds = %loop.body, %entry
|
|
%2 = load ptr, ptr %s1, align 8
|
|
%ptradd_any = getelementptr i8, ptr %2, i64 1
|
|
store ptr %ptradd_any, ptr %s1, align 8
|
|
%3 = load i8, ptr %2, align 1
|
|
%4 = load ptr, ptr %s2, align 8
|
|
%ptradd_any1 = getelementptr i8, ptr %4, i64 1
|
|
store ptr %ptradd_any1, ptr %s2, align 8
|
|
%5 = load i8, ptr %4, align 1
|
|
%eq = icmp eq i8 %3, %5
|
|
br i1 %eq, label %loop.body, label %loop.exit
|
|
|
|
loop.body: ; preds = %loop.cond
|
|
br label %loop.cond
|
|
|
|
loop.exit: ; preds = %loop.cond
|
|
%6 = load ptr, ptr %s1, align 8
|
|
%7 = load i8, ptr %6, align 1
|
|
%zext = zext i8 %7 to i32
|
|
%eq2 = icmp eq i32 0, %zext
|
|
br i1 %eq2, label %if.then, label %if.else6
|
|
|
|
if.then: ; preds = %loop.exit
|
|
%8 = load ptr, ptr %s2, align 8
|
|
%9 = load i8, ptr %8, align 1
|
|
%zext3 = zext i8 %9 to i32
|
|
%eq4 = icmp eq i32 0, %zext3
|
|
br i1 %eq4, label %if.then5, label %if.else
|
|
|
|
if.then5: ; preds = %if.then
|
|
ret i32 0
|
|
|
|
if.else: ; preds = %if.then
|
|
ret i32 -1
|
|
|
|
if.else6: ; preds = %loop.exit
|
|
%10 = load ptr, ptr %s2, align 8
|
|
%11 = load i8, ptr %10, align 1
|
|
%zext7 = zext i8 %11 to i32
|
|
%eq8 = icmp eq i32 0, %zext7
|
|
br i1 %eq8, label %if.then9, label %if.else10
|
|
|
|
if.then9: ; preds = %if.else6
|
|
ret i32 1
|
|
|
|
if.else10: ; preds = %if.else6
|
|
%12 = load ptr, ptr %s1, align 8
|
|
%ptradd_any11 = getelementptr i8, ptr %12, i64 -1
|
|
store ptr %ptradd_any11, ptr %s1, align 8
|
|
%13 = load i8, ptr %ptradd_any11, align 1
|
|
%zext12 = zext i8 %13 to i32
|
|
%14 = load ptr, ptr %s2, align 8
|
|
%ptradd_any13 = getelementptr i8, ptr %14, i64 -1
|
|
store ptr %ptradd_any13, ptr %s2, align 8
|
|
%15 = load i8, ptr %ptradd_any13, align 1
|
|
%zext14 = zext i8 %15 to i32
|
|
%sub = sub i32 %zext12, %zext14
|
|
ret i32 %sub
|
|
}
|