about summary refs log tree commit diff homepage
path: root/test/Concrete
diff options
context:
space:
mode:
Diffstat (limited to 'test/Concrete')
-rw-r--r--test/Concrete/BitwiseOps.ll15
-rw-r--r--test/Concrete/BoolReadWrite.ll13
-rwxr-xr-xtest/Concrete/Casts.ll28
-rw-r--r--test/Concrete/CmpEq.ll14
-rwxr-xr-xtest/Concrete/ConcreteTest.py99
-rw-r--r--test/Concrete/ConstantExpr.ll166
-rw-r--r--test/Concrete/FloatingPointOps.ll685
-rwxr-xr-xtest/Concrete/GlobalInitializers.ll47
-rw-r--r--test/Concrete/GlobalVariable.ll9
-rw-r--r--test/Concrete/ICmp.ll245
-rw-r--r--test/Concrete/InvokeAndReturn.ll18
-rw-r--r--test/Concrete/InvokeAndUnwindOnce.ll18
-rw-r--r--test/Concrete/InvokeAndUnwindTwice.ll22
-rw-r--r--test/Concrete/Makefile55
-rw-r--r--test/Concrete/OneCall.ll12
-rw-r--r--test/Concrete/OverlappingPhiNodes.ll15
-rw-r--r--test/Concrete/Select.ll15
-rw-r--r--test/Concrete/Shifts.ll21
-rw-r--r--test/Concrete/SimpleStoreAndLoad.ll17
-rw-r--r--test/Concrete/UnconditionalBranch.ll10
-rw-r--r--test/Concrete/UnconditionalBranchWithSimplePhi.ll14
-rw-r--r--test/Concrete/UnorderedPhiNodes.ll15
-rw-r--r--test/Concrete/_testingUtils.c32
-rw-r--r--test/Concrete/ackermann.c16
-rw-r--r--test/Concrete/arith_test.ll76
25 files changed, 1677 insertions, 0 deletions
diff --git a/test/Concrete/BitwiseOps.ll b/test/Concrete/BitwiseOps.ll
new file mode 100644
index 00000000..cf5e7e6b
--- /dev/null
+++ b/test/Concrete/BitwiseOps.ll
@@ -0,0 +1,15 @@
+declare void @print_i32(i32)
+
+define i32 @main() {
+	%a = or i32 12345678, 87654321
+	%b = and i32 %a, 87654321
+	%check = xor i32 %b, 87654321
+	%test = icmp eq i32 %check, 0
+	br i1 %test, label %exitTrue, label %exitFalse
+exitTrue:
+	call void @print_i32(i32 1)
+	ret i32 0
+exitFalse:
+	call void @print_i32(i32 0)
+	ret i32 0
+}
diff --git a/test/Concrete/BoolReadWrite.ll b/test/Concrete/BoolReadWrite.ll
new file mode 100644
index 00000000..f37359f8
--- /dev/null
+++ b/test/Concrete/BoolReadWrite.ll
@@ -0,0 +1,13 @@
+declare void @print_i1(i1)
+
+define i32 @main() {
+        %mem = alloca i1
+        store i1 1, i1* %mem
+        %v = load i1* %mem
+        br i1 %v, label %ok, label %exit
+ok:
+	call void @print_i1(i1 %v)
+        br label %exit
+exit:
+	ret i32 0
+}
diff --git a/test/Concrete/Casts.ll b/test/Concrete/Casts.ll
new file mode 100755
index 00000000..1329a127
--- /dev/null
+++ b/test/Concrete/Casts.ll
@@ -0,0 +1,28 @@
+declare void @print_i32(i32)
+
+define i32 @main() {
+entry:
+	%a = add i32 315904, 128
+	%b = trunc i32 %a to i8
+	%c0 = icmp eq i8 %b, 128
+	%d = zext i8 %b to i32
+	%c1 = icmp eq i32 %d, 128
+	%e = sext i8 %b to i32
+	%c2 = icmp eq i32 %e, -128
+	%c0i = zext i1 %c0 to i32
+	%c1i = zext i1 %c1 to i32
+	%c2i = zext i1 %c2 to i32
+	%c0is = shl i32 %c0i, 0
+	%c1is = shl i32 %c1i, 1
+	%c2is = shl i32 %c2i, 2
+	%tmp = add i32 %c0is, %c1is
+	%res = add i32 %tmp, %c2is
+	%p = icmp eq i32 %res, 7
+	br i1 %p, label %exitTrue, label %exitFalse
+exitTrue:
+	call void @print_i32(i32 1)
+	ret i32 0
+exitFalse:
+	call void @print_i32(i32 0)
+	ret i32 0
+}
diff --git a/test/Concrete/CmpEq.ll b/test/Concrete/CmpEq.ll
new file mode 100644
index 00000000..a8c2fe7a
--- /dev/null
+++ b/test/Concrete/CmpEq.ll
@@ -0,0 +1,14 @@
+declare void @print_i32(i32)
+
+define i32 @main() {
+	%a = add i8 0, 1
+	%b = add i8 %a, -1
+	%c = icmp eq i8 %b, 0
+	br i1 %c, label %exitTrue, label %exitFalse
+exitTrue:
+	call void @print_i32(i32 1)
+	ret i32 0
+exitFalse:
+	call void @print_i32(i32 0)
+	ret i32 0
+}
diff --git a/test/Concrete/ConcreteTest.py b/test/Concrete/ConcreteTest.py
new file mode 100755
index 00000000..758d0caa
--- /dev/null
+++ b/test/Concrete/ConcreteTest.py
@@ -0,0 +1,99 @@
+#!/usr/bin/python
+
+import os
+import sys
+import popen2
+
+class TestError(Exception):
+    pass
+
+kLLIPath = '../../llvm/Debug/bin/lli'
+kKleePath = '../../Debug/bin/klee'
+
+def getFiles():
+    for name in os.listdir('.'):
+        if (name[0]!='.' and name[0]!='_' and
+            (name.endswith('.ll') or name.endswith('.c'))):
+            yield name
+
+def readFile(f):
+    s = ""
+    while 1:
+        data = f.read()
+        if not data:
+            break
+        s += data
+    return s
+
+def testFile(name, printOutput=False):
+    baseName,ext = os.path.splitext(name)
+    exeFile = 'Output/linked_%s.bc'%baseName
+    if printOutput:
+        redirectStderr = ''
+    else:
+        redirectStderr = '2> /dev/null'
+
+    if os.system('make %s > /dev/null %s'%(exeFile,redirectStderr)):
+        raise TestError('make failed')
+
+    if printOutput:
+        print '-- running lli --'
+    lli = popen2.Popen3('%s -force-interpreter=true %s %s'%(kLLIPath,exeFile,redirectStderr))
+    lliOut = readFile(lli.fromchild)
+    if lli.wait():
+        raise TestError('lli execution failed')
+
+    if printOutput:
+        print lliOut
+
+    if printOutput:
+        print '-- running klee --'
+    klee = popen2.Popen3('%s --no-output %s %s'%(kKleePath,exeFile,redirectStderr))
+    kleeOut = readFile(klee.fromchild)
+    if klee.wait():
+        raise TestError('klee execution failed')
+    if printOutput:
+        print kleeOut
+        
+    if lliOut!=kleeOut:
+        raise TestError('outputs differ')
+        
+def testOneFile(f, printOutput=False, log=None):
+    try:
+        testFile(f, printOutput)
+        code = ['pass','xpass'][f.startswith('broken')]
+        extra = ''
+    except TestError,e:
+        code = ['fail','xfail'][f.startswith('broken')]
+        extra = str(e)
+
+    print '%s: %s -- %s'%(code,f,extra)
+    if log:
+        print >>log,'%s: %s -- %s'%(code,f,extra)
+
+def test():
+    if not os.path.exists('Output'):
+        os.mkdir('Output')
+    log = open("Output/test.log","w")
+    files = list(getFiles())
+    files.sort(key = lambda n: n.lower())
+    for f in files:
+        testOneFile(f, log=log)
+    log.close()
+
+if __name__=='__main__':
+    args = sys.argv
+    args.pop(0)
+    
+    runAll = not args
+
+    while args:
+        arg = args.pop(0)
+        if arg=='--run':
+            testFile(args.pop(0), printOutput=True)
+        else:
+            raise ValueError,'invalid argument: %s'%arg
+
+    if runAll:
+        test()
+        
diff --git a/test/Concrete/ConstantExpr.ll b/test/Concrete/ConstantExpr.ll
new file mode 100644
index 00000000..2bc33a1e
--- /dev/null
+++ b/test/Concrete/ConstantExpr.ll
@@ -0,0 +1,166 @@
+@gInt = global i32 10
+@gIntWithConstant = global i32 sub(i32 ptrtoint(i32* @gInt to i32), 
+                                 i32 ptrtoint(i32* @gInt to i32))
+
+define void @"test_int_to_ptr"()
+begin
+  %t1 = add i8 ptrtoint(i8* inttoptr(i32 100 to i8*) to i8), 0
+  %t2 = add i32 ptrtoint(i32* inttoptr(i8 100 to i32*) to i32), 0
+  %t3 = add i32 ptrtoint(i32* inttoptr(i64 100 to i32*) to i32), 0
+  %t4 = add i64 ptrtoint(i8* inttoptr(i32 100 to i8*) to i64), 0
+
+  call void @print_i8(i8 %t1)
+  call void @print_i32(i32 %t2)
+  call void @print_i32(i32 %t3)
+  call void @print_i64(i64 %t4)
+    
+  ret void
+end
+
+define void @"test_constant_ops"()
+begin
+  %t1 = add i8 trunc(i64 add(i64 ptrtoint(i32* @gInt to i64), i64 -10) to i8), 10
+  %t2 = sub i64 sext(i32 ptrtoint(i32* @gInt to i32) to i64), ptrtoint(i32* @gInt to i64)
+  %t3 = sub i64 zext(i32 ptrtoint(i32* @gInt to i32) to i64), ptrtoint(i32* @gInt to i64)
+
+  %t4 = icmp eq i8 trunc(i64 ptrtoint(i32* @gInt to i64) to i8), %t1
+  %t5 = zext i1 %t4 to i8
+    
+  call void @print_i8(i8 %t5)
+  call void @print_i64(i64 %t2)
+  call void @print_i64(i64 %t3)
+  
+  ret void
+end
+
+define void @"test_logical_ops"()
+begin
+  %t1 = add i32 -10, and(i32 ptrtoint(i32* @gInt to i32), i32 xor(i32 ptrtoint(i32* @gInt to i32), i32 -1))
+  %t2 = add i32 -10, or(i32 ptrtoint(i32* @gInt to i32), i32 xor(i32 ptrtoint(i32* @gInt to i32), i32 -1))
+  %t3 = add i32 -10, xor(i32 xor(i32 ptrtoint(i32* @gInt to i32), i32 1024),  i32 ptrtoint(i32* @gInt to i32))
+
+  call void @print_i32(i32 %t1)
+  call void @print_i32(i32 %t2)
+  call void @print_i32(i32 %t3)
+  
+  %t4 = shl i32 lshr(i32 ptrtoint(i32* @gInt to i32), i32 8), 8
+  %t5 = shl i32 ashr(i32 ptrtoint(i32* @gInt to i32), i32 8), 8
+  %t6 = lshr i32 shl(i32 ptrtoint(i32* @gInt to i32), i32 8), 8
+  
+  %t7 = icmp eq i32 %t4, %t5     
+  %t8 = icmp ne i32 %t4, %t6     
+  
+  %t9 = zext i1 %t7 to i8
+  %t10 = zext i1 %t8 to i8
+  
+  call void @print_i8(i8 %t9)
+  call void @print_i8(i8 %t10)
+  
+  ret void   
+end
+
+%test.struct.type = type { i32, i32 }
+@test_struct = global %test.struct.type { i32 0, i32 10 }
+
+define void @"test_misc"()
+begin
+  ; probability that @gInt == 100 is very very low 
+  %t1 = add i32 select(i1 icmp eq (i32* @gInt, i32* inttoptr(i32 100 to i32*)), i32 10, i32 0), 0
+  call void @print_i32(i32 %t1)
+
+  %t2 = load i32* getelementptr(%test.struct.type* @test_struct, i32 0, i32 1)
+  call void @print_i32(i32 %t2)                             
+        
+  ret void
+end
+
+define void @"test_simple_arith"()
+begin
+  %t1 = add i32 add(i32 ptrtoint(i32* @gInt to i32), i32 0), 0
+  %t2 = add i32 sub(i32 0, i32 ptrtoint(i32* @gInt to i32)), %t1
+  %t3 = mul i32 mul(i32 ptrtoint(i32* @gInt to i32), i32 10), %t2
+
+  call void @print_i32(i32 %t3)
+
+  ret void     
+end
+
+define void @"test_div_and_mod"()
+begin
+  %t1 = add i32 udiv(i32 ptrtoint(i32* @gInt to i32), i32 13), 0
+  %t2 = add i32 urem(i32 ptrtoint(i32* @gInt to i32), i32 13), 0
+  %t3 = add i32 sdiv(i32 ptrtoint(i32* @gInt to i32), i32 13), 0
+  %t4 = add i32 srem(i32 ptrtoint(i32* @gInt to i32), i32 13), 0
+
+  %p = ptrtoint i32* @gInt to i32
+
+  %i1 = udiv i32 %p, 13
+  %i2 = urem i32 %p, 13
+  %i3 = sdiv i32 %p, 13
+  %i4 = srem i32 %p, 13
+
+  %x1 = sub i32 %t1, %i1
+  %x2 = sub i32 %t2, %i2
+  %x3 = sub i32 %t3, %i3
+  %x4 = sub i32 %t4, %i4
+
+  call void @print_i32(i32 %x1)
+  call void @print_i32(i32 %x2)
+  call void @print_i32(i32 %x3)
+  call void @print_i32(i32 %x4)
+
+  ret void     
+end
+        
+define void @test_cmp()
+begin
+  %t1 = add i8 zext(i1 icmp ult (i32 ptrtoint(i32* @gInt to i32), i32 0) to i8), 1
+  %t2 = add i8 zext(i1 icmp ule (i32 ptrtoint(i32* @gInt to i32), i32 0) to i8), 1
+  %t3 = add i8 zext(i1 icmp uge (i32 ptrtoint(i32* @gInt to i32), i32 0) to i8), 1
+  %t4 = add i8 zext(i1 icmp ugt (i32 ptrtoint(i32* @gInt to i32), i32 0) to i8), 1
+  %t5 = add i8 zext(i1 icmp slt (i32 ptrtoint(i32* @gInt to i32), i32 0) to i8), 1
+  %t6 = add i8 zext(i1 icmp sle (i32 ptrtoint(i32* @gInt to i32), i32 0) to i8), 1
+  %t7 = add i8 zext(i1 icmp sge (i32 ptrtoint(i32* @gInt to i32), i32 0) to i8), 1
+  %t8 = add i8 zext(i1 icmp sgt (i32 ptrtoint(i32* @gInt to i32), i32 0) to i8), 1
+  %t9 = add i8 zext(i1 icmp eq (i32 ptrtoint(i32* @gInt to i32), i32 10) to i8), 1
+  %t10 = add i8 zext(i1 icmp ne (i32 ptrtoint(i32* @gInt to i32), i32 10) to i8), 1
+
+  call void @print_i1(i8 %t1)
+  call void @print_i1(i8 %t2)
+  call void @print_i1(i8 %t3)
+  call void @print_i1(i8 %t4)
+  call void @print_i1(i8 %t5)
+  call void @print_i1(i8 %t6)
+  call void @print_i1(i8 %t7)
+  call void @print_i1(i8 %t8)
+  call void @print_i1(i8 %t9)
+  call void @print_i1(i8 %t10)
+
+  ret void
+end
+
+define i32 @main()
+begin
+    call void @test_simple_arith()
+
+    call void @test_div_and_mod()
+
+    call void @test_cmp()
+ 
+    call void @test_int_to_ptr()
+
+    call void @test_constant_ops()
+
+    call void @test_logical_ops()
+
+    call void @test_misc()
+    
+    ret i32 0
+end
+
+; defined in print_int.c
+declare void @print_i1(i8)
+declare void @print_i8(i8)
+declare void @print_i16(i16)
+declare void @print_i32(i32)
+declare void @print_i64(i64)
diff --git a/test/Concrete/FloatingPointOps.ll b/test/Concrete/FloatingPointOps.ll
new file mode 100644
index 00000000..7f23dcef
--- /dev/null
+++ b/test/Concrete/FloatingPointOps.ll
@@ -0,0 +1,685 @@
+%struct.stdout = type { i32, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, %struct._IO_marker*, %struct.stdout*, i32, i32, i32, i16, i8, [1 x i8], i8*, i64, i8*, i8*, i8*, i8*, i32, i32, [40 x i8] }
+%struct._IO_marker = type { %struct._IO_marker*, %struct.stdout*, i32 }
+@stdout = external global %struct.stdout*
+
+; casting error messages
+@.strTrunc     = internal constant [15 x i8] c"FPTrunc broken\00"
+@.strExt       = internal constant [13 x i8] c"FPExt broken\00"
+@.strFPToUIFlt = internal constant [20 x i8] c"FPToUI float broken\00"
+@.strFPToUIDbl = internal constant [21 x i8] c"FPToUI double broken\00"
+@.strFPToSIFlt = internal constant [20 x i8] c"FPToSI float broken\00"
+@.strFPToSIDbl = internal constant [21 x i8] c"FPToSI double broken\00"
+@.strUIToFPFlt = internal constant [20 x i8] c"UIToFP float broken\00"
+@.strUIToFPDbl = internal constant [21 x i8] c"UIToFP double broken\00"
+@.strSIToFPFlt = internal constant [20 x i8] c"SIToFP float broken\00"
+@.strSIToFPDbl = internal constant [21 x i8] c"SIToFP double broken\00"
+
+; mathematical operator error messages
+@.strDivFlt    = internal constant [18 x i8] c"FDiv float broken\00"
+@.strDivDbl    = internal constant [19 x i8] c"FDiv double broken\00"
+@.strRemFlt    = internal constant [18 x i8] c"FRem float broken\00"
+@.strRemDbl    = internal constant [19 x i8] c"FRem double broken\00"
+@.strAddInt    = internal constant [16 x i8] c"Add ints broken\00"
+@.strAddFlt    = internal constant [18 x i8] c"Add floats broken\00"
+@.strAddDbl    = internal constant [19 x i8] c"Add doubles broken\00"
+@.strSubInt    = internal constant [16 x i8] c"Sub ints broken\00"
+@.strSubFlt    = internal constant [18 x i8] c"Sub floats broken\00"
+@.strSubDbl    = internal constant [19 x i8] c"Sub doubles broken\00"
+@.strMulInt    = internal constant [16 x i8] c"Mul ints broken\00"
+@.strMulFlt    = internal constant [18 x i8] c"Mul floats broken\00"
+@.strMulDbl    = internal constant [19 x i8] c"Mul doubles broken\00"
+
+; fcmp error messages
+@.strCmpTrFlt  = internal constant [19 x i8] c"floats TRUE broken\00" ; fcmp::generic broken msgs
+@.strCmpFaFlt  = internal constant [20 x i8] c"floats FALSE broken\00"
+@.strCmpTrDbl  = internal constant [19 x i8] c"double TRUE broken\00"
+@.strCmpFaDbl  = internal constant [20 x i8] c"double FALSE broken\00"
+@.strCmpEqFlt  = internal constant [17 x i8] c"floats == broken\00" ; fcmp::ordered broken msgs
+@.strCmpGeFlt  = internal constant [17 x i8] c"floats >= broken\00"
+@.strCmpGtFlt  = internal constant [17 x i8] c"floats >  broken\00"
+@.strCmpLeFlt  = internal constant [17 x i8] c"floats <= broken\00"
+@.strCmpLtFlt  = internal constant [17 x i8] c"floats <  broken\00"
+@.strCmpNeFlt  = internal constant [17 x i8] c"floats != broken\00"
+@.strCmpOrdFlt = internal constant [18 x i8] c"floats ORD broken\00"
+@.strCmpEqDbl  = internal constant [18 x i8] c"doubles == broken\00"
+@.strCmpGeDbl  = internal constant [18 x i8] c"doubles >= broken\00"
+@.strCmpGtDbl  = internal constant [18 x i8] c"doubles >  broken\00"
+@.strCmpLeDbl  = internal constant [18 x i8] c"doubles <= broken\00"
+@.strCmpLtDbl  = internal constant [18 x i8] c"doubles <  broken\00"
+@.strCmpNeDbl  = internal constant [18 x i8] c"doubles != broken\00"
+@.strCmpOrdDbl = internal constant [19 x i8] c"doubles ORD broken\00"
+@.strCmpEqFltU = internal constant [17 x i8] c"U:floats==broken\00" ; fcmp::unordered broken msgs
+@.strCmpGeFltU = internal constant [17 x i8] c"U:floats>=broken\00"
+@.strCmpGtFltU = internal constant [17 x i8] c"U:floats> broken\00"
+@.strCmpLeFltU = internal constant [17 x i8] c"U:floats<=broken\00"
+@.strCmpLtFltU = internal constant [17 x i8] c"U:floats< broken\00"
+@.strCmpNeFltU = internal constant [17 x i8] c"U:floats!=broken\00"
+@.strCmpUnoFlt = internal constant [20 x i8] c"U:floats UNO broken\00"
+@.strCmpEqDblU = internal constant [18 x i8] c"U:doubles==broken\00"
+@.strCmpGeDblU = internal constant [18 x i8] c"U:doubles>=broken\00"
+@.strCmpGtDblU = internal constant [18 x i8] c"U:doubles> broken\00"
+@.strCmpLeDblU = internal constant [18 x i8] c"U:doubles<=broken\00"
+@.strCmpLtDblU = internal constant [18 x i8] c"U:doubles< broken\00"
+@.strCmpNeDblU = internal constant [18 x i8] c"U:doubles!=broken\00"
+@.strCmpUnoDbl = internal constant [21 x i8] c"U:doubles UNO broken\00"
+
+@.strWorks     = internal constant [20 x i8] c"Everything works!\0D\0A\00"
+@.strNL        = internal constant [3 x i8]  c"\0D\0A\00"
+
+declare i32 @fprintf(%struct.stdout*, i8*, ...)
+declare void @exit(i32)
+declare void @llvm.memcpy.i32(i8*, i8*, i32, i32)
+
+; if isOk is false, then print errMsg to stdout and exit(1)
+define void @failCheck(i1 %isOk, i8* %errMsg) {
+entry:
+  %fail = icmp eq i1 %isOk, 0
+  br i1 %fail, label %failed, label %return
+
+failed:
+  ; print the error msg
+  %err_stream = load %struct.stdout** @stdout
+  %ret = call i32 (%struct.stdout*, i8*, ...)* @fprintf( %struct.stdout* %err_stream, i8* %errMsg )
+
+  ; add a newline to the ostream
+  %nl = getelementptr [3 x i8]* @.strNL, i32 0, i32 0
+  %ret2 = call i32 (%struct.stdout*, i8*, ...)* @fprintf( %struct.stdout* %err_stream, i8* %nl )
+
+  ; exit with return value 1 to denote that an error occurred
+  call void @exit( i32 1 )
+  unreachable
+
+return:
+  ret void
+}
+
+; test FPTrunc which casts doubles to floats
+define void @testFPTrunc() {
+entry:
+  %d_addr = alloca double, align 8
+  store double 8.000000e+00, double* %d_addr
+  %d = load double* %d_addr
+  %f = fptrunc double %d to float
+  %matches = fcmp oeq float %f, 8.000000e+00
+  %err_msg = getelementptr [15 x i8]* @.strTrunc, i32 0, i32 0
+  call void @failCheck( i1 %matches, i8* %err_msg )
+  ret void
+}
+
+; test FPExt which casts floats to doubles
+define void @testFPExt() {
+entry:
+  %f_addr = alloca float, align 4
+  store float 8.000000e+00, float* %f_addr
+  %f = load float* %f_addr
+  %d = fpext float %f to double
+  %matches = fcmp oeq double %d, 8.000000e+00
+  %err_msg = getelementptr [13 x i8]* @.strExt, i32 0, i32 0
+  call void @failCheck( i1 %matches, i8* %err_msg )
+  ret void
+}
+
+; test casting fp to an unsigned int
+define void @testFPToUI() {
+entry:
+  %f_addr = alloca float, align 4
+  %d_addr = alloca double, align 8
+
+  ; test float to UI
+  store float 0x4020333340000000, float* %f_addr; %f = 8.1
+  %f = load float* %f_addr
+  %uf = fptoui float %f to i32
+  %matchesf = icmp eq i32 %uf, 8
+  %err_msgf = getelementptr [20 x i8]* @.strFPToUIFlt, i32 0, i32 0
+  call void @failCheck( i1 %matchesf, i8* %err_msgf )
+
+  ; test double to UI
+  store double 8.100000e+00, double* %d_addr
+  %d = load double* %d_addr
+  %ud = fptoui double %d to i32
+  %matchesd = icmp eq i32 %ud, 8
+  %err_msgd = getelementptr [21 x i8]* @.strFPToUIDbl, i32 0, i32 0
+  call void @failCheck( i1 %matchesd, i8* %err_msgd )
+
+  ret void
+}
+
+; test casting fp to a signed int
+define void @testFPToSI() {
+entry:
+  %f_addr = alloca float, align 4
+  %d_addr = alloca double, align 8
+
+  ; test float 8.1 to signed int
+  store float 0x4020333340000000, float* %f_addr
+  %f = load float* %f_addr
+  %sf = fptosi float %f to i32
+  %matchesf = icmp eq i32 %sf, 8
+  %err_msgf = getelementptr [20 x i8]* @.strFPToSIFlt, i32 0, i32 0
+  call void @failCheck( i1 %matchesf, i8* %err_msgf )
+
+  ; test double -8.1 to signed int
+  store double -8.100000e+00, double* %d_addr
+  %d = load double* %d_addr
+  %sd = fptosi double %d to i32
+  %matchesd = icmp eq i32 %sd, -8
+  %err_msgd = getelementptr [21 x i8]* @.strFPToSIDbl, i32 0, i32 0
+  call void @failCheck( i1 %matchesd, i8* %err_msgd )
+
+  ret void
+}
+
+; test casting unsigned int to fp
+define void @testUIToFP() {
+entry:
+  ; unsigned int to float
+  %f = uitofp i32 7 to float
+  %matchesf = fcmp oeq float %f, 7.000000e+00
+  %err_msgf = getelementptr [20 x i8]* @.strUIToFPFlt, i32 0, i32 0
+  call void @failCheck( i1 %matchesf, i8* %err_msgf )
+
+  ; unsigned int to double
+  %d = uitofp i32 7 to double
+  %matchesd = fcmp oeq double %d, 7.000000e+00
+  %err_msgd = getelementptr [21 x i8]* @.strUIToFPDbl, i32 0, i32 0
+  call void @failCheck( i1 %matchesd, i8* %err_msgd )
+
+  ret void
+}
+
+; test casting signed int to fp
+define void @testSIToFP() {
+entry:
+  ; signed int to float
+  %f = sitofp i32 -7 to float
+  %matchesf = fcmp oeq float %f, -7.000000e+00
+  %err_msgf = getelementptr [20 x i8]* @.strSIToFPFlt, i32 0, i32 0
+  call void @failCheck( i1 %matchesf, i8* %err_msgf )
+
+  ; signed int to double
+  %d = sitofp i32 -7 to double
+  %matchesd = fcmp oeq double %d, -7.000000e+00
+  %err_msgd = getelementptr [21 x i8]* @.strSIToFPDbl, i32 0, i32 0
+  call void @failCheck( i1 %matchesd, i8* %err_msgd )
+
+  ret void
+}
+
+; testing fp division
+define void @testFDiv() {
+entry:
+  %fN_addr = alloca float, align 4
+  %fD_addr = alloca float, align 4
+  %dN_addr = alloca double, align 8
+  %dD_addr = alloca double, align 8
+
+  ; float division
+  store float 2.200000e+01, float* %fN_addr
+  store float 4.000000e+00, float* %fD_addr
+  %fN = load float* %fN_addr
+  %fD = load float* %fD_addr
+  %f = fdiv float %fN, %fD
+  %matchesf = fcmp oeq float %f, 5.500000e+00
+  %err_msgf = getelementptr [18 x i8]* @.strDivFlt, i32 0, i32 0
+  call void @failCheck( i1 %matchesf, i8* %err_msgf )
+
+  ; double division
+  store double 2.200000e+01, double* %dN_addr
+  store double -4.000000e+00, double* %dD_addr
+  %dN = load double* %dN_addr
+  %dD = load double* %dD_addr
+  %d = fdiv double %dN, %dD
+  %matchesd = fcmp oeq double %d, -5.500000e+00
+  %err_msgd = getelementptr [19 x i8]* @.strDivDbl, i32 0, i32 0
+  call void @failCheck( i1 %matchesd, i8* %err_msgd )
+
+  ret void
+}
+
+; testing fp modulo
+define void @testFRem() {
+entry:
+  %fN_addr = alloca float, align 4
+  %fD_addr = alloca float, align 4
+  %dN_addr = alloca double, align 8
+  %dD_addr = alloca double, align 8
+
+  ; float modoulo
+  store float 2.200000e+01, float* %fN_addr
+  store float 4.000000e+00, float* %fD_addr
+  %fN = load float* %fN_addr
+  %fD = load float* %fD_addr
+  %f = frem float %fN, %fD
+  %matchesf = fcmp oeq float %f, 2.000000e+00
+  %err_msgf = getelementptr [18 x i8]* @.strRemFlt, i32 0, i32 0
+  call void @failCheck( i1 %matchesf, i8* %err_msgf )
+
+  ; double modulo
+  store double -2.200000e+01, double* %dN_addr
+  store double 4.000000e+00, double* %dD_addr
+  %dN = load double* %dN_addr
+  %dD = load double* %dD_addr
+  %d = frem double %dN, %dD
+  %matchesd = fcmp oeq double %d, -2.000000e+00
+  %err_msgd = getelementptr [19 x i8]* @.strRemDbl, i32 0, i32 0
+  call void @failCheck( i1 %matchesd, i8* %err_msgd )
+
+  ret void
+}
+
+; test addition (fp and int since add is polymorphic)
+define void @testAdd() {
+entry:
+  %f1_addr = alloca float, align 4
+  %f2_addr = alloca float, align 4
+  %d1_addr = alloca double, align 8
+  %d2_addr = alloca double, align 8
+
+  ; test integer addition (3 + 4)
+  %sumi = add i32 3, 4
+  %matchesi = icmp eq i32 %sumi, 7
+  %err_msgi = getelementptr [16 x i8]* @.strAddInt, i32 0, i32 0
+  call void @failCheck( i1 %matchesi, i8* %err_msgi )
+
+  ; test float addition (3.5 + 4.2)
+  store float 3.500000e+00, float* %f1_addr
+  store float 0x4010CCCCC0000000, float* %f2_addr
+  %f1 = load float* %f1_addr
+  %f2 = load float* %f2_addr
+  %sumf = add float %f1, %f2
+  %matchesf = fcmp oeq float %sumf, 0x401ECCCCC0000000
+  %err_msgf = getelementptr [18 x i8]* @.strAddFlt, i32 0, i32 0
+  call void @failCheck( i1 %matchesf, i8* %err_msgf )
+
+  ; test double addition (3.5 + -4.2)
+  store double 3.500000e+00, double* %d1_addr
+  store double -4.200000e+00, double* %d2_addr
+  %d1 = load double* %d1_addr
+  %d2 = load double* %d2_addr
+  %sumd = add double %d1, %d2
+  %matchesd = fcmp oeq double %sumd, 0xBFE6666666666668
+  %err_msgd = getelementptr [19 x i8]* @.strAddDbl, i32 0, i32 0
+  call void @failCheck( i1 %matchesd, i8* %err_msgd )
+
+  ret void
+}
+
+; test subtraction (fp and int since sub is polymorphic)
+define void @testSub() {
+entry:
+  %f1_addr = alloca float, align 4
+  %f2_addr = alloca float, align 4
+  %d1_addr = alloca double, align 8
+  %d2_addr = alloca double, align 8
+
+  ; test integer subtraction (3 - 4)
+  %subi = sub i32 3, 4
+  %matchesi = icmp eq i32 %subi, -1
+  %err_msgi = getelementptr [16 x i8]* @.strSubInt, i32 0, i32 0
+  call void @failCheck( i1 %matchesi, i8* %err_msgi )
+
+  ; test float subtraction (3.5 - 4.2)
+  store float 3.500000e+00, float* %f1_addr
+  store float 0x4010CCCCC0000000, float* %f2_addr
+  %f1 = load float* %f1_addr
+  %f2 = load float* %f2_addr
+  %subf = sub float %f1, %f2
+  %matchesf = fcmp oeq float %subf, 0xBFE6666600000000
+  %err_msgf = getelementptr [18 x i8]* @.strSubFlt, i32 0, i32 0
+  call void @failCheck( i1 %matchesf, i8* %err_msgf )
+
+  ; test double subtraction (3.5 - -4.2)
+  store double 3.500000e+00, double* %d1_addr
+  store double -4.200000e+00, double* %d2_addr
+  %d1 = load double* %d1_addr
+  %d2 = load double* %d2_addr
+  %subd = sub double %d1, %d2
+  %matchesd = fcmp oeq double %subd, 7.700000e+00
+  %err_msgd = getelementptr [19 x i8]* @.strSubDbl, i32 0, i32 0
+  call void @failCheck( i1 %matchesd, i8* %err_msgd )
+
+  ret void
+}
+
+; test multiplication (fp and int since mul is polymorphic)
+define void @testMul() {
+entry:
+  %f1_addr = alloca float, align 4
+  %f2_addr = alloca float, align 4
+  %d1_addr = alloca double, align 8
+  %d2_addr = alloca double, align 8
+
+  ; test integer multiplication (3 * 4)
+  %muli = mul i32 3, 4
+  %matchesi = icmp eq i32 %muli, 12
+  %err_msgi = getelementptr [16 x i8]* @.strMulInt, i32 0, i32 0
+  call void @failCheck( i1 %matchesi, i8* %err_msgi )
+
+  ; test float multiplication (3.5 * 4.2)
+  store float 3.500000e+00, float* %f1_addr
+  store float 0x4010CCCCC0000000, float* %f2_addr
+  %f1 = load float* %f1_addr
+  %f2 = load float* %f2_addr
+  %mulf = mul float %f1, %f2
+  %matchesf = fcmp oeq float %mulf, 0x402D666640000000
+  %err_msgf = getelementptr [18 x i8]* @.strMulFlt, i32 0, i32 0
+  call void @failCheck( i1 %matchesf, i8* %err_msgf )
+
+  ; test double multiplication (3.5 * -4.2)
+  store double 3.500000e+00, double* %d1_addr
+  store double -4.200000e+00, double* %d2_addr
+  %d1 = load double* %d1_addr
+  %d2 = load double* %d2_addr
+  %muld = mul double %d1, %d2
+  %matchesd = fcmp oeq double %muld, 0xC02D666666666667
+  %err_msgd = getelementptr [19 x i8]* @.strMulDbl, i32 0, i32 0
+  call void @failCheck( i1 %matchesd, i8* %err_msgd )
+
+  ret void
+}
+
+; test float comparisons (ordered)
+define void @testFCmpFOrdered(float %f1, float %f2, i1 %eq, i1 %ge, i1 %gt, i1 %le, i1 %lt, i1 %ne, i1 %ord) {
+entry:
+  ; test fcmp::true -- should always return true
+  %cmp_t    = fcmp true float %f1, %f2
+  %cmp_t_ok = icmp eq i1 %cmp_t, 1
+  %cmp_t_em = getelementptr [19 x i8]* @.strCmpTrFlt, i32 0, i32 0
+  call void @failCheck( i1 %cmp_t_ok, i8* %cmp_t_em )
+
+  ; test fcmp::false -- should always return false
+  %cmp_f    = fcmp false float %f1, %f2
+  %cmp_f_ok = icmp eq i1 %cmp_f, 0
+  %cmp_f_em = getelementptr [20 x i8]* @.strCmpFaFlt, i32 0, i32 0
+  call void @failCheck( i1 %cmp_f_ok, i8* %cmp_f_em )
+
+  ; test fcmp::ord -- should return true if neither operand is NaN
+  %cmp_o    = fcmp ord float %f1, %f2
+  %cmp_o_ok = icmp eq i1 %cmp_o, %ord
+  %cmp_o_em = getelementptr [18 x i8]* @.strCmpOrdFlt, i32 0, i32 0
+  call void @failCheck( i1 %cmp_o_ok, i8* %cmp_o_em )
+
+  ; test fcmp::oeq -- should return true if neither operand is a NaN and they are equal
+  %cmp_eq    = fcmp oeq float %f1, %f2
+  %cmp_eq_ok = icmp eq i1 %cmp_eq, %eq
+  %cmp_eq_em = getelementptr [17 x i8]* @.strCmpEqFlt, i32 0, i32 0
+  call void @failCheck( i1 %cmp_eq_ok, i8* %cmp_eq_em )
+
+  ; test fcmp::oge -- should return true if neither operand is a NaN and the first is greater or equal
+  %cmp_ge    = fcmp oge float %f1, %f2
+  %cmp_ge_ok = icmp eq i1 %cmp_ge, %ge
+  %cmp_ge_em = getelementptr [17 x i8]* @.strCmpGeFlt, i32 0, i32 0
+  call void @failCheck( i1 %cmp_ge_ok, i8* %cmp_ge_em )
+
+  ; test fcmp::ogt -- should return true if neither operand is a NaN and the first is greater
+  %cmp_gt    = fcmp ogt float %f1, %f2
+  %cmp_gt_ok = icmp eq i1 %cmp_gt, %gt
+  %cmp_gt_em = getelementptr [17 x i8]* @.strCmpGtFlt, i32 0, i32 0
+  call void @failCheck( i1 %cmp_gt_ok, i8* %cmp_gt_em )
+
+  ; test fcmp::ole -- should return true if neither operand is a NaN and the first is less or equal
+  %cmp_le    = fcmp ole float %f1, %f2
+  %cmp_le_ok = icmp eq i1 %cmp_le, %le
+  %cmp_le_em = getelementptr [17 x i8]* @.strCmpLeFlt, i32 0, i32 0
+  call void @failCheck( i1 %cmp_le_ok, i8* %cmp_le_em )
+
+  ; test fcmp::olt -- should return true if neither operand is a NaN and the first is less
+  %cmp_lt    = fcmp olt float %f1, %f2
+  %cmp_lt_ok = icmp eq i1 %cmp_lt, %lt
+  %cmp_lt_em = getelementptr [17 x i8]* @.strCmpLtFlt, i32 0, i32 0
+  call void @failCheck( i1 %cmp_lt_ok, i8* %cmp_lt_em )
+
+  ; test fcmp::one -- should return true if neither operand is a NaN and they are not equal
+  %cmp_ne    = fcmp one float %f1, %f2
+  %cmp_ne_ok = icmp eq i1 %cmp_ne, %ne
+  %cmp_ne_em = getelementptr [17 x i8]* @.strCmpNeFlt, i32 0, i32 0
+  call void @failCheck( i1 %cmp_ne_ok, i8* %cmp_ne_em )
+
+  ret void
+}
+
+; test double comparisons (ordered)
+define void @testFCmpDOrdered(double %d1, double %d2, i1 %eq, i1 %ge, i1 %gt, i1 %le, i1 %lt, i1 %ne, i1 %ord) {
+entry:
+  ; test fcmp::true -- should always return true
+  %cmp_t    = fcmp true double %d1, %d2
+  %cmp_t_ok = icmp eq i1 %cmp_t, 1
+  %cmp_t_em = getelementptr [19 x i8]* @.strCmpTrDbl, i32 0, i32 0
+  call void @failCheck( i1 %cmp_t_ok, i8* %cmp_t_em )
+
+  ; test fcmp::false -- should always return false
+  %cmp_f    = fcmp false double %d1, %d2
+  %cmp_f_ok = icmp eq i1 %cmp_f, 0
+  %cmp_f_em = getelementptr [20 x i8]* @.strCmpFaDbl, i32 0, i32 0
+  call void @failCheck( i1 %cmp_f_ok, i8* %cmp_f_em )
+
+  ; test fcmp::ord -- should return true if neither operand is NaN
+  %cmp_o    = fcmp ord double %d1, %d2
+  %cmp_o_ok = icmp eq i1 %cmp_o, %ord
+  %cmp_o_em = getelementptr [19 x i8]* @.strCmpOrdDbl, i32 0, i32 0
+  call void @failCheck( i1 %cmp_o_ok, i8* %cmp_o_em )
+
+  ; test fcmp::oeq -- should return true if neither operand is a NaN and they are equal
+  %cmp_eq    = fcmp oeq double %d1, %d2
+  %cmp_eq_ok = icmp eq i1 %cmp_eq, %eq
+  %cmp_eq_em = getelementptr [18 x i8]* @.strCmpEqDbl, i32 0, i32 0
+  call void @failCheck( i1 %cmp_eq_ok, i8* %cmp_eq_em )
+
+  ; test fcmp::oge -- should return true if neither operand is a NaN and the first is greater or equal
+  %cmp_ge    = fcmp oge double %d1, %d2
+  %cmp_ge_ok = icmp eq i1 %cmp_ge, %ge
+  %cmp_ge_em = getelementptr [18 x i8]* @.strCmpGeDbl, i32 0, i32 0
+  call void @failCheck( i1 %cmp_ge_ok, i8* %cmp_ge_em )
+
+  ; test fcmp::ogt -- should return true if neither operand is a NaN and the first is greater
+  %cmp_gt    = fcmp ogt double %d1, %d2
+  %cmp_gt_ok = icmp eq i1 %cmp_gt, %gt
+  %cmp_gt_em = getelementptr [18 x i8]* @.strCmpGtDbl, i32 0, i32 0
+  call void @failCheck( i1 %cmp_gt_ok, i8* %cmp_gt_em )
+
+  ; test fcmp::ole -- should return true if neither operand is a NaN and the first is less or equal
+  %cmp_le    = fcmp ole double %d1, %d2
+  %cmp_le_ok = icmp eq i1 %cmp_le, %le
+  %cmp_le_em = getelementptr [18 x i8]* @.strCmpLeDbl, i32 0, i32 0
+  call void @failCheck( i1 %cmp_le_ok, i8* %cmp_le_em )
+
+  ; test fcmp::olt -- should return true if neither operand is a NaN and the first is less
+  %cmp_lt    = fcmp olt double %d1, %d2
+  %cmp_lt_ok = icmp eq i1 %cmp_lt, %lt
+  %cmp_lt_em = getelementptr [18 x i8]* @.strCmpLtDbl, i32 0, i32 0
+  call void @failCheck( i1 %cmp_lt_ok, i8* %cmp_lt_em )
+
+  ; test fcmp::one -- should return true if neither operand is a NaN and they are not equal
+  %cmp_ne    = fcmp one double %d1, %d2
+  %cmp_ne_ok = icmp eq i1 %cmp_ne, %ne
+  %cmp_ne_em = getelementptr [18 x i8]* @.strCmpNeDbl, i32 0, i32 0
+  call void @failCheck( i1 %cmp_ne_ok, i8* %cmp_ne_em )
+
+  ret void
+}
+
+; test floating point comparisons (ordered)
+define void @testFCmpBothOrdered(double %d1, double %d2, i1 %eq, i1 %ge, i1 %gt, i1 %le, i1 %lt, i1 %ne, i1 %ord) {
+entry:
+  call void @testFCmpDOrdered( double %d1, double %d2, i1 %eq, i1 %ge, i1 %gt, i1 %le, i1 %lt, i1 %ne, i1 %ord )
+
+  %f1 = fptrunc double %d1 to float
+  %f2 = fptrunc double %d2 to float
+  call void @testFCmpFOrdered( float %f1, float %f2, i1 %eq, i1 %ge, i1 %gt, i1 %le, i1 %lt, i1 %ne, i1 %ord )
+
+  ret void
+}
+
+; test float comparisons (unordered)
+define void @testFCmpFUnordered(float %f1, float %f2, i1 %eq, i1 %ge, i1 %gt, i1 %le, i1 %lt, i1 %ne, i1 %uno) {
+entry:
+  ; test fcmp::uno -- should return true if either operand is NaN
+  %cmp_o    = fcmp uno float %f1, %f2
+  %cmp_o_ok = icmp eq i1 %cmp_o, %uno
+  %cmp_o_em = getelementptr [20 x i8]* @.strCmpUnoFlt, i32 0, i32 0
+  call void @failCheck( i1 %cmp_o_ok, i8* %cmp_o_em )
+
+  ; test fcmp::oeq -- should return true if either operand is a NaN and they are equal
+  %cmp_eq    = fcmp ueq float %f1, %f2
+  %cmp_eq_ok = icmp eq i1 %cmp_eq, %eq
+  %cmp_eq_em = getelementptr [17 x i8]* @.strCmpEqFltU, i32 0, i32 0
+  call void @failCheck( i1 %cmp_eq_ok, i8* %cmp_eq_em )
+
+  ; test fcmp::oge -- should return true if either operand is a NaN and the first is greater or equal
+  %cmp_ge    = fcmp uge float %f1, %f2
+  %cmp_ge_ok = icmp eq i1 %cmp_ge, %ge
+  %cmp_ge_em = getelementptr [17 x i8]* @.strCmpGeFltU, i32 0, i32 0
+  call void @failCheck( i1 %cmp_ge_ok, i8* %cmp_ge_em )
+
+  ; test fcmp::ogt -- should return true if either operand is a NaN and the first is greater
+  %cmp_gt    = fcmp ugt float %f1, %f2
+  %cmp_gt_ok = icmp eq i1 %cmp_gt, %gt
+  %cmp_gt_em = getelementptr [17 x i8]* @.strCmpGtFltU, i32 0, i32 0
+  call void @failCheck( i1 %cmp_gt_ok, i8* %cmp_gt_em )
+
+  ; test fcmp::ole -- should return true if either operand is a NaN and the first is less or equal
+  %cmp_le    = fcmp ule float %f1, %f2
+  %cmp_le_ok = icmp eq i1 %cmp_le, %le
+  %cmp_le_em = getelementptr [17 x i8]* @.strCmpLeFltU, i32 0, i32 0
+  call void @failCheck( i1 %cmp_le_ok, i8* %cmp_le_em )
+
+  ; test fcmp::olt -- should return true if either operand is a NaN and the first is less
+  %cmp_lt    = fcmp ult float %f1, %f2
+  %cmp_lt_ok = icmp eq i1 %cmp_lt, %lt
+  %cmp_lt_em = getelementptr [17 x i8]* @.strCmpLtFltU, i32 0, i32 0
+  call void @failCheck( i1 %cmp_lt_ok, i8* %cmp_lt_em )
+
+  ; test fcmp::one -- should return true if either operand is a NaN and they are not equal
+  %cmp_ne    = fcmp une float %f1, %f2
+  %cmp_ne_ok = icmp eq i1 %cmp_ne, %ne
+  %cmp_ne_em = getelementptr [17 x i8]* @.strCmpNeFltU, i32 0, i32 0
+  call void @failCheck( i1 %cmp_ne_ok, i8* %cmp_ne_em )
+
+  ret void
+}
+
+; test double comparisons (unordered)
+define void @testFCmpDUnordered(double %d1, double %d2, i1 %eq, i1 %ge, i1 %gt, i1 %le, i1 %lt, i1 %ne, i1 %uno) {
+entry:
+  ; test fcmp::uno -- should return true if either operand is NaN
+  %cmp_o    = fcmp uno double %d1, %d2
+  %cmp_o_ok = icmp eq i1 %cmp_o, %uno
+  %cmp_o_em = getelementptr [21 x i8]* @.strCmpUnoDbl, i32 0, i32 0
+  call void @failCheck( i1 %cmp_o_ok, i8* %cmp_o_em )
+
+  ; test fcmp::ueq -- should return true if either operand is a NaN and they are equal
+  %cmp_eq    = fcmp ueq double %d1, %d2
+  %cmp_eq_ok = icmp eq i1 %cmp_eq, %eq
+  %cmp_eq_em = getelementptr [18 x i8]* @.strCmpEqDblU, i32 0, i32 0
+  call void @failCheck( i1 %cmp_eq_ok, i8* %cmp_eq_em )
+
+  ; test fcmp::uge -- should return true if either operand is a NaN and the first is greater or equal
+  %cmp_ge    = fcmp uge double %d1, %d2
+  %cmp_ge_ok = icmp eq i1 %cmp_ge, %ge
+  %cmp_ge_em = getelementptr [18 x i8]* @.strCmpGeDblU, i32 0, i32 0
+  call void @failCheck( i1 %cmp_ge_ok, i8* %cmp_ge_em )
+
+  ; test fcmp::ugt -- should return true if either operand is a NaN and the first is greater
+  %cmp_gt    = fcmp ugt double %d1, %d2
+  %cmp_gt_ok = icmp eq i1 %cmp_gt, %gt
+  %cmp_gt_em = getelementptr [18 x i8]* @.strCmpGtDblU, i32 0, i32 0
+  call void @failCheck( i1 %cmp_gt_ok, i8* %cmp_gt_em )
+
+  ; test fcmp::ule -- should return true if either operand is a NaN and the first is less or equal
+  %cmp_le    = fcmp ule double %d1, %d2
+  %cmp_le_ok = icmp eq i1 %cmp_le, %le
+  %cmp_le_em = getelementptr [18 x i8]* @.strCmpLeDblU, i32 0, i32 0
+  call void @failCheck( i1 %cmp_le_ok, i8* %cmp_le_em )
+
+  ; test fcmp::ult -- should return true if either operand is a NaN and the first is less
+  %cmp_lt    = fcmp ult double %d1, %d2
+  %cmp_lt_ok = icmp eq i1 %cmp_lt, %lt
+  %cmp_lt_em = getelementptr [18 x i8]* @.strCmpLtDblU, i32 0, i32 0
+  call void @failCheck( i1 %cmp_lt_ok, i8* %cmp_lt_em )
+
+  ; test fcmp::une -- should return true if either operand is a NaN and they are not equal
+  %cmp_ne    = fcmp une double %d1, %d2
+  %cmp_ne_ok = icmp eq i1 %cmp_ne, %ne
+  %cmp_ne_em = getelementptr [18 x i8]* @.strCmpNeDblU, i32 0, i32 0
+  call void @failCheck( i1 %cmp_ne_ok, i8* %cmp_ne_em )
+
+  ret void
+}
+
+; test floating point comparisons (unordered)
+define void @testFCmpBothUnordered(double %d1, double %d2, i1 %eq, i1 %ge, i1 %gt, i1 %le, i1 %lt, i1 %ne, i1 %uno) {
+entry:
+  call void @testFCmpDUnordered( double %d1, double %d2, i1 %eq, i1 %ge, i1 %gt, i1 %le, i1 %lt, i1 %ne, i1 %uno )
+
+  %f1 = fptrunc double %d1 to float
+  %f2 = fptrunc double %d2 to float
+  call void @testFCmpFUnordered( float %f1, float %f2, i1 %eq, i1 %ge, i1 %gt, i1 %le, i1 %lt, i1 %ne, i1 %uno )
+
+  ret void
+}
+
+; test floating point comparisons (ordered and unordered)
+define void @testFCmpBoth(double %d1, double %d2, i1 %eq, i1 %ge, i1 %gt, i1 %le, i1 %lt, i1 %ne, i1 %ord, i1 %uno) {
+entry:
+  call void @testFCmpBothOrdered( double %d1, double %d2, i1 %eq, i1 %ge, i1 %gt, i1 %le, i1 %lt, i1 %ne, i1 %ord )
+  call void @testFCmpBothUnordered( double %d1, double %d2, i1 %eq, i1 %ge, i1 %gt, i1 %le, i1 %lt, i1 %ne, i1 %uno )
+
+  ret void
+}
+
+; test floating point comparisons (ordered and unordered) with a variety of real numbers and NaNs as operands
+define void @testFCmp() {
+entry:
+  %x = alloca i64, align 8
+  %nan = alloca double, align 8
+
+  ; test FCmp on some real number inputs
+  call void @testFCmpBoth( double 0.000000e+00, double 0.000000e+00, i1 1, i1 1, i1 0, i1 1, i1 0, i1 0, i1 1, i1 0 )
+  call void @testFCmpBoth( double 0.000000e+00, double 1.000000e+00, i1 0, i1 0, i1 0, i1 1, i1 1, i1 1, i1 1, i1 0 )
+  call void @testFCmpBoth( double 1.000000e+00, double 0.000000e+00, i1 0, i1 1, i1 1, i1 0, i1 0, i1 1, i1 1, i1 0 )
+
+  ; build NaN
+  store i64 -1, i64* %x
+  %nan_as_i8 = bitcast double* %nan to i8*
+  %x_as_i8 = bitcast i64* %x to i8*
+  call void @llvm.memcpy.i32( i8* %nan_as_i8, i8* %x_as_i8, i32 8, i32 8 )
+
+  ; load two copies of our NaN
+  %nan1 = load double* %nan
+  %nan2 = load double* %nan
+
+  ; Warning: NaN comparisons with normal operators is BROKEN in LLVM JIT v2.0.  Fixed in v2.1.
+  ; NaNs do different things depending on ordered vs unordered
+;  call void @testFCmpBothOrdered( double %nan1, double 0.000000e+00, i1 0, i1 0, i1 0, i1 0, i1 0, i1 0, i1 0 )
+;  call void @testFCmpBothOrdered( double %nan1, double %nan2, i1 0, i1 0, i1 0, i1 0, i1 0, i1 0, i1 0 )
+;  call void @testFCmpBothUnordered( double %nan1, double 0.000000e+00, i1 1, i1 1, i1 1, i1 1, i1 1, i1 1, i1 1 )
+;  call void @testFCmpBothUnordered( double %nan1, double %nan2, i1 1, i1 1, i1 1, i1 1, i1 1, i1 1, i1 1 )
+
+  ret void
+}
+
+; tes all floating point instructions
+define i32 @main() {
+entry:
+  call void @testFPTrunc( )
+  call void @testFPExt( )
+  call void @testFPToUI( )
+  call void @testFPToSI( )
+  call void @testUIToFP( )
+  call void @testSIToFP( )
+
+  call void @testFDiv( )
+  call void @testFRem( )
+  call void @testAdd( )
+  call void @testSub( )
+  call void @testMul( )
+
+  call void @testFCmp( )
+
+  ; everything worked -- print a message saying so
+  %works_msg = getelementptr [20 x i8]* @.strWorks, i32 0, i32 0
+  %err_stream = load %struct.stdout** @stdout
+  %ret = call i32 (%struct.stdout*, i8*, ...)* @fprintf( %struct.stdout* %err_stream, i8* %works_msg )
+
+  ret i32 0
+}
diff --git a/test/Concrete/GlobalInitializers.ll b/test/Concrete/GlobalInitializers.ll
new file mode 100755
index 00000000..b4d95de6
--- /dev/null
+++ b/test/Concrete/GlobalInitializers.ll
@@ -0,0 +1,47 @@
+; (cd .. && make) && ../llvm/Release/bin/llvm-as test.ll -o=- | ../Debug/bin/klee 
+
+declare void @print_i32(i32)
+
+%simple = type { i8, i16, i32, i64 }
+@gInt = global i32 2
+@gInts = global [2 x i32] [ i32 3, i32 5 ]
+@gStruct = global %simple { i8 7, i16 11, i32 13, i64 17 }
+@gZero = global %simple zeroinitializer
+
+define i32 @main() {
+entry:
+	%addr0 = getelementptr i32* @gInt, i32 0
+	%addr1 = getelementptr [2 x i32]* @gInts, i32 0, i32 0
+	%addr2 = getelementptr [2 x i32]* @gInts, i32 0, i32 1
+	%addr3 = getelementptr %simple* @gStruct, i32 0, i32 0
+	%addr4 = getelementptr %simple* @gStruct, i32 0, i32 1
+	%addr5 = getelementptr %simple* @gStruct, i32 0, i32 2
+	%addr6 = getelementptr %simple* @gStruct, i32 0, i32 3
+	%addr7 = getelementptr %simple* @gZero, i32 0, i32 2
+	%contents0 = load i32* %addr0
+	%contents1 = load i32* %addr1
+	%contents2 = load i32* %addr2
+	%contents3tmp = load i8* %addr3
+	%contents3 = zext i8 %contents3tmp to i32
+	%contents4tmp = load i16* %addr4
+	%contents4 = zext i16 %contents4tmp to i32
+	%contents5 = load i32* %addr5
+	%contents6tmp = load i64* %addr6
+	%contents6 = trunc i64 %contents6tmp to i32
+	%contents7 = load i32* %addr7
+	%tmp0 = mul i32 %contents0, %contents1
+	%tmp1 = mul i32 %tmp0, %contents2
+	%tmp2 = mul i32 %tmp1, %contents3
+	%tmp3 = mul i32 %tmp2, %contents4
+	%tmp4 = mul i32 %tmp3, %contents5
+	%tmp5 = mul i32 %tmp4, %contents6
+	%tmp6 = add i32 %tmp5, %contents7
+	%p = icmp eq i32 %tmp5, 510510
+	br i1 %p, label %exitTrue, label %exitFalse
+exitTrue:
+	call void @print_i32(i32 1)
+	ret i32 0
+exitFalse:
+	call void @print_i32(i32 0)
+	ret i32 0
+}
diff --git a/test/Concrete/GlobalVariable.ll b/test/Concrete/GlobalVariable.ll
new file mode 100644
index 00000000..d15df064
--- /dev/null
+++ b/test/Concrete/GlobalVariable.ll
@@ -0,0 +1,9 @@
+declare void @print_i32(i32)
+
+@anInt = global i32 1
+@aRef = global i32* @anInt
+
+define i32 @main() {
+        call void @print_i32(i32 0)
+	ret i32 0
+}
diff --git a/test/Concrete/ICmp.ll b/test/Concrete/ICmp.ll
new file mode 100644
index 00000000..e2a1ef24
--- /dev/null
+++ b/test/Concrete/ICmp.ll
@@ -0,0 +1,245 @@
+declare void @print_i32(i32)
+
+define i1 @checkSlt() {
+	%c0 = icmp slt i8 -1, 1		; 1
+	%c1 = icmp slt i8 0, 1		; 1
+	%c2 = icmp slt i8 1, 1		; 0
+	%c3 = icmp slt i8 1, -1		; 0
+	%c4 = icmp slt i8 1, 0		; 0
+	%c5 = icmp slt i8 1, 1		; 0
+	%a0 = select i1 %c0, i8 1, i8 0
+	%a1 = select i1 %c1, i8 2, i8 0
+	%a2 = select i1 %c2, i8 4, i8 0
+	%a3 = select i1 %c3, i8 8, i8 0
+	%a4 = select i1 %c4, i8 16, i8 0
+	%a5 = select i1 %c5, i8 32, i8 0
+	%sum0 = add i8 %a0, %a1
+	%sum1 = add i8 %sum0, %a2
+	%sum2 = add i8 %sum1, %a3
+	%sum3 = add i8 %sum2, %a4
+	%sum = add i8 %sum3, %a5
+	%test = icmp eq i8 %sum, 3	; 0bin000011
+	ret i1 %test
+}
+
+define i1 @checkSle() {
+	%c0 = icmp sle i8 -1, 1		; 1
+	%c1 = icmp sle i8 0, 1		; 1
+	%c2 = icmp sle i8 1, 1		; 1
+	%c3 = icmp sle i8 1, -1		; 0
+	%c4 = icmp sle i8 1, 0		; 0
+	%c5 = icmp sle i8 1, 1		; 1
+	%a0 = select i1 %c0, i8 1, i8 0
+	%a1 = select i1 %c1, i8 2, i8 0
+	%a2 = select i1 %c2, i8 4, i8 0
+	%a3 = select i1 %c3, i8 8, i8 0
+	%a4 = select i1 %c4, i8 16, i8 0
+	%a5 = select i1 %c5, i8 32, i8 0
+	%sum0 = add i8 %a0, %a1
+	%sum1 = add i8 %sum0, %a2
+	%sum2 = add i8 %sum1, %a3
+	%sum3 = add i8 %sum2, %a4
+	%sum = add i8 %sum3, %a5
+	%test = icmp eq i8 %sum, 39	; 0bin100111
+	ret i1 %test
+}
+
+define i1 @checkSgt() {
+	%c0 = icmp sgt i8 -1, 1		; 0
+	%c1 = icmp sgt i8 0, 1		; 0
+	%c2 = icmp sgt i8 1, 1		; 0
+	%c3 = icmp sgt i8 1, -1		; 1
+	%c4 = icmp sgt i8 1, 0		; 1
+	%c5 = icmp sgt i8 1, 1		; 0
+	%a0 = select i1 %c0, i8 1, i8 0
+	%a1 = select i1 %c1, i8 2, i8 0
+	%a2 = select i1 %c2, i8 4, i8 0
+	%a3 = select i1 %c3, i8 8, i8 0
+	%a4 = select i1 %c4, i8 16, i8 0
+	%a5 = select i1 %c5, i8 32, i8 0
+	%sum0 = add i8 %a0, %a1
+	%sum1 = add i8 %sum0, %a2
+	%sum2 = add i8 %sum1, %a3
+	%sum3 = add i8 %sum2, %a4
+	%sum = add i8 %sum3, %a5
+	%test = icmp eq i8 %sum, 24	; 0bin011000
+	ret i1 %test
+}
+
+define i1 @checkSge() {
+	%c0 = icmp sge i8 -1, 1		; 0
+	%c1 = icmp sge i8 0, 1		; 0
+	%c2 = icmp sge i8 1, 1		; 1
+	%c3 = icmp sge i8 1, -1		; 1
+	%c4 = icmp sge i8 1, 0		; 1
+	%c5 = icmp sge i8 1, 1		; 1
+	%a0 = select i1 %c0, i8 1, i8 0
+	%a1 = select i1 %c1, i8 2, i8 0
+	%a2 = select i1 %c2, i8 4, i8 0
+	%a3 = select i1 %c3, i8 8, i8 0
+	%a4 = select i1 %c4, i8 16, i8 0
+	%a5 = select i1 %c5, i8 32, i8 0
+	%sum0 = add i8 %a0, %a1
+	%sum1 = add i8 %sum0, %a2
+	%sum2 = add i8 %sum1, %a3
+	%sum3 = add i8 %sum2, %a4
+	%sum = add i8 %sum3, %a5
+	%test = icmp eq i8 %sum, 60	; 0bin111100
+	ret i1 %test
+}
+
+define i1 @checkUlt() {
+	%c0 = icmp ult i8 -1, 1		; 0
+	%c1 = icmp ult i8 0, 1		; 1
+	%c2 = icmp ult i8 1, 1		; 0
+	%c3 = icmp ult i8 1, -1		; 1
+	%c4 = icmp ult i8 1, 0		; 0
+	%c5 = icmp ult i8 1, 1		; 0
+	%a0 = select i1 %c0, i8 1, i8 0
+	%a1 = select i1 %c1, i8 2, i8 0
+	%a2 = select i1 %c2, i8 4, i8 0
+	%a3 = select i1 %c3, i8 8, i8 0
+	%a4 = select i1 %c4, i8 16, i8 0
+	%a5 = select i1 %c5, i8 32, i8 0
+	%sum0 = add i8 %a0, %a1
+	%sum1 = add i8 %sum0, %a2
+	%sum2 = add i8 %sum1, %a3
+	%sum3 = add i8 %sum2, %a4
+	%sum = add i8 %sum3, %a5
+	%test = icmp eq i8 %sum, 10	; 0bin001010
+	ret i1 %test
+}
+
+define i1 @checkUle() {
+	%c0 = icmp ule i8 -1, 1		; 0
+	%c1 = icmp ule i8 0, 1		; 1
+	%c2 = icmp ule i8 1, 1		; 1
+	%c3 = icmp ule i8 1, -1		; 1
+	%c4 = icmp ule i8 1, 0		; 0
+	%c5 = icmp ule i8 1, 1		; 1
+	%a0 = select i1 %c0, i8 1, i8 0
+	%a1 = select i1 %c1, i8 2, i8 0
+	%a2 = select i1 %c2, i8 4, i8 0
+	%a3 = select i1 %c3, i8 8, i8 0
+	%a4 = select i1 %c4, i8 16, i8 0
+	%a5 = select i1 %c5, i8 32, i8 0
+	%sum0 = add i8 %a0, %a1
+	%sum1 = add i8 %sum0, %a2
+	%sum2 = add i8 %sum1, %a3
+	%sum3 = add i8 %sum2, %a4
+	%sum = add i8 %sum3, %a5
+	%test = icmp eq i8 %sum, 46	; 0bin101110
+	ret i1 %test
+}
+
+define i1 @checkUgt() {
+	%c0 = icmp ugt i8 -1, 1		; 1
+	%c1 = icmp ugt i8 0, 1		; 0
+	%c2 = icmp ugt i8 1, 1		; 0
+	%c3 = icmp ugt i8 1, -1		; 0
+	%c4 = icmp ugt i8 1, 0		; 1
+	%c5 = icmp ugt i8 1, 1		; 0
+	%a0 = select i1 %c0, i8 1, i8 0
+	%a1 = select i1 %c1, i8 2, i8 0
+	%a2 = select i1 %c2, i8 4, i8 0
+	%a3 = select i1 %c3, i8 8, i8 0
+	%a4 = select i1 %c4, i8 16, i8 0
+	%a5 = select i1 %c5, i8 32, i8 0
+	%sum0 = add i8 %a0, %a1
+	%sum1 = add i8 %sum0, %a2
+	%sum2 = add i8 %sum1, %a3
+	%sum3 = add i8 %sum2, %a4
+	%sum = add i8 %sum3, %a5
+	%test = icmp eq i8 %sum, 17	; 0bin010001
+	ret i1 %test
+}
+
+define i1 @checkUge() {
+	%c0 = icmp uge i8 -1, 1		; 1
+	%c1 = icmp uge i8 0, 1		; 0
+	%c2 = icmp uge i8 1, 1		; 1
+	%c3 = icmp uge i8 1, -1		; 0
+	%c4 = icmp uge i8 1, 0		; 1
+	%c5 = icmp uge i8 1, 1		; 1
+	%a0 = select i1 %c0, i8 1, i8 0
+	%a1 = select i1 %c1, i8 2, i8 0
+	%a2 = select i1 %c2, i8 4, i8 0
+	%a3 = select i1 %c3, i8 8, i8 0
+	%a4 = select i1 %c4, i8 16, i8 0
+	%a5 = select i1 %c5, i8 32, i8 0
+	%sum0 = add i8 %a0, %a1
+	%sum1 = add i8 %sum0, %a2
+	%sum2 = add i8 %sum1, %a3
+	%sum3 = add i8 %sum2, %a4
+	%sum = add i8 %sum3, %a5
+	%test = icmp eq i8 %sum, 53	; 0bin110101
+	ret i1 %test
+}
+
+define i1 @checkEq() {
+	%c0 = icmp eq i8 -1, 1		; 0
+	%c1 = icmp eq i8 1, 1		; 1
+	%c2 = icmp eq i8 1, -1		; 0
+	%a0 = select i1 %c0, i8 1, i8 0
+	%a1 = select i1 %c1, i8 2, i8 0
+	%a2 = select i1 %c2, i8 4, i8 0
+	%sum0 = add i8 %a0, %a1
+	%sum = add i8 %sum0, %a2
+	%test = icmp eq i8 %sum, 2
+	ret i1 %test
+}
+
+define i1 @checkNe() {
+	%c0 = icmp ne i8 -1, 1		; 1
+	%c1 = icmp ne i8 1, 1		; 0
+	%c2 = icmp ne i8 1, -1		; 1
+	%a0 = select i1 %c0, i8 1, i8 0
+	%a1 = select i1 %c1, i8 2, i8 0
+	%a2 = select i1 %c2, i8 4, i8 0
+	%sum0 = add i8 %a0, %a1
+	%sum = add i8 %sum0, %a2
+	%test = icmp eq i8 %sum, 5
+	ret i1 %test
+}
+
+define i32 @main() {
+	%c0 = call i1 @checkSlt ()
+	%c1 = call i1 @checkSle ()
+	%c2 = call i1 @checkSgt ()
+	%c3 = call i1 @checkSge ()
+	%c4 = call i1 @checkUlt ()
+	%c5 = call i1 @checkUle ()
+	%c6 = call i1 @checkUgt ()
+	%c7 = call i1 @checkUge ()
+	%c8 = call i1 @checkEq ()
+	%c9 = call i1 @checkNe ()
+	%a0 = select i1 %c0, i16 1, i16 0
+	%a1 = select i1 %c1, i16 2, i16 0
+	%a2 = select i1 %c2, i16 4, i16 0
+	%a3 = select i1 %c3, i16 8, i16 0
+	%a4 = select i1 %c4, i16 16, i16 0
+	%a5 = select i1 %c5, i16 32, i16 0
+	%a6 = select i1 %c6, i16 64, i16 0
+	%a7 = select i1 %c7, i16 128, i16 0
+	%a8 = select i1 %c8, i16 256, i16 0
+	%a9 = select i1 %c9, i16 512, i16 0
+	%sum0 = add i16 %a0, %a1
+	%sum1 = add i16 %sum0, %a2
+	%sum2 = add i16 %sum1, %a3
+	%sum3 = add i16 %sum2, %a4
+	%sum4 = add i16 %sum3, %a5
+	%sum5 = add i16 %sum4, %a6
+	%sum6 = add i16 %sum5, %a7
+	%sum7 = add i16 %sum6, %a8
+	%sum8 = add i16 %sum7, %a9
+	%t = shl i16 63, 10
+	%sum = add i16 %sum8, %t
+	%test = icmp eq i16 %sum, -1
+	br i1 %test, label %exitTrue, label %exitFalse
+exitTrue:
+	call void @print_i32(i32 1)
+	ret i32 0
+exitFalse:
+	call void @print_i32(i32 0)
+	ret i32 0
+}
diff --git a/test/Concrete/InvokeAndReturn.ll b/test/Concrete/InvokeAndReturn.ll
new file mode 100644
index 00000000..f73c242a
--- /dev/null
+++ b/test/Concrete/InvokeAndReturn.ll
@@ -0,0 +1,18 @@
+declare void @print_i32(i32)
+
+define i8 @sum(i8 %a, i8 %b) {
+	%c = add i8 %a, %b
+	ret i8 %c
+}
+
+define i32 @main() {
+	invoke i8 @sum(i8 1, i8 2) 
+		to label %continue
+		unwind label %error
+continue:
+	call void @print_i32(i32 1)
+	ret i32 0
+error:
+	call void @print_i32(i32 0)
+	ret i32 0
+}
diff --git a/test/Concrete/InvokeAndUnwindOnce.ll b/test/Concrete/InvokeAndUnwindOnce.ll
new file mode 100644
index 00000000..2834ec82
--- /dev/null
+++ b/test/Concrete/InvokeAndUnwindOnce.ll
@@ -0,0 +1,18 @@
+declare void @print_i32(i32)
+
+define i8 @sum(i8 %a, i8 %b) {
+	%c = add i8 %a, %b
+	unwind
+}
+
+define i32 @main() {
+	invoke i8 @sum(i8 1, i8 2) 
+		to label %continue
+		unwind label %error
+continue:
+	call void @print_i32(i32 1)
+	ret i32 0
+error:
+	call void @print_i32(i32 0)
+	ret i32 0
+}
diff --git a/test/Concrete/InvokeAndUnwindTwice.ll b/test/Concrete/InvokeAndUnwindTwice.ll
new file mode 100644
index 00000000..81760b86
--- /dev/null
+++ b/test/Concrete/InvokeAndUnwindTwice.ll
@@ -0,0 +1,22 @@
+declare void @print_i32(i32)
+
+define i8 @myadd(i8 %a, i8 %b) {
+	unwind
+}
+
+define i8 @sum(i8 %a, i8 %b) {
+	%c = call i8 @myadd(i8 %a, i8 %b)
+	ret i8 %c
+}
+
+define i32 @main() {
+	invoke i8 @sum(i8 1, i8 2) 
+		to label %continue
+		unwind label %error
+continue:
+	call void @print_i32(i32 1)
+	ret i32 0
+error:
+	call void @print_i32(i32 0)
+	ret i32 0
+}
diff --git a/test/Concrete/Makefile b/test/Concrete/Makefile
new file mode 100644
index 00000000..4acfadad
--- /dev/null
+++ b/test/Concrete/Makefile
@@ -0,0 +1,55 @@
+LEVEL = ../..
+
+# hard-coding bad. will get fixed.
+LCCFLAGS  += -O0 -Wall
+LCXXFLAGS += -O0 -Wall
+LLCFLAGS =
+
+test:
+	./ConcreteTest.py
+
+clean::
+	-rm -rf Output klee-last klee-out* test.log
+	-rm -rf *.bc
+
+# We do not want to make .d files for tests! 
+DISABLE_AUTO_DEPENDENCIES=1
+
+include ${LEVEL}/Makefile.common
+
+# Compile from X.c to Output/X.ll
+Output/%.ll: %.c $(LCC1) Output/.dir $(INCLUDES)
+	$(LLVMGCCWITHPATH) --emit-llvm $(CPPFLAGS) $(LCCFLAGS) -S $< -o $@
+
+# Compile from X.cpp to Output/X.ll
+Output/%.ll: %.cpp $(LCC1XX) Output/.dir $(INCLUDES)
+	$(LLVMGXXWITHPATH) --emit-llvm $(CPPFLAGS) $(LCXXFLAGS) -S $< -o $@
+
+# Compile from X.cc to Output/X.ll
+Output/%.ll: %.cc $(LCC1XX) Output/.dir $(INCLUDES)
+	$(LLVMGXXWITHPATH) --emit-llvm $(CPPFLAGS) $(LCXXFLAGS) -S $< -o $@
+
+# LLVM Assemble from Output/X.ll to Output/X.bc.  Output/X.ll must have come
+# from GCC output, so use GCCAS.
+#
+Output/%.bc: Output/%.ll $(LLVMAS)
+	$(LLVMAS) -f $< -o $@
+
+# LLVM Assemble from X.ll to Output/X.bc.  Because we are coming directly from
+# LLVM source, use the non-transforming assembler.
+#
+Output/%.bc: %.ll $(LLVMAS) Output/.dir
+	$(LLVMAS) -f $< -o $@
+
+Output/linked_%.bc: Output/%.bc Output/_testingUtils.bc
+	$(LLVMLD) -disable-opt -link-as-library Output/_testingUtils.bc $< -o $@
+
+.PRECIOUS: Output/.dir
+
+## Cancel built-in implicit rules that override above rules
+%: %.s
+
+%: %.c
+
+%.o: %.c
+
diff --git a/test/Concrete/OneCall.ll b/test/Concrete/OneCall.ll
new file mode 100644
index 00000000..d8b94b37
--- /dev/null
+++ b/test/Concrete/OneCall.ll
@@ -0,0 +1,12 @@
+declare void @print_i32(i32)
+
+define i32 @sum(i32 %a, i32 %b) {
+	%c = sub i32 %a, %b
+	ret i32 %c
+}
+
+define i32 @main() {
+	%a = call i32 @sum(i32 54, i32 2)
+	call void @print_i32(i32 %a)
+	ret i32 0
+}
diff --git a/test/Concrete/OverlappingPhiNodes.ll b/test/Concrete/OverlappingPhiNodes.ll
new file mode 100644
index 00000000..d3dc76ab
--- /dev/null
+++ b/test/Concrete/OverlappingPhiNodes.ll
@@ -0,0 +1,15 @@
+declare void @print_i32(i32)
+
+define i32 @main() {
+entry:
+	br label %test
+test:
+	%a = phi i32 [10, %entry], [%b, %test]
+	%b = phi i32 [20, %entry], [%a, %test]
+	%c = phi i32 [0, %entry], [1, %test]
+	%d = icmp eq i32 %c, 1
+	br i1 %d, label %exit, label %test
+exit:
+	call void @print_i32(i32 %b)
+	ret i32 0
+}
diff --git a/test/Concrete/Select.ll b/test/Concrete/Select.ll
new file mode 100644
index 00000000..29b81e3e
--- /dev/null
+++ b/test/Concrete/Select.ll
@@ -0,0 +1,15 @@
+declare void @print_i32(i32)
+
+define i32 @main() {
+	%ten = select i1 true, i32 10, i32 0
+	%five = select i1 false, i32 0, i32 5
+	%check = add i32 %ten, %five
+	%test = icmp eq i32 %check, 15
+	br i1 %test, label %exitTrue, label %exitFalse
+exitTrue:
+	call void @print_i32(i32 1)
+	ret i32 0
+exitFalse:
+	call void @print_i32(i32 0)
+	ret i32 0
+}
diff --git a/test/Concrete/Shifts.ll b/test/Concrete/Shifts.ll
new file mode 100644
index 00000000..2430f879
--- /dev/null
+++ b/test/Concrete/Shifts.ll
@@ -0,0 +1,21 @@
+declare void @print_i32(i32)
+
+define i32 @main() {
+	%amt = add i8 2, 5
+	%a = shl i8 1, 5
+	%b = lshr i8 %a, 5
+	%c = shl i8 %b, %amt
+	%d = lshr i8 %c, %amt
+	%e = shl i8 %d, 7
+	%f = ashr i8 %e, 7
+	%g = shl i8 %f, %amt
+	%h = ashr i8 %g, %amt
+	%test = icmp eq i8 %h, -1
+	br i1 %test, label %exitTrue, label %exitFalse
+exitTrue:
+	call void @print_i32(i32 1)
+	ret i32 0
+exitFalse:
+	call void @print_i32(i32 0)
+	ret i32 0
+}
diff --git a/test/Concrete/SimpleStoreAndLoad.ll b/test/Concrete/SimpleStoreAndLoad.ll
new file mode 100644
index 00000000..0201ba15
--- /dev/null
+++ b/test/Concrete/SimpleStoreAndLoad.ll
@@ -0,0 +1,17 @@
+declare void @print_i32(i32)
+
+define i32 @main() {
+entry:
+	%a = alloca i32, i32 4
+	%tmp1 = getelementptr i32* %a, i32 0
+	store i32 0, i32* %tmp1
+	%tmp2 = load i32* %tmp1
+	%tmp3 = icmp eq i32 %tmp2, 0
+	br i1 %tmp3, label %exitTrue, label %exitFalse
+exitTrue:
+	call void @print_i32(i32 1)
+	ret i32 0
+exitFalse:
+	call void @print_i32(i32 0)
+	ret i32 0
+}
diff --git a/test/Concrete/UnconditionalBranch.ll b/test/Concrete/UnconditionalBranch.ll
new file mode 100644
index 00000000..81e2f931
--- /dev/null
+++ b/test/Concrete/UnconditionalBranch.ll
@@ -0,0 +1,10 @@
+declare void @print_i32(i32)
+
+define i32 @main() {
+entry:
+	%a = add i32 0, 1
+	br label %exit
+exit:
+	call void @print_i32(i32 %a)
+	ret i32 0
+}
diff --git a/test/Concrete/UnconditionalBranchWithSimplePhi.ll b/test/Concrete/UnconditionalBranchWithSimplePhi.ll
new file mode 100644
index 00000000..551ddf5d
--- /dev/null
+++ b/test/Concrete/UnconditionalBranchWithSimplePhi.ll
@@ -0,0 +1,14 @@
+declare void @print_i32(i32)
+
+define i32 @main() {
+entry:
+	%a = add i32 0, 1
+	br label %exit
+unused:
+	%b = add i32 1, 2
+	br label %exit
+exit:
+	%c = phi i32 [%a, %entry], [%b, %unused]
+	call void @print_i32(i32 %c)
+	ret i32 0
+}
diff --git a/test/Concrete/UnorderedPhiNodes.ll b/test/Concrete/UnorderedPhiNodes.ll
new file mode 100644
index 00000000..3ecd5083
--- /dev/null
+++ b/test/Concrete/UnorderedPhiNodes.ll
@@ -0,0 +1,15 @@
+declare void @print_i32(i32)
+
+define i32 @main() {
+entry:
+	br label %test
+test:
+	%a = phi i32 [10, %entry], [%b, %test]
+	%b = phi i32 [%a, %test], [20, %entry]
+	%c = phi i32 [0, %entry], [1, %test]
+	%d = icmp eq i32 %c, 1
+	br i1 %d, label %exit, label %test
+exit:
+	call void @print_i32(i32 %b)
+	ret i32 0
+}
diff --git a/test/Concrete/_testingUtils.c b/test/Concrete/_testingUtils.c
new file mode 100644
index 00000000..02d0529e
--- /dev/null
+++ b/test/Concrete/_testingUtils.c
@@ -0,0 +1,32 @@
+int putchar(int x);
+
+void print_int(unsigned long long val);
+
+#define TYPED_PRINT(_name_type, _arg_type)  \
+    void print_ ## _name_type(_arg_type val) { print_int(val); }
+ 
+TYPED_PRINT(i1, unsigned char)
+TYPED_PRINT(i8, unsigned char)
+TYPED_PRINT(i16, unsigned short)
+TYPED_PRINT(i32, unsigned int)
+TYPED_PRINT(i64, unsigned long long)
+
+void print_int(unsigned long long val) {
+    int cur = 1;
+
+    // effectively do a log (can't call log because it returns floats)
+    // do the nasty divide to prevent overflow
+    while (cur <= val / 10)
+        cur *= 10;
+
+    while (cur) {
+        int digit = val / cur;
+
+        putchar(digit + '0');
+        
+        val = val % cur;
+        cur /= 10;
+    }
+    
+    putchar('\n');
+}
diff --git a/test/Concrete/ackermann.c b/test/Concrete/ackermann.c
new file mode 100644
index 00000000..0f21a3ab
--- /dev/null
+++ b/test/Concrete/ackermann.c
@@ -0,0 +1,16 @@
+// llvm-gcc -O2 --emit-llvm -c ackermann.c && ../../Debug/bin/klee ackermann.o 2 2
+
+#include <stdio.h>
+
+int ackermann(int m, int n) {
+   if (m == 0)
+     return n+1;
+   else
+     return ackermann(m-1, (n==0) ? 1 : ackermann(m, n-1));
+ }
+
+int main() {
+  printf("ackerman(%d, %d) = %d\n", 2, 2, ackermann(2, 2));
+
+  return 0;
+}
diff --git a/test/Concrete/arith_test.ll b/test/Concrete/arith_test.ll
new file mode 100644
index 00000000..5624462b
--- /dev/null
+++ b/test/Concrete/arith_test.ll
@@ -0,0 +1,76 @@
+define void @"test_simple_arith"(i16 %i0, i16 %j0)
+begin
+  %t1 = add i16 %i0, %j0
+  %t2 = sub i16 %i0, %j0
+  %t3 = mul i16 %t1, %t2
+
+  call void @print_i16(i16 %t3)
+
+  ret void     
+end
+
+define void @"test_div_and_mod"(i16 %op1, i16 %op2)
+begin
+  %t1 = udiv i16 %op1, %op2
+  %t2 = urem i16 %op1, %op2  
+  %t3 = sdiv i16 %op1, %op2  
+  %t4 = srem i16 %op1, %op2  
+
+  call void @print_i16(i16 %t1)
+  call void @print_i16(i16 %t2)
+  call void @print_i16(i16 %t3)
+  call void @print_i16(i16 %t4)
+
+  ret void     
+end
+        
+define void @test_cmp(i16 %op1, i16 %op2)
+begin
+  %t1 = icmp ule i16 %op1, %op2
+  %t2 = icmp ult i16 %op1, %op2  
+  %t3 = icmp uge i16 %op1, %op2  
+  %t4 = icmp ugt i16 %op1, %op2  
+  %t6 = icmp slt i16 %op1, %op2  
+  %t5 = icmp sle i16 %op1, %op2
+  %t7 = icmp sge i16 %op1, %op2  
+  %t8 = icmp sgt i16 %op1, %op2  
+  %t9 = icmp eq i16 %op1, %op2  
+  %t10 = icmp ne i16 %op1, %op2  
+
+  call void @print_i1(i1 %t1)
+  call void @print_i1(i1 %t2)
+  call void @print_i1(i1 %t3)
+  call void @print_i1(i1 %t4)
+  call void @print_i1(i1 %t5)
+  call void @print_i1(i1 %t6)
+  call void @print_i1(i1 %t7)
+  call void @print_i1(i1 %t8)
+  call void @print_i1(i1 %t9)
+  call void @print_i1(i1 %t10)
+
+  ret void
+end
+
+define i32 @main()
+begin
+    call void @test_simple_arith(i16 111, i16 100)
+
+    call void @test_div_and_mod(i16 63331, i16 3123)
+    call void @test_div_and_mod(i16 1000, i16 55444)
+    call void @test_div_and_mod(i16 49012, i16 55444)
+    call void @test_div_and_mod(i16 1000, i16 25)
+
+    call void @test_cmp(i16 63331, i16 3123)
+    call void @test_cmp(i16 1000, i16 55444)
+    call void @test_cmp(i16 49012, i16 55444)
+    call void @test_cmp(i16 1000, i16 25)
+        
+    ret i32 0
+end
+
+; defined in print_int.c
+declare void @print_i1(i1)
+declare void @print_i8(i8)
+declare void @print_i16(i16)
+declare void @print_i32(i32)
+declare void @print_i64(i64)