Some of these are feature tests, not regression tests.

This directory needs to be reorganized and some of the tests
need changes to make them executable.  Also comments would help...


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@2865 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Vikram S. Adve 2002-07-10 21:54:05 +00:00
parent 975f6d4f44
commit a7a1c7e971
20 changed files with 1208 additions and 0 deletions

View File

@ -0,0 +1,28 @@
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

View File

@ -0,0 +1,44 @@
; 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

View File

@ -0,0 +1,33 @@
;;
;; 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

View File

@ -0,0 +1,48 @@
; 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

View File

@ -0,0 +1,30 @@
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

View File

@ -0,0 +1,155 @@
%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

View File

@ -0,0 +1,52 @@
; 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)

74
test/LLC/badfuncptr.c Normal file
View File

@ -0,0 +1,74 @@
/*
* 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;
}

28
test/LLC/badlive.ll Normal file
View File

@ -0,0 +1,28 @@
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

156
test/LLC/callargs.c Normal file
View File

@ -0,0 +1,156 @@
#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;
}

84
test/LLC/casts.c Normal file
View File

@ -0,0 +1,84 @@
#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;
}

44
test/LLC/constindices.ll Normal file
View File

@ -0,0 +1,44 @@
; 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

33
test/LLC/fwdtwice.ll Normal file
View File

@ -0,0 +1,33 @@
;;
;; 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

48
test/LLC/negintconst.ll Normal file
View File

@ -0,0 +1,48 @@
; 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

41
test/LLC/poisson.c Normal file
View File

@ -0,0 +1,41 @@
/* 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;
}

30
test/LLC/sched.ll Normal file
View File

@ -0,0 +1,30 @@
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

155
test/LLC/select.ll Normal file
View File

@ -0,0 +1,155 @@
%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

52
test/LLC/spillccr.ll Normal file
View File

@ -0,0 +1,52 @@
; 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)

44
test/LLC/testtrace.c Normal file
View File

@ -0,0 +1,44 @@
#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;
}

29
test/LLC/varargs.c Normal file
View File

@ -0,0 +1,29 @@
#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;
}