--- /dev/null
+implementation
+
+int "main"()
+begin
+bb0:
+ %reg109 = malloc int, uint 100
+ br label %bb2
+
+bb2:
+ %cann-indvar1 = phi int [ 0, %bb0 ], [ %add1-indvar1, %bb2 ]
+ %reg127 = mul int %cann-indvar1, 2
+ %add1-indvar1 = add int %cann-indvar1, 1
+ store int 999, int * %reg109, uint 0
+ %cond1015 = setle int 1, 99
+ %reg128 = add int %reg127, 2
+ br bool %cond1015, label %bb2, label %bb4
+
+bb4: ;[#uses=3]
+ %cann-indvar = phi uint [ %add1-indvar, %bb4 ], [ 0, %bb2 ]
+ %add1-indvar = add uint %cann-indvar, 1 ; <uint> [#uses=1]
+ store int 333, int * %reg109, uint 0
+ %reg131 = add uint %add1-indvar, 3 ; <int> [#uses=1]
+ %cond1017 = setle uint %reg131, 99 ; <bool> [#uses=1]
+ br bool %cond1017, label %bb4, label %bb5
+
+bb5:
+ ret int 0
+end
--- /dev/null
+; Test that a sequence of constant indices are folded correctly
+; into the equivalent offset at compile-time.
+
+%MixedA = type { float, [15 x int], sbyte, float }
+
+%MixedB = type { float, %MixedA, float }
+
+%fmtArg = internal global [44 x sbyte] c"sqrt(2) = %g\0Aexp(1) = %g\0Api = %g\0Afive = %g\0A\00"; <[44 x sbyte]*> [#uses=1]
+
+implementation
+
+declare int "printf"(sbyte*, ...)
+
+int "main"()
+begin
+ %ScalarA = alloca %MixedA
+ %ScalarB = alloca %MixedB
+ %ArrayA = alloca %MixedA, uint 4
+ %ArrayB = alloca %MixedB, uint 3
+
+ store float 1.4142, %MixedA* %ScalarA, uint 0, ubyte 0
+ store float 2.7183, %MixedB* %ScalarB, uint 0, ubyte 1, ubyte 0
+
+ %fptrA = getelementptr %MixedA* %ArrayA, uint 1, ubyte 0
+ %fptrB = getelementptr %MixedB* %ArrayB, uint 2, ubyte 1, ubyte 0
+
+ store float 3.1415, float* %fptrA
+ store float 5.0, float* %fptrB
+
+ %sqrtTwo = load %MixedA* %ScalarA, uint 0, ubyte 0
+ %exp = load %MixedB* %ScalarB, uint 0, ubyte 1, ubyte 0
+ %pi = load %MixedA* %ArrayA, uint 1, ubyte 0
+ %five = load %MixedB* %ArrayB, uint 2, ubyte 1, ubyte 0
+
+ %dsqrtTwo = cast float %sqrtTwo to double
+ %dexp = cast float %exp to double
+ %dpi = cast float %pi to double
+ %dfive = cast float %five to double
+
+ %castFmt = getelementptr [44 x sbyte]* %fmtArg, uint 0, uint 0
+ call int (sbyte*, ...)* %printf(sbyte* %castFmt, double %dsqrtTwo, double %dexp, double %dpi, double %dfive)
+
+ ret int 0
+end
--- /dev/null
+;;
+;; Test the sequence:
+;; cast -> setle 0, %cast -> br %cond
+;; This sequence should cause the cast value to be forwarded twice,
+;; i.e., cast is forwarded to the setle and teh setle is forwarded
+;; to the branch.
+;; register argument of the "branch-on-register" instruction, i.e.,
+;;
+;; This produces the bogus output instruction:
+;; brlez <NULL VALUE>, .L_SumArray_bb3.
+;; This came from %bb1 of sumarrray.ll generated from sumarray.c.
+
+
+;;;; ******************************************************
+implementation
+;;;; ******************************************************
+
+int "SumArray"(int %Num)
+begin
+bb0: ;[#uses=3]
+ br label %Top
+Top:
+ %Num = alloca int ; <int *> [#uses=2]
+ store int %Num, int * %Num
+ %reg108 = load int * %Num ; <int> [#uses=2]
+ %cast1006 = cast int %reg108 to uint ; <uint> [#uses=1]
+ %cond1001 = setle uint %cast1006, 0 ; <bool> [#uses=1]
+ br bool %cond1001, label %bb6, label %Top
+
+bb6:
+ ret int 42
+end
+
--- /dev/null
+; Test that a negative constant smaller than 64 bits (e.g., int)
+; is correctly implemented with sign-extension.
+; In particular, the current code generated is:
+;
+; main:
+; .L_main_LL_0:
+; save %o6, -224, %o6
+; setx .G_fmtArg_1, %o1, %o0
+; setuw 1, %o1 ! i = 1
+; setuw 4294967295, %o3 ! THE BUG: 0x00000000ffffffff
+; setsw 0, %i0
+; add %i6, 1999, %o2 ! fval
+; add %o1, %g0, %o1
+; add %o0, 0, %o0
+; mulx %o1, %o3, %o1 ! ERROR: 0xffffffff; should be -1
+; add %o1, 3, %o1 ! ERROR: 0x100000002; should be 0x2
+; mulx %o1, 12, %o3 !
+; add %o2, %o3, %o3 ! produces bad address!
+; call printf
+; nop
+; jmpl %i7+8, %g0
+; restore %g0, 0, %g0
+;
+; llc produces:
+; ioff = 2 fval = 0xffffffff7fffec90 &fval[2] = 0xb7fffeca8
+; instead of:
+; ioff = 2 fval = 0xffffffff7fffec90 &fval[2] = 0xffffffff7fffeca8
+;
+
+%Results = type { float, float, float }
+
+%fmtArg = internal global [39 x sbyte] c"ioff = %u\09fval = 0x%p\09&fval[2] = 0x%p\0A\00"; <[39 x sbyte]*> [#uses=1]
+
+implementation
+
+declare int "printf"(sbyte*, ...)
+
+int "main"()
+begin
+ %fval = alloca %Results, uint 4
+ %i = add uint 1, 0 ; i = 1
+ %iscale = mul uint %i, 4294967295 ; i*-1 = -1
+ %ioff = add uint %iscale, 3 ; 3+(-i) = 2
+ %fptr = getelementptr %Results* %fval, uint %ioff ; &fval[2]
+ %castFmt = getelementptr [39 x sbyte]* %fmtArg, uint 0, uint 0
+ call int (sbyte*, ...)* %printf(sbyte* %castFmt, uint %ioff, %Results* %fval, %Results* %fptr)
+ ret int 0
+end
--- /dev/null
+implementation
+declare int "printf"(sbyte*, int, float)
+
+
+int "testissue"(int %i, float %x, float %y)
+begin
+bb1:
+ %x1 = mul float %x, %y ;; x1
+ %y1 = mul float %y, 0.75 ;; y1
+ %z1 = add float %x1, %y1 ;; z1 = x1 + y1
+
+ %x2 = mul float %x, 0.5 ;; x2
+ %y2 = mul float %y, 0.9 ;; y2
+ %z2 = add float %x2, %y2 ;; z2 = x2 + y2
+
+ %z3 = add float %z1, %z2 ;; z3 = z1 + z2
+
+ %i1 = shl int %i, ubyte 3 ;; i1
+ %j1 = add int %i, 7 ;; j1
+ %m1 = add int %i1, %j1 ;; k1 = i1 + j1
+;; %m1 = div int %k1, 99 ;; m1 = k1 / 99
+
+ %b = setle int %m1, 6 ;; (m1 <= 6)?
+ br bool %b, label %bb1, label %bb2
+
+bb2:
+ %Msg = cast ulong 0 to sbyte *
+ call int %printf(sbyte* %Msg, int %m1, float %z3)
+ ret int 0
+end
--- /dev/null
+%AConst = constant int 123
+
+implementation
+
+; Test setting values of different constants in registers.
+;
+void "testConsts"(int %N, float %X)
+begin
+; <label>:0
+ %a = add int %N, 1 ; 1 should be put in immed field
+ %a2= add int %N, 12345678 ; constant has to be loaded
+ %b = add short 4, 3 ; one of the operands shd be immed
+ %c = add float %X, 0.0 ; will this be optimzzed?
+ %d = add float %X, 3.1415 ; constant has to be loaded
+ %f = add uint 4294967295, 10 ; result shd be 9 (not in immed fld)
+ %g = add ushort 20, 65535 ; result shd be 19 (65536 in immed fld)
+ %g = add ushort 65535, 30 ; result shd be 29 (not in immed fld)
+ %h = add ubyte 40, 255 ; result shd be 39 (255 in immed fld)
+ %h = add ubyte 255, 50 ; result shd be 49 (not in immed fld)
+
+ ret void
+end
+
+; A SetCC whose result is used should produce instructions to
+; compute the boolean value in a register. One whose result
+; is unused will only generate the condition code but not
+; the boolean result.
+;
+void "unusedBool"(int * %x, int * %y)
+begin
+; <label>:0 ; [#uses=0]
+ seteq int * %x, %y ; <bool>:0 [#uses=1]
+ not bool %0 ; <bool>:1 [#uses=0]
+ setne int * %x, %y ; <bool>:2 [#uses=0]
+ ret void
+end
+
+; A constant argument to a Phi produces a Cast instruction in the
+; corresponding predecessor basic block. This checks a few things:
+; -- phi arguments coming from the bottom of the same basic block
+; (they should not be forward substituted in the machine code!)
+; -- code generation for casts of various types
+; -- use of immediate fields for integral constants of different sizes
+; -- branch on a constant condition
+;
+void "mergeConstants"(int * %x, int * %y)
+begin
+; <label>:0
+ br label %Top
+Top:
+ phi int [ 0, %0 ], [ 1, %Top ], [ 524288, %Next ]
+ phi float [ 0.0, %0 ], [ 1.0, %Top ], [ 2.0, %Next ]
+ phi double [ 0.5, %0 ], [ 1.5, %Top ], [ 2.5, %Next ]
+ phi bool [ true, %0 ], [ false,%Top ], [ true, %Next ]
+ br bool true, label %Top, label %Next
+Next:
+ br label %Top
+end
+
+
+
+; A constant argument to a cast used only once should be forward substituted
+; and loaded where needed, which happens is:
+; -- User of cast has no immediate field
+; -- User of cast has immediate field but constant is too large to fit
+; or constant is not resolved until later (e.g., global address)
+; -- User of cast uses it as a call arg. or return value so it is an implicit
+; use but has to be loaded into a virtual register so that the reg.
+; allocator can allocate the appropriate phys. reg. for it
+;
+int* "castconst"(float)
+begin
+; <label>:0
+ %castbig = cast ulong 99999999 to int
+ %castsmall = cast ulong 1 to int
+ %usebig = add int %castbig, %castsmall
+
+ %castglob = cast int* %AConst to long*
+ %dummyl = load long* %castglob
+
+ %castnull = cast ulong 0 to int*
+ ret int* %castnull
+end
+
+
+
+; Test branch-on-comparison-with-zero, in two ways:
+; 1. can be folded
+; 2. cannot be folded because result of comparison is used twice
+;
+void "testbool"(int, int) ; Def %0, %1
+ const int 0 ; Def 2
+ const int -4 ; Def 3
+begin
+; <label>:0
+ br label %Top
+Top:
+ add int %0, %1 ; Def 4
+ sub int %4, %3 ; Def 5
+ setle int %5, %2 ; Def 0 - bool plane
+ br bool %0, label %retlbl, label %loop
+
+loop:
+ add int %0, %1 ; Def 6
+ sub int %4, %3 ; Def 7
+ setle int %7, %2 ; Def 1 - bool
+ not bool %1 ; Def 2 - bool. first use of bool %1
+ br bool %1, label %loop, label %Top ; second use of bool %1
+
+retlbl:
+ ret void
+end
+
+
+; Test branch on floating point comparison
+;
+void "testfloatbool"(float %x, float %y) ; Def %0, %1 - float
+begin
+; <label>:0
+ br label %Top
+Top:
+ %p = add float %x, %y ; Def 2 - float
+ %z = sub float %x, %y ; Def 3 - float
+ %b = setle float %p, %z ; Def 0 - bool
+ %c = not bool %b ; Def 1 - bool
+ br bool %b, label %Top, label %goon
+goon:
+ ret void
+end
+
+
+; Test cases where an LLVM instruction requires no machine
+; instructions (e.g., cast int* to long). But there are 2 cases:
+; 1. If the result register has only a single use and the use is in the
+; same basic block, the operand will be copy-propagated during
+; instruction selection.
+; 2. If the result register has multiple uses or is in a different
+; basic block, it cannot (or will not) be copy propagated during
+; instruction selection. It will generate a
+; copy instruction (add-with-0), but this copy should get coalesced
+; away by the register allocator.
+;
+int "checkForward"(int %N, int* %A)
+begin
+
+bb2: ;;<label>
+ %reg114 = shl int %N, ubyte 2 ;;
+ %cast115 = cast int %reg114 to int* ;; reg114 will be propagated
+ %reg116 = add int* %A, %cast115 ;;
+ %reg118 = load int* %reg116 ;;
+ %cast117 = cast int %reg118 to long ;; reg118 will be copied 'cos
+ %reg159 = add long 1234567, %cast117 ;; cast117 has 2 uses, here
+ %reg160 = add long 7654321, %cast117 ;; and here.
+ ret void
+end
--- /dev/null
+; July 6, 2002 -- LLC Regression test
+; This test case checks if the integer CC register %xcc (or %ccr)
+; is correctly spilled. The code fragment came from function
+; MakeGraph in Olden-mst.
+; The original code made all comparisons with 0, so that the %xcc
+; register is not needed for the branch in the first basic block.
+; Replace 0 with 1 in the first comparson so that the
+; branch-on-register instruction cannot be used directly, i.e.,
+; the %xcc register is needed for the first branch.
+;
+ %Graph = type %struct.graph_st*
+ %Hash = type %struct.hash*
+ %HashEntry = type %struct.hash_entry*
+ %Vertex = type %struct.vert_st*
+ %struct.graph_st = type { [1 x %Vertex] }
+ %struct.hash = type { %HashEntry*, int (uint)*, int }
+ %struct.hash_entry = type { uint, sbyte*, %HashEntry }
+ %struct.vert_st = type { int, %Vertex, %Hash }
+%HashRange = internal uninitialized global int ; <int*> [#uses=1]
+%.LC0 = internal global [13 x sbyte] c"Make phase 2\00" ; <[13 x sbyte]*> [#uses=1]
+%.LC1 = internal global [13 x sbyte] c"Make phase 3\00" ; <[13 x sbyte]*> [#uses=1]
+%.LC2 = internal global [13 x sbyte] c"Make phase 4\00" ; <[13 x sbyte]*> [#uses=1]
+%.LC3 = internal global [15 x sbyte] c"Make returning\00" ; <[15 x sbyte]*> [#uses=1]
+
+implementation ; Functions:
+
+%Graph %MakeGraph(int %numvert, int %numproc) {
+bb1: ;[#uses=1]
+ %reg111 = add int %numproc, -1 ; <int> [#uses=3]
+ %cond275 = setlt int %reg111, 1 ; <bool> [#uses=2]
+ %cond276 = setle int %reg111, 0 ; <bool> [#uses=1]
+ %cond277 = setge int %numvert, 0 ; <bool> [#uses=2]
+ %reg162 = add int %numvert, 3 ; <int> [#uses=2]
+ br bool %cond275, label %bb7, label %bb4
+
+bb4:
+ br bool %cond276, label %bb7, label %bb5
+
+bb5:
+ br bool %cond277, label %bb7, label %bb6
+
+bb6: ;[#uses=2]
+ ret %Graph null
+
+bb7: ;[#uses=2]
+ ret %Graph null
+}
+
+int %main(int argc, sbyte** argv) {
+bb1:
+ %reg100 = call %struct.graph_st* (int, int)* %MakeGraph(1, 1)
+
--- /dev/null
+/*
+ * Program: llc
+ *
+ * Test Name: badfuncptr.c
+ *
+ * Test Problem:
+ * Indirect call via function pointer is mishandled in reg. alloc.
+ * The indirect call address was allocated the same register as the
+ * first outgoing argument, so it was overwritten before the call.
+ *
+ * Test Resolution:
+ * In PhyRegAlloc.cpp, mark the live range for the indirect call
+ * address as having a Call Interference. This has to be done
+ * as a special case since it may not be live after the call.
+ *
+ * Resolution Status:
+ * Fixed on 3/29/02 -- Adve.
+ */
+/* For copyright information, see olden_v1.0/COPYRIGHT */
+
+#include <stdlib.h>
+/* #include "hash.h" */
+/*--------*/
+/* hash.h */
+/*--------*/
+/* For copyright information, see olden_v1.0/COPYRIGHT */
+
+#include "stdio.h"
+
+typedef struct hash_entry {
+ unsigned int key;
+ void *entry;
+ struct hash_entry *next;
+} *HashEntry;
+
+typedef struct hash {
+ HashEntry *array;
+ int (*mapfunc)(unsigned int);
+ int size;
+} *Hash;
+
+Hash MakeHash(int size, int (*map)(unsigned int));
+void *HashLookup(unsigned int key, Hash hash);
+void HashInsert(void *entry,unsigned int key, Hash hash);
+void HashDelete(unsigned int key, Hash hash);
+/*--------*/
+/* END hash.h */
+/*--------*/
+
+#define assert(num,a) if (!(a)) {printf("Assertion failure:%d in hash\n",num); exit(-1);}
+
+void *HashLookup(unsigned int key, Hash hash)
+{
+ int j;
+ HashEntry ent;
+
+ j = (hash->mapfunc)(key); /* 14% miss in hash->mapfunc */
+ assert(1,j>=0);
+ assert(2,j<hash->size);
+ for (ent = hash->array[j]; /* 17% miss in hash->array[j] */ /* adt_pf can't detect :( */
+ ent && /* 47% miss in ent->key */ /* adt_pf can detect :) */
+ ent->key!=key;
+ ent=ent->next); /* 8% miss in ent->next */ /* adt_pf can detect :) */
+ if (ent) return ent->entry;
+ return NULL;
+}
+
+/* essentially dummy main so testing does not fail */
+int
+main()
+{
+ printf("&HashLookup = 0x%p\n", HashLookup);
+ return 0;
+}
--- /dev/null
+implementation
+
+int "main"()
+begin
+bb0:
+ %reg109 = malloc int, uint 100
+ br label %bb2
+
+bb2:
+ %cann-indvar1 = phi int [ 0, %bb0 ], [ %add1-indvar1, %bb2 ]
+ %reg127 = mul int %cann-indvar1, 2
+ %add1-indvar1 = add int %cann-indvar1, 1
+ store int 999, int * %reg109, uint 0
+ %cond1015 = setle int 1, 99
+ %reg128 = add int %reg127, 2
+ br bool %cond1015, label %bb2, label %bb4
+
+bb4: ;[#uses=3]
+ %cann-indvar = phi uint [ %add1-indvar, %bb4 ], [ 0, %bb2 ]
+ %add1-indvar = add uint %cann-indvar, 1 ; <uint> [#uses=1]
+ store int 333, int * %reg109, uint 0
+ %reg131 = add uint %add1-indvar, 3 ; <int> [#uses=1]
+ %cond1017 = setle uint %reg131, 99 ; <bool> [#uses=1]
+ br bool %cond1017, label %bb4, label %bb5
+
+bb5:
+ ret int 0
+end
--- /dev/null
+#include <stdio.h>
+#include <stdarg.h>
+
+
+#undef LLVM_CAN_PASS_STRUCTS_BY_VALUE
+#ifdef LLVM_CAN_PASS_STRUCTS_BY_VALUE
+typedef struct SmallStruct_struct {
+ char c1, c2, c3, c4;
+ int n;
+} SmallStruct;
+
+
+typedef struct BigStruct_struct {
+ char c1, c2, c3, c4;
+ double d1, d2; /* Note: d1 will need padding */
+ int n;
+ struct BigStruct_struct* next; /* Note: next will need padding */
+} BigStruct;
+
+
+SmallStruct
+printStructArgs(SmallStruct s1, /* Could fit in reg */
+ int a1, float a2, char a3, double a4, char* a5,
+ BigStruct s2, /* Must go on stack */
+ int a6, float a7, char a8, double a9, char* a10,
+ SmallStruct s3, /* Probably no available regs */
+ int a11, float a12, char a13, double a14, char* a15)
+{
+ SmallStruct result;
+
+ printf("\nprintStructArgs with 13 arguments:\n");
+ printf("\tArg 1 : %c %c %c %c %d\n", s1.c1, s1.c2, s1.c3, s1.c4, s1.n);
+ printf("\tArgs 2-6 : %d %f %c %lf %c\n", a1, a2, a3, a4, *a5);
+ printf("\tArg 7 : %c %c %c %c %lf %lf %d %p\n",
+ s2.c1, s2.c2, s2.c3, s2.c4, s2.d1, s2.d2, s2.n,s2.next);
+ printf("\tArg 8 : %c %c %c %c %d\n", s3.c1, s3.c2, s3.c3, s3.c4, s3.n);
+ printf("\tArgs 9-13 : %d %f %c %lf %c\n", a6, a7, a8, a9, *a10);
+ printf("\tArgs 14-18: %d %f %c %lf %c\n", a11, a12, a13, a14, *a15);
+ printf("\n");
+
+ result.c1 = s2.c1;
+ result.c2 = s2.c2;
+ result.c3 = s2.c3;
+ result.c4 = s2.c4;
+ result.n = s2.n;
+
+ return result;
+}
+#endif /* LLVM_CAN_PASS_STRUCTS_BY_VALUE */
+
+#undef LLC_SUPPORTS_VARARGS_FUNCTIONS
+#ifdef LLC_SUPPORTS_VARARGS_FUNCTIONS
+void
+printVarArgs(int a1, ...)
+{
+ double a2, a7, a12; /* float is promoted to double! */
+ int a3, a8, a13; /* char is promoted to int! */
+ double a4, a9, a14;
+ char *a5, *a10, *a15;
+ int a6, a11;
+
+ va_list ap;
+ va_start(ap, a1);
+ a2 = va_arg(ap, double);
+ a3 = va_arg(ap, int);
+ a4 = va_arg(ap, double);
+ a5 = va_arg(ap, char*);
+
+ a6 = va_arg(ap, int);
+ a7 = va_arg(ap, double);
+ a8 = va_arg(ap, int);
+ a9 = va_arg(ap, double);
+ a10 = va_arg(ap, char*);
+
+ a11 = va_arg(ap, int);
+ a12 = va_arg(ap, double);
+ a13 = va_arg(ap, int);
+ a14 = va_arg(ap, double);
+ a15 = va_arg(ap, char*);
+
+ printf("\nprintVarArgs with 15 arguments:\n");
+ printf("\tArgs 1-5 : %d %f %c %lf %c\n", a1, a2, a3, a4, *a5);
+ printf("\tArgs 6-10 : %d %f %c %lf %c\n", a6, a7, a8, a9, *a10);
+ printf("\tArgs 11-14: %d %f %c %lf %c\n", a11, a12, a13, a14, *a15);
+ printf("\n");
+ return;
+}
+#endif /* LLC_SUPPORTS_VARARGS_FUNCTIONS */
+
+
+void
+printArgsNoRet(int a1, float a2, char a3, double a4, char* a5,
+ int a6, float a7, char a8, double a9, char* a10,
+ int a11, float a12, char a13, double a14, char* a15)
+{
+ printf("\nprintArgsNoRet with 15 arguments:\n");
+ printf("\tArgs 1-5 : %d %f %c %lf %c\n", a1, a2, a3, a4, *a5);
+ printf("\tArgs 6-10 : %d %f %c %lf %c\n", a6, a7, a8, a9, *a10);
+ printf("\tArgs 11-14: %d %f %c %lf %c\n", a11, a12, a13, a14, *a15);
+ printf("\n");
+ return;
+}
+
+
+int
+main(int argc, char** argv)
+{
+#ifdef LLVM_CAN_PASS_STRUCTS_BY_VALUE
+ SmallStruct s1, s3, result;
+ BigStruct s2;
+#endif /* LLVM_CAN_PASS_STRUCTS_BY_VALUE */
+
+ printArgsNoRet(1, 2.1, 'c', 4.1, "e",
+ 6, 7.1, 'h', 9.1, "j",
+ 11, 12.1, 'm', 14.1, "o");
+
+#ifdef LLC_SUPPORTS_VARARGS_FUNCTIONS
+ printVarArgs(1, 2.2, 'c', 4.2, "e",
+ 6, 7.2, 'h', 9.2, "j",
+ 11, 12.2, 'm', 14.2, "o");
+#endif /* LLC_SUPPORTS_VARARGS_FUNCTIONS */
+
+#ifdef LLVM_CAN_PASS_STRUCTS_BY_VALUE
+ s1.c1 = 'a';
+ s1.c2 = 'b';
+ s1.c3 = 'c';
+ s1.c4 = 'd';
+ s1.n = 111;
+
+ s2.c1 = 'h';
+ s2.c2 = 'i';
+ s2.c3 = 'j';
+ s2.c4 = 'k';
+ s2.d1 = 1.1;
+ s2.d2 = 2.2;
+ s2.n = 222;
+ s2.next = &s2;
+
+ s3.c1 = 'w';
+ s3.c2 = 'x';
+ s3.c3 = 'y';
+ s3.c4 = 'z';
+ s3.n = 333;
+
+ result = printStructArgs(s1,
+ 1, 2.0, 'c', 4.0, "e",
+ s2,
+ 6, 7.0, 'h', 9.0, "j",
+ s3);
+
+ printf("\nprintStructArgs returns:\n\t%c %c %c %c %d\n\n",
+ result.c1, result.c2, result.c3, result.c4, result.n);
+#endif /* LLVM_CAN_PASS_STRUCTS_BY_VALUE */
+
+ return 0;
+}
--- /dev/null
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/types.h>
+
+int
+main(int argc, char** argv)
+{
+ char c1;
+ short s1, ssf1, ssd1;
+ uint8_t ubs0;
+ int8_t bs0;
+ unsigned char ubc0, uc2;
+ unsigned short us2, usf1, usd1;
+ int ic3, is3, sif1, sid1;
+ uint uic4, uis4, uif1, uid1;
+ long slf1, sld1;
+ ulong ulf1, uld1;
+ float f1;
+ double d1;
+
+ /* Test integer to integer conversions */
+
+ c1 = (char) (argc >= 2)? atoi(argv[1]) : 0xff64; /* 100 = 'd' */
+ s1 = (short) (argc >= 3)? atoi(argv[2]) : -769; /* 0xf7ff = -769 */
+
+ ubc0 = (unsigned char) c1; /* 100 = 'd' */
+ ubs0 = (uint8_t) s1; /* 0xff = 255 */
+ bs0 = (int8_t) s1; /* 0xff = -1 */
+
+ uc2 = (unsigned char) c1; /* 100 = 'd' */
+ us2 = (unsigned short) s1; /* 0xf7ff = 64767 */
+
+ ic3 = (int) c1; /* 100 = 'd' */
+ is3 = (int) s1; /* 0xfffff7ff = -769 */
+
+ uic4 = (unsigned int) c1; /* 100 = 'd' */
+ uis4 = (unsigned int) s1; /* 0xfffff7ff = 4294966527 */
+
+ printf("ubc0 = '%c'\n", ubc0);
+ printf("ubs0 = %u\n", ubs0);
+ printf("bs0 = %d\n", bs0);
+ printf("c1 = '%c'\n", c1);
+ printf("s1 = %d\n", s1);
+ printf("uc2 = '%c'\n", uc2);
+ printf("us2 = %u\n", us2);
+ printf("ic3 = '%c'\n", ic3);
+ printf("is3 = %d\n", is3);
+ printf("uic4 = '%c'\n", uic4);
+ printf("uis4 = %u\n", uis4);
+
+ /* Test floating-point to integer conversions */
+ f1 = (float) (argc >= 4)? atof(argv[3]) : 1.0;
+ d1 = (argc >= 5)? atof(argv[4]) : 2.0;
+
+ usf1 = (unsigned short) f1;
+ usd1 = (unsigned short) d1;
+ uif1 = (unsigned int) f1;
+ uid1 = (unsigned int) d1;
+ ulf1 = (unsigned long) f1;
+ uld1 = (unsigned long) d1;
+
+ ssf1 = (short) f1;
+ ssd1 = (short) d1;
+ sif1 = (int) f1;
+ sid1 = (int) d1;
+ slf1 = (long) f1;
+ sld1 = (long) d1;
+
+ printf("usf1 = %u\n", usf1);
+ printf("usd1 = %u\n", usd1);
+ printf("uif1 = %u\n", uif1);
+ printf("uid1 = %u\n", uid1);
+ printf("ulf1 = %u\n", ulf1);
+ printf("uld1 = %u\n", uld1);
+
+ printf("ssf1 = %d\n", ssf1);
+ printf("ssd1 = %d\n", ssd1);
+ printf("sif1 = %d\n", sif1);
+ printf("sid1 = %d\n", sid1);
+ printf("slf1 = %d\n", slf1);
+ printf("sld1 = %d\n", sld1);
+
+ return 0;
+}
--- /dev/null
+; Test that a sequence of constant indices are folded correctly
+; into the equivalent offset at compile-time.
+
+%MixedA = type { float, [15 x int], sbyte, float }
+
+%MixedB = type { float, %MixedA, float }
+
+%fmtArg = internal global [44 x sbyte] c"sqrt(2) = %g\0Aexp(1) = %g\0Api = %g\0Afive = %g\0A\00"; <[44 x sbyte]*> [#uses=1]
+
+implementation
+
+declare int "printf"(sbyte*, ...)
+
+int "main"()
+begin
+ %ScalarA = alloca %MixedA
+ %ScalarB = alloca %MixedB
+ %ArrayA = alloca %MixedA, uint 4
+ %ArrayB = alloca %MixedB, uint 3
+
+ store float 1.4142, %MixedA* %ScalarA, uint 0, ubyte 0
+ store float 2.7183, %MixedB* %ScalarB, uint 0, ubyte 1, ubyte 0
+
+ %fptrA = getelementptr %MixedA* %ArrayA, uint 1, ubyte 0
+ %fptrB = getelementptr %MixedB* %ArrayB, uint 2, ubyte 1, ubyte 0
+
+ store float 3.1415, float* %fptrA
+ store float 5.0, float* %fptrB
+
+ %sqrtTwo = load %MixedA* %ScalarA, uint 0, ubyte 0
+ %exp = load %MixedB* %ScalarB, uint 0, ubyte 1, ubyte 0
+ %pi = load %MixedA* %ArrayA, uint 1, ubyte 0
+ %five = load %MixedB* %ArrayB, uint 2, ubyte 1, ubyte 0
+
+ %dsqrtTwo = cast float %sqrtTwo to double
+ %dexp = cast float %exp to double
+ %dpi = cast float %pi to double
+ %dfive = cast float %five to double
+
+ %castFmt = getelementptr [44 x sbyte]* %fmtArg, uint 0, uint 0
+ call int (sbyte*, ...)* %printf(sbyte* %castFmt, double %dsqrtTwo, double %dexp, double %dpi, double %dfive)
+
+ ret int 0
+end
--- /dev/null
+;;
+;; Test the sequence:
+;; cast -> setle 0, %cast -> br %cond
+;; This sequence should cause the cast value to be forwarded twice,
+;; i.e., cast is forwarded to the setle and teh setle is forwarded
+;; to the branch.
+;; register argument of the "branch-on-register" instruction, i.e.,
+;;
+;; This produces the bogus output instruction:
+;; brlez <NULL VALUE>, .L_SumArray_bb3.
+;; This came from %bb1 of sumarrray.ll generated from sumarray.c.
+
+
+;;;; ******************************************************
+implementation
+;;;; ******************************************************
+
+int "SumArray"(int %Num)
+begin
+bb0: ;[#uses=3]
+ br label %Top
+Top:
+ %Num = alloca int ; <int *> [#uses=2]
+ store int %Num, int * %Num
+ %reg108 = load int * %Num ; <int> [#uses=2]
+ %cast1006 = cast int %reg108 to uint ; <uint> [#uses=1]
+ %cond1001 = setle uint %cast1006, 0 ; <bool> [#uses=1]
+ br bool %cond1001, label %bb6, label %Top
+
+bb6:
+ ret int 42
+end
+
--- /dev/null
+; Test that a negative constant smaller than 64 bits (e.g., int)
+; is correctly implemented with sign-extension.
+; In particular, the current code generated is:
+;
+; main:
+; .L_main_LL_0:
+; save %o6, -224, %o6
+; setx .G_fmtArg_1, %o1, %o0
+; setuw 1, %o1 ! i = 1
+; setuw 4294967295, %o3 ! THE BUG: 0x00000000ffffffff
+; setsw 0, %i0
+; add %i6, 1999, %o2 ! fval
+; add %o1, %g0, %o1
+; add %o0, 0, %o0
+; mulx %o1, %o3, %o1 ! ERROR: 0xffffffff; should be -1
+; add %o1, 3, %o1 ! ERROR: 0x100000002; should be 0x2
+; mulx %o1, 12, %o3 !
+; add %o2, %o3, %o3 ! produces bad address!
+; call printf
+; nop
+; jmpl %i7+8, %g0
+; restore %g0, 0, %g0
+;
+; llc produces:
+; ioff = 2 fval = 0xffffffff7fffec90 &fval[2] = 0xb7fffeca8
+; instead of:
+; ioff = 2 fval = 0xffffffff7fffec90 &fval[2] = 0xffffffff7fffeca8
+;
+
+%Results = type { float, float, float }
+
+%fmtArg = internal global [39 x sbyte] c"ioff = %u\09fval = 0x%p\09&fval[2] = 0x%p\0A\00"; <[39 x sbyte]*> [#uses=1]
+
+implementation
+
+declare int "printf"(sbyte*, ...)
+
+int "main"()
+begin
+ %fval = alloca %Results, uint 4
+ %i = add uint 1, 0 ; i = 1
+ %iscale = mul uint %i, 4294967295 ; i*-1 = -1
+ %ioff = add uint %iscale, 3 ; 3+(-i) = 2
+ %fptr = getelementptr %Results* %fval, uint %ioff ; &fval[2]
+ %castFmt = getelementptr [39 x sbyte]* %fmtArg, uint 0, uint 0
+ call int (sbyte*, ...)* %printf(sbyte* %castFmt, uint %ioff, %Results* %fval, %Results* %fptr)
+ ret int 0
+end
--- /dev/null
+/* For copyright information, see olden_v1.0/COPYRIGHT */
+
+/**********************************************************
+ * poisson.c: handles math routines for health.c *
+ **********************************************************/
+
+#include <stdio.h>
+#include <math.h>
+
+/* From health.h */
+#define IA 16807
+#define IM 2147483647
+#define AM (1.0 / IM)
+#define IQ 127773
+#define IR 2836
+#define MASK 123459876
+
+float my_rand(long idum)
+{
+ long k;
+ float answer;
+
+ idum ^= MASK;
+ k = idum / IQ;
+ idum = IA * (idum - k * IQ) - IR * k;
+ idum ^= MASK;
+ if (idum < 0)
+ idum += IM;
+ answer = AM * idum;
+ return answer;
+}
+
+int
+main(int argc, char** argv)
+{
+ printf("my_rand(%d) = %g\n", 2555540, my_rand(2555540));
+ printf("my_rand(%d) = %g\n", 2427763, my_rand(2427763));
+ return 0;
+}
+
+
--- /dev/null
+implementation
+declare int "printf"(sbyte*, int, float)
+
+
+int "testissue"(int %i, float %x, float %y)
+begin
+bb1:
+ %x1 = mul float %x, %y ;; x1
+ %y1 = mul float %y, 0.75 ;; y1
+ %z1 = add float %x1, %y1 ;; z1 = x1 + y1
+
+ %x2 = mul float %x, 0.5 ;; x2
+ %y2 = mul float %y, 0.9 ;; y2
+ %z2 = add float %x2, %y2 ;; z2 = x2 + y2
+
+ %z3 = add float %z1, %z2 ;; z3 = z1 + z2
+
+ %i1 = shl int %i, ubyte 3 ;; i1
+ %j1 = add int %i, 7 ;; j1
+ %m1 = add int %i1, %j1 ;; k1 = i1 + j1
+;; %m1 = div int %k1, 99 ;; m1 = k1 / 99
+
+ %b = setle int %m1, 6 ;; (m1 <= 6)?
+ br bool %b, label %bb1, label %bb2
+
+bb2:
+ %Msg = cast ulong 0 to sbyte *
+ call int %printf(sbyte* %Msg, int %m1, float %z3)
+ ret int 0
+end
--- /dev/null
+%AConst = constant int 123
+
+implementation
+
+; Test setting values of different constants in registers.
+;
+void "testConsts"(int %N, float %X)
+begin
+; <label>:0
+ %a = add int %N, 1 ; 1 should be put in immed field
+ %a2= add int %N, 12345678 ; constant has to be loaded
+ %b = add short 4, 3 ; one of the operands shd be immed
+ %c = add float %X, 0.0 ; will this be optimzzed?
+ %d = add float %X, 3.1415 ; constant has to be loaded
+ %f = add uint 4294967295, 10 ; result shd be 9 (not in immed fld)
+ %g = add ushort 20, 65535 ; result shd be 19 (65536 in immed fld)
+ %g = add ushort 65535, 30 ; result shd be 29 (not in immed fld)
+ %h = add ubyte 40, 255 ; result shd be 39 (255 in immed fld)
+ %h = add ubyte 255, 50 ; result shd be 49 (not in immed fld)
+
+ ret void
+end
+
+; A SetCC whose result is used should produce instructions to
+; compute the boolean value in a register. One whose result
+; is unused will only generate the condition code but not
+; the boolean result.
+;
+void "unusedBool"(int * %x, int * %y)
+begin
+; <label>:0 ; [#uses=0]
+ seteq int * %x, %y ; <bool>:0 [#uses=1]
+ not bool %0 ; <bool>:1 [#uses=0]
+ setne int * %x, %y ; <bool>:2 [#uses=0]
+ ret void
+end
+
+; A constant argument to a Phi produces a Cast instruction in the
+; corresponding predecessor basic block. This checks a few things:
+; -- phi arguments coming from the bottom of the same basic block
+; (they should not be forward substituted in the machine code!)
+; -- code generation for casts of various types
+; -- use of immediate fields for integral constants of different sizes
+; -- branch on a constant condition
+;
+void "mergeConstants"(int * %x, int * %y)
+begin
+; <label>:0
+ br label %Top
+Top:
+ phi int [ 0, %0 ], [ 1, %Top ], [ 524288, %Next ]
+ phi float [ 0.0, %0 ], [ 1.0, %Top ], [ 2.0, %Next ]
+ phi double [ 0.5, %0 ], [ 1.5, %Top ], [ 2.5, %Next ]
+ phi bool [ true, %0 ], [ false,%Top ], [ true, %Next ]
+ br bool true, label %Top, label %Next
+Next:
+ br label %Top
+end
+
+
+
+; A constant argument to a cast used only once should be forward substituted
+; and loaded where needed, which happens is:
+; -- User of cast has no immediate field
+; -- User of cast has immediate field but constant is too large to fit
+; or constant is not resolved until later (e.g., global address)
+; -- User of cast uses it as a call arg. or return value so it is an implicit
+; use but has to be loaded into a virtual register so that the reg.
+; allocator can allocate the appropriate phys. reg. for it
+;
+int* "castconst"(float)
+begin
+; <label>:0
+ %castbig = cast ulong 99999999 to int
+ %castsmall = cast ulong 1 to int
+ %usebig = add int %castbig, %castsmall
+
+ %castglob = cast int* %AConst to long*
+ %dummyl = load long* %castglob
+
+ %castnull = cast ulong 0 to int*
+ ret int* %castnull
+end
+
+
+
+; Test branch-on-comparison-with-zero, in two ways:
+; 1. can be folded
+; 2. cannot be folded because result of comparison is used twice
+;
+void "testbool"(int, int) ; Def %0, %1
+ const int 0 ; Def 2
+ const int -4 ; Def 3
+begin
+; <label>:0
+ br label %Top
+Top:
+ add int %0, %1 ; Def 4
+ sub int %4, %3 ; Def 5
+ setle int %5, %2 ; Def 0 - bool plane
+ br bool %0, label %retlbl, label %loop
+
+loop:
+ add int %0, %1 ; Def 6
+ sub int %4, %3 ; Def 7
+ setle int %7, %2 ; Def 1 - bool
+ not bool %1 ; Def 2 - bool. first use of bool %1
+ br bool %1, label %loop, label %Top ; second use of bool %1
+
+retlbl:
+ ret void
+end
+
+
+; Test branch on floating point comparison
+;
+void "testfloatbool"(float %x, float %y) ; Def %0, %1 - float
+begin
+; <label>:0
+ br label %Top
+Top:
+ %p = add float %x, %y ; Def 2 - float
+ %z = sub float %x, %y ; Def 3 - float
+ %b = setle float %p, %z ; Def 0 - bool
+ %c = not bool %b ; Def 1 - bool
+ br bool %b, label %Top, label %goon
+goon:
+ ret void
+end
+
+
+; Test cases where an LLVM instruction requires no machine
+; instructions (e.g., cast int* to long). But there are 2 cases:
+; 1. If the result register has only a single use and the use is in the
+; same basic block, the operand will be copy-propagated during
+; instruction selection.
+; 2. If the result register has multiple uses or is in a different
+; basic block, it cannot (or will not) be copy propagated during
+; instruction selection. It will generate a
+; copy instruction (add-with-0), but this copy should get coalesced
+; away by the register allocator.
+;
+int "checkForward"(int %N, int* %A)
+begin
+
+bb2: ;;<label>
+ %reg114 = shl int %N, ubyte 2 ;;
+ %cast115 = cast int %reg114 to int* ;; reg114 will be propagated
+ %reg116 = add int* %A, %cast115 ;;
+ %reg118 = load int* %reg116 ;;
+ %cast117 = cast int %reg118 to long ;; reg118 will be copied 'cos
+ %reg159 = add long 1234567, %cast117 ;; cast117 has 2 uses, here
+ %reg160 = add long 7654321, %cast117 ;; and here.
+ ret void
+end
--- /dev/null
+; July 6, 2002 -- LLC Regression test
+; This test case checks if the integer CC register %xcc (or %ccr)
+; is correctly spilled. The code fragment came from function
+; MakeGraph in Olden-mst.
+; The original code made all comparisons with 0, so that the %xcc
+; register is not needed for the branch in the first basic block.
+; Replace 0 with 1 in the first comparson so that the
+; branch-on-register instruction cannot be used directly, i.e.,
+; the %xcc register is needed for the first branch.
+;
+ %Graph = type %struct.graph_st*
+ %Hash = type %struct.hash*
+ %HashEntry = type %struct.hash_entry*
+ %Vertex = type %struct.vert_st*
+ %struct.graph_st = type { [1 x %Vertex] }
+ %struct.hash = type { %HashEntry*, int (uint)*, int }
+ %struct.hash_entry = type { uint, sbyte*, %HashEntry }
+ %struct.vert_st = type { int, %Vertex, %Hash }
+%HashRange = internal uninitialized global int ; <int*> [#uses=1]
+%.LC0 = internal global [13 x sbyte] c"Make phase 2\00" ; <[13 x sbyte]*> [#uses=1]
+%.LC1 = internal global [13 x sbyte] c"Make phase 3\00" ; <[13 x sbyte]*> [#uses=1]
+%.LC2 = internal global [13 x sbyte] c"Make phase 4\00" ; <[13 x sbyte]*> [#uses=1]
+%.LC3 = internal global [15 x sbyte] c"Make returning\00" ; <[15 x sbyte]*> [#uses=1]
+
+implementation ; Functions:
+
+%Graph %MakeGraph(int %numvert, int %numproc) {
+bb1: ;[#uses=1]
+ %reg111 = add int %numproc, -1 ; <int> [#uses=3]
+ %cond275 = setlt int %reg111, 1 ; <bool> [#uses=2]
+ %cond276 = setle int %reg111, 0 ; <bool> [#uses=1]
+ %cond277 = setge int %numvert, 0 ; <bool> [#uses=2]
+ %reg162 = add int %numvert, 3 ; <int> [#uses=2]
+ br bool %cond275, label %bb7, label %bb4
+
+bb4:
+ br bool %cond276, label %bb7, label %bb5
+
+bb5:
+ br bool %cond277, label %bb7, label %bb6
+
+bb6: ;[#uses=2]
+ ret %Graph null
+
+bb7: ;[#uses=2]
+ ret %Graph null
+}
+
+int %main(int argc, sbyte** argv) {
+bb1:
+ %reg100 = call %struct.graph_st* (int, int)* %MakeGraph(1, 1)
+
--- /dev/null
+#include <stdio.h>
+
+/*
+ * Test routines for testing the tracing code.
+ */
+
+struct DummyStruct {
+ struct DummyStruct* next;
+ int seqnum;
+};
+
+int
+AddCounts(struct DummyStruct* S1,
+ struct DummyStruct* S2,
+ struct DummyStruct* S3, int noPrint)
+{
+ if (!noPrint)
+ printf("&S1 = %p\t&S2 = %p\t&S3 = %p\n", S1, S2, S3);
+ return S1->seqnum + S2->seqnum + S3->seqnum;
+}
+
+void
+testAllocaOrder(int noPrint)
+{
+ static int count = 0;
+ struct DummyStruct S1, S2, S3;
+
+ S1.seqnum = ++count;
+ S2.seqnum = ++count;
+ S3.seqnum = ++count;
+
+ printf("sum = %d\n", AddCounts(&S1, &S2, &S3, noPrint));
+}
+
+int
+main(int argc, char** argv)
+{
+ unsigned int i, noPrint = 1;
+ if (argc > 1 && ! strcmp(argv[1], "-d"))
+ noPrint = 0;
+ for (i=0; i < 10; ++i)
+ testAllocaOrder(noPrint);
+ return 0;
+}
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+
+#define A 16807.0
+#define M 2147483647.0
+
+/*
+ * This function calls floor() which does not have a prototype.
+ * Test that the argument to floor is passed correctly.
+ */
+double
+my_rand(double seed)
+{
+ double t = A*seed + 1;
+ double floor();
+
+ seed = t - (M * floor(t / M)); /* t%M if t > M; t otherwise */
+ return seed;
+
+} /* end of random */
+
+
+int
+main(int argc, char** argv)
+{
+ double seed = 123 * ((argc > 1)? atof(argv[1]) : 3.1415926);
+ printf("my_rand(%lf) = %lf\n", seed, my_rand(seed));
+ return 0;
+}