diff options
35 files changed, 1657 insertions, 176 deletions
diff --git a/test/Concrete/BoolReadWrite.leq36.ll b/test/Concrete/BoolReadWrite.leq36.ll new file mode 100644 index 00000000..34a50447 --- /dev/null +++ b/test/Concrete/BoolReadWrite.leq36.ll @@ -0,0 +1,16 @@ +; REQUIRES: lt-llvm-3.7 +; RUN: %S/ConcreteTest.py --klee='%klee' --lli=%lli %s + +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/BoolReadWrite.ll b/test/Concrete/BoolReadWrite.ll index f818ecaf..4dfb49e0 100644 --- a/test/Concrete/BoolReadWrite.ll +++ b/test/Concrete/BoolReadWrite.ll @@ -1,3 +1,5 @@ +; LLVM 3.7 requires a type as the first argument to 'load' +; REQUIRES: geq-llvm-3.7 ; RUN: %S/ConcreteTest.py --klee='%klee' --lli=%lli %s declare void @print_i1(i1) @@ -5,7 +7,7 @@ declare void @print_i1(i1) define i32 @main() { %mem = alloca i1 store i1 1, i1* %mem - %v = load i1* %mem + %v = load i1, i1* %mem br i1 %v, label %ok, label %exit ok: call void @print_i1(i1 %v) diff --git a/test/Concrete/ConstantExpr.leq36.ll b/test/Concrete/ConstantExpr.leq36.ll new file mode 100644 index 00000000..2d8e5bc6 --- /dev/null +++ b/test/Concrete/ConstantExpr.leq36.ll @@ -0,0 +1,166 @@ +; REQUIRES: lt-llvm-3.7 +; RUN: %S/ConcreteTest.py --klee='%klee' --lli=%lli %s + +; Most of the test below use the *address* of gInt as part of their computation, +; and then perform some operation (like x | ~x) which makes the result +; deterministic. They do, however, assume that the sign bit of the address as a +; 64-bit value will never be set. +@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"() { + %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 +} + +define void @"test_constant_ops"() { + %t1 = add i8 trunc(i64 add(i64 ptrtoint(i32* @gInt to i64), i64 -10) to i8), 10 + %t2 = and i64 sub(i64 sext(i32 ptrtoint(i32* @gInt to i32) to i64), i64 ptrtoint(i32* @gInt to i64)), 4294967295 + %t3 = and i64 sub(i64 zext(i32 ptrtoint(i32* @gInt to i32) to i64), i64 ptrtoint(i32* @gInt to i64)), 4294967295 + + %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 +} + +define void @"test_logical_ops"() { + %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) + + ; or the address with 1 to ensure the addresses will differ in 'ne' below + %t4 = shl i64 lshr(i64 or(i64 ptrtoint(i32* @gInt to i64), i64 1), i64 8), 8 + %t5 = shl i64 ashr(i64 or(i64 ptrtoint(i32* @gInt to i64), i64 1), i64 8), 8 + %t6 = lshr i64 shl(i64 or(i64 ptrtoint(i32* @gInt to i64), i64 1), i64 8), 8 + + %t7 = icmp eq i64 %t4, %t5 + %t8 = icmp ne i64 %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 +} + +%test.struct.type = type { i32, i32 } +@test_struct = global %test.struct.type { i32 0, i32 10 } + +define void @"test_misc"() { + ; 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 +} + +define void @"test_simple_arith"() { + %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 +} + +define void @"test_div_and_mod"() { + %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 +} + +define void @test_cmp() { + %t1 = add i8 zext(i1 icmp ult (i64 ptrtoint(i32* @gInt to i64), i64 0) to i8), 1 + %t2 = add i8 zext(i1 icmp ule (i64 ptrtoint(i32* @gInt to i64), i64 0) to i8), 1 + %t3 = add i8 zext(i1 icmp uge (i64 ptrtoint(i32* @gInt to i64), i64 0) to i8), 1 + %t4 = add i8 zext(i1 icmp ugt (i64 ptrtoint(i32* @gInt to i64), i64 0) to i8), 1 + %t5 = add i8 zext(i1 icmp slt (i64 ptrtoint(i32* @gInt to i64), i64 0) to i8), 1 + %t6 = add i8 zext(i1 icmp sle (i64 ptrtoint(i32* @gInt to i64), i64 0) to i8), 1 + %t7 = add i8 zext(i1 icmp sge (i64 ptrtoint(i32* @gInt to i64), i64 0) to i8), 1 + %t8 = add i8 zext(i1 icmp sgt (i64 ptrtoint(i32* @gInt to i64), i64 0) to i8), 1 + %t9 = add i8 zext(i1 icmp eq (i64 ptrtoint(i32* @gInt to i64), i64 10) to i8), 1 + %t10 = add i8 zext(i1 icmp ne (i64 ptrtoint(i32* @gInt to i64), i64 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 +} + +define i32 @main() { + 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 +} + +; 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/ConstantExpr.ll b/test/Concrete/ConstantExpr.ll index d00c59a6..38577f70 100644 --- a/test/Concrete/ConstantExpr.ll +++ b/test/Concrete/ConstantExpr.ll @@ -1,3 +1,5 @@ +; LLVM 3.7 requires a type as the first argument to 'getelementptr' +; REQUIRES: geq-llvm-3.7 ; RUN: %S/ConcreteTest.py --klee='%klee' --lli=%lli %s ; Most of the test below use the *address* of gInt as part of their computation, @@ -71,7 +73,7 @@ define void @"test_misc"() { %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) + %t2 = load i32, i32* getelementptr(%test.struct.type, %test.struct.type* @test_struct, i32 0, i32 1) call void @print_i32(i32 %t2) ret void diff --git a/test/Concrete/ConstantInit.leq36.ll b/test/Concrete/ConstantInit.leq36.ll new file mode 100644 index 00000000..44f85212 --- /dev/null +++ b/test/Concrete/ConstantInit.leq36.ll @@ -0,0 +1,60 @@ +; REQUIRES: lt-llvm-3.7 +; RUN: %S/ConcreteTest.py --klee='%klee' --lli=%lli %s + +%struct.dirent = type { i64, i64, i16, i8 } +declare void @print_i64(i64) + +define void @test_constant_vector_simple() { + entry: + %a = alloca %struct.dirent + %tmp1 = getelementptr %struct.dirent* %a, i32 0 + %tmp2 = bitcast %struct.dirent* %tmp1 to <2 x i64>* + ; Initialize with constant vector parsed as ConstantDataSequential + store <2 x i64> <i64 0, i64 4096>, <2 x i64>* %tmp2, align 8 + + br label %exit +exit: + ; Print first initialized element + %idx = getelementptr %struct.dirent* %a, i32 0, i32 0 + %val = load i64* %idx + call void @print_i64(i64 %val) + + ; Print second initialized element + %idx2 = getelementptr %struct.dirent* %a, i32 0, i32 1 + %val2 = load i64* %idx2 + call void @print_i64(i64 %val2) + ret void +} + +define void @test_constant_vector_complex() { +entry: + ; Create a vector using an uncommon type: i1024: Force usage of constant vector + %a = alloca <2 x i1024> + store <2 x i1024> <i1024 5, i1024 1024>, <2 x i1024>* %a, align 8 + + br label %exit +exit: + ; Print first initialized element + %idx = getelementptr <2 x i1024>* %a, i32 0, i32 0 + %narrow = bitcast i1024* %idx to i64* + %val = load i64* %narrow + call void @print_i64(i64 %val) + + ; Print second initialized element + %idx2 = getelementptr <2 x i1024>* %a, i32 0, i32 1 + %narrow2 = bitcast i1024* %idx2 to i64* + %val2 = load i64* %narrow2 + call void @print_i64(i64 %val2) + + ret void +} + +define i32 @main() { +entry: + call void @test_constant_vector_simple() + call void @test_constant_vector_complex() + + br label %exit +exit: + ret i32 0 +} diff --git a/test/Concrete/ConstantInit.ll b/test/Concrete/ConstantInit.ll index 2127d27b..c30b7f09 100644 --- a/test/Concrete/ConstantInit.ll +++ b/test/Concrete/ConstantInit.ll @@ -1,3 +1,6 @@ +; LLVM 3.7 requires a type as the first argument to 'load' +; LLVM 3.7 requires a type as the first argument to 'getelementptr' +; REQUIRES: geq-llvm-3.7 ; RUN: %S/ConcreteTest.py --klee='%klee' --lli=%lli %s %struct.dirent = type { i64, i64, i16, i8 } @@ -6,23 +9,23 @@ declare void @print_i64(i64) define void @test_constant_vector_simple() { entry: %a = alloca %struct.dirent - %tmp1 = getelementptr %struct.dirent* %a, i32 0 + %tmp1 = getelementptr %struct.dirent, %struct.dirent* %a, i32 0 %tmp2 = bitcast %struct.dirent* %tmp1 to <2 x i64>* ; Initialize with constant vector parsed as ConstantDataSequential store <2 x i64> <i64 0, i64 4096>, <2 x i64>* %tmp2, align 8 - + br label %exit exit: ; Print first initialized element - %idx = getelementptr %struct.dirent* %a, i32 0, i32 0 - %val = load i64* %idx + %idx = getelementptr %struct.dirent, %struct.dirent* %a, i32 0, i32 0 + %val = load i64, i64* %idx call void @print_i64(i64 %val) - ; Print second initialized element - %idx2 = getelementptr %struct.dirent* %a, i32 0, i32 1 - %val2 = load i64* %idx2 + ; Print second initialized element + %idx2 = getelementptr %struct.dirent, %struct.dirent* %a, i32 0, i32 1 + %val2 = load i64, i64* %idx2 call void @print_i64(i64 %val2) - ret void + ret void } define void @test_constant_vector_complex() { @@ -34,18 +37,18 @@ entry: br label %exit exit: ; Print first initialized element - %idx = getelementptr <2 x i1024>* %a, i32 0, i32 0 + %idx = getelementptr <2 x i1024>, <2 x i1024>* %a, i32 0, i32 0 %narrow = bitcast i1024* %idx to i64* - %val = load i64* %narrow + %val = load i64, i64* %narrow call void @print_i64(i64 %val) ; Print second initialized element - %idx2 = getelementptr <2 x i1024>* %a, i32 0, i32 1 + %idx2 = getelementptr <2 x i1024>, <2 x i1024>* %a, i32 0, i32 1 %narrow2 = bitcast i1024* %idx2 to i64* - %val2 = load i64* %narrow2 + %val2 = load i64, i64* %narrow2 call void @print_i64(i64 %val2) - ret void + ret void } define i32 @main() { diff --git a/test/Concrete/FloatingPointOps.leq36.ll b/test/Concrete/FloatingPointOps.leq36.ll new file mode 100644 index 00000000..b81a3b8d --- /dev/null +++ b/test/Concrete/FloatingPointOps.leq36.ll @@ -0,0 +1,678 @@ +; REQUIRES: lt-llvm-3.7 +; RUN: %S/ConcreteTest.py --klee='%klee' --lli=%lli %s + +; 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 @printf(i8*, ...) +declare void @exit(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 + %ret = call i32 (i8*, ...)* @printf( i8* %errMsg ) + + ; add a newline to the ostream + %nl = getelementptr [3 x i8]* @.strNL, i32 0, i32 0 + %ret2 = call i32 (i8*, ...)* @printf( 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 +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 = fadd 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 = fadd 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 +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 = fsub 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 = fsub 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 +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 = fmul 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 = fmul 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 + %nan_as_i64 = bitcast double* %nan to i64* + store i64 -1, i64* %nan_as_i64 + + ; load two copies of our NaN + %nan1 = load double* %nan + %nan2 = load double* %nan + + ; 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 +} + +; test 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 + %ret = call i32 (i8*, ...)* @printf( i8* %works_msg ) + + ret i32 0 +} diff --git a/test/Concrete/FloatingPointOps.ll b/test/Concrete/FloatingPointOps.ll index 00d4e877..4c96e336 100644 --- a/test/Concrete/FloatingPointOps.ll +++ b/test/Concrete/FloatingPointOps.ll @@ -1,3 +1,7 @@ +; LLVM 3.7 requires a type as the first argument to 'load' +; LLVM 3.7 requires a type as the first argument to 'getelementptr' +; LLVM 3.7 no longer accepts '*' with a 'call' +; REQUIRES: geq-llvm-3.7 ; RUN: %S/ConcreteTest.py --klee='%klee' --lli=%lli %s ; casting error messages @@ -75,11 +79,11 @@ entry: failed: ; print the error msg - %ret = call i32 (i8*, ...)* @printf( i8* %errMsg ) + %ret = call i32 (i8*, ...) @printf( i8* %errMsg ) ; add a newline to the ostream - %nl = getelementptr [3 x i8]* @.strNL, i32 0, i32 0 - %ret2 = call i32 (i8*, ...)* @printf( i8* %nl ) + %nl = getelementptr [3 x i8], [3 x i8]* @.strNL, i32 0, i32 0 + %ret2 = call i32 (i8*, ...) @printf( i8* %nl ) ; exit with return value 1 to denote that an error occurred call void @exit( i32 1 ) @@ -94,10 +98,10 @@ define void @testFPTrunc() { entry: %d_addr = alloca double, align 8 store double 8.000000e+00, double* %d_addr - %d = load double* %d_addr + %d = load double, 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 + %err_msg = getelementptr [15 x i8], [15 x i8]* @.strTrunc, i32 0, i32 0 call void @failCheck( i1 %matches, i8* %err_msg ) ret void } @@ -107,10 +111,10 @@ define void @testFPExt() { entry: %f_addr = alloca float, align 4 store float 8.000000e+00, float* %f_addr - %f = load float* %f_addr + %f = load float, 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 + %err_msg = getelementptr [13 x i8], [13 x i8]* @.strExt, i32 0, i32 0 call void @failCheck( i1 %matches, i8* %err_msg ) ret void } @@ -123,18 +127,18 @@ entry: ; test float to UI store float 0x4020333340000000, float* %f_addr; %f = 8.1 - %f = load float* %f_addr + %f = load float, 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 + %err_msgf = getelementptr [20 x i8], [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 + %d = load double, 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 + %err_msgd = getelementptr [21 x i8], [21 x i8]* @.strFPToUIDbl, i32 0, i32 0 call void @failCheck( i1 %matchesd, i8* %err_msgd ) ret void @@ -148,18 +152,18 @@ entry: ; test float 8.1 to signed int store float 0x4020333340000000, float* %f_addr - %f = load float* %f_addr + %f = load float, 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 + %err_msgf = getelementptr [20 x i8], [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 + %d = load double, 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 + %err_msgd = getelementptr [21 x i8], [21 x i8]* @.strFPToSIDbl, i32 0, i32 0 call void @failCheck( i1 %matchesd, i8* %err_msgd ) ret void @@ -171,13 +175,13 @@ 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 + %err_msgf = getelementptr [20 x i8], [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 + %err_msgd = getelementptr [21 x i8], [21 x i8]* @.strUIToFPDbl, i32 0, i32 0 call void @failCheck( i1 %matchesd, i8* %err_msgd ) ret void @@ -189,13 +193,13 @@ 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 + %err_msgf = getelementptr [20 x i8], [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 + %err_msgd = getelementptr [21 x i8], [21 x i8]* @.strSIToFPDbl, i32 0, i32 0 call void @failCheck( i1 %matchesd, i8* %err_msgd ) ret void @@ -212,21 +216,21 @@ entry: ; 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 + %fN = load float, float* %fN_addr + %fD = load float, 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 + %err_msgf = getelementptr [18 x i8], [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 + %dN = load double, double* %dN_addr + %dD = load double, 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 + %err_msgd = getelementptr [19 x i8], [19 x i8]* @.strDivDbl, i32 0, i32 0 call void @failCheck( i1 %matchesd, i8* %err_msgd ) ret void @@ -243,21 +247,21 @@ entry: ; 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 + %fN = load float, float* %fN_addr + %fD = load float, 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 + %err_msgf = getelementptr [18 x i8], [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 + %dN = load double, double* %dN_addr + %dD = load double, 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 + %err_msgd = getelementptr [19 x i8], [19 x i8]* @.strRemDbl, i32 0, i32 0 call void @failCheck( i1 %matchesd, i8* %err_msgd ) ret void @@ -274,27 +278,27 @@ entry: ; 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 + %err_msgi = getelementptr [16 x i8], [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 + %f1 = load float, float* %f1_addr + %f2 = load float, float* %f2_addr %sumf = fadd float %f1, %f2 %matchesf = fcmp oeq float %sumf, 0x401ECCCCC0000000 - %err_msgf = getelementptr [18 x i8]* @.strAddFlt, i32 0, i32 0 + %err_msgf = getelementptr [18 x i8], [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 + %d1 = load double, double* %d1_addr + %d2 = load double, double* %d2_addr %sumd = fadd double %d1, %d2 %matchesd = fcmp oeq double %sumd, 0xBFE6666666666668 - %err_msgd = getelementptr [19 x i8]* @.strAddDbl, i32 0, i32 0 + %err_msgd = getelementptr [19 x i8], [19 x i8]* @.strAddDbl, i32 0, i32 0 call void @failCheck( i1 %matchesd, i8* %err_msgd ) ret void @@ -311,27 +315,27 @@ entry: ; 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 + %err_msgi = getelementptr [16 x i8], [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 + %f1 = load float, float* %f1_addr + %f2 = load float, float* %f2_addr %subf = fsub float %f1, %f2 %matchesf = fcmp oeq float %subf, 0xBFE6666600000000 - %err_msgf = getelementptr [18 x i8]* @.strSubFlt, i32 0, i32 0 + %err_msgf = getelementptr [18 x i8], [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 + %d1 = load double, double* %d1_addr + %d2 = load double, double* %d2_addr %subd = fsub double %d1, %d2 %matchesd = fcmp oeq double %subd, 7.700000e+00 - %err_msgd = getelementptr [19 x i8]* @.strSubDbl, i32 0, i32 0 + %err_msgd = getelementptr [19 x i8], [19 x i8]* @.strSubDbl, i32 0, i32 0 call void @failCheck( i1 %matchesd, i8* %err_msgd ) ret void @@ -348,27 +352,27 @@ entry: ; 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 + %err_msgi = getelementptr [16 x i8], [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 + %f1 = load float, float* %f1_addr + %f2 = load float, float* %f2_addr %mulf = fmul float %f1, %f2 %matchesf = fcmp oeq float %mulf, 0x402D666640000000 - %err_msgf = getelementptr [18 x i8]* @.strMulFlt, i32 0, i32 0 + %err_msgf = getelementptr [18 x i8], [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 + %d1 = load double, double* %d1_addr + %d2 = load double, double* %d2_addr %muld = fmul double %d1, %d2 %matchesd = fcmp oeq double %muld, 0xC02D666666666667 - %err_msgd = getelementptr [19 x i8]* @.strMulDbl, i32 0, i32 0 + %err_msgd = getelementptr [19 x i8], [19 x i8]* @.strMulDbl, i32 0, i32 0 call void @failCheck( i1 %matchesd, i8* %err_msgd ) ret void @@ -380,55 +384,55 @@ 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 + %cmp_t_em = getelementptr [19 x i8], [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 + %cmp_f_em = getelementptr [20 x i8], [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 + %cmp_o_em = getelementptr [18 x i8], [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 + %cmp_eq_em = getelementptr [17 x i8], [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 + %cmp_ge_em = getelementptr [17 x i8], [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 + %cmp_gt_em = getelementptr [17 x i8], [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 + %cmp_le_em = getelementptr [17 x i8], [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 + %cmp_lt_em = getelementptr [17 x i8], [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 + %cmp_ne_em = getelementptr [17 x i8], [17 x i8]* @.strCmpNeFlt, i32 0, i32 0 call void @failCheck( i1 %cmp_ne_ok, i8* %cmp_ne_em ) ret void @@ -440,55 +444,55 @@ 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 + %cmp_t_em = getelementptr [19 x i8], [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 + %cmp_f_em = getelementptr [20 x i8], [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 + %cmp_o_em = getelementptr [19 x i8], [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 + %cmp_eq_em = getelementptr [18 x i8], [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 + %cmp_ge_em = getelementptr [18 x i8], [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 + %cmp_gt_em = getelementptr [18 x i8], [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 + %cmp_le_em = getelementptr [18 x i8], [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 + %cmp_lt_em = getelementptr [18 x i8], [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 + %cmp_ne_em = getelementptr [18 x i8], [18 x i8]* @.strCmpNeDbl, i32 0, i32 0 call void @failCheck( i1 %cmp_ne_ok, i8* %cmp_ne_em ) ret void @@ -512,43 +516,43 @@ 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 + %cmp_o_em = getelementptr [20 x i8], [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 + %cmp_eq_em = getelementptr [17 x i8], [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 + %cmp_ge_em = getelementptr [17 x i8], [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 + %cmp_gt_em = getelementptr [17 x i8], [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 + %cmp_le_em = getelementptr [17 x i8], [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 + %cmp_lt_em = getelementptr [17 x i8], [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 + %cmp_ne_em = getelementptr [17 x i8], [17 x i8]* @.strCmpNeFltU, i32 0, i32 0 call void @failCheck( i1 %cmp_ne_ok, i8* %cmp_ne_em ) ret void @@ -560,43 +564,43 @@ 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 + %cmp_o_em = getelementptr [21 x i8], [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 + %cmp_eq_em = getelementptr [18 x i8], [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 + %cmp_ge_em = getelementptr [18 x i8], [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 + %cmp_gt_em = getelementptr [18 x i8], [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 + %cmp_le_em = getelementptr [18 x i8], [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 + %cmp_lt_em = getelementptr [18 x i8], [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 + %cmp_ne_em = getelementptr [18 x i8], [18 x i8]* @.strCmpNeDblU, i32 0, i32 0 call void @failCheck( i1 %cmp_ne_ok, i8* %cmp_ne_em ) ret void @@ -639,8 +643,8 @@ entry: store i64 -1, i64* %nan_as_i64 ; load two copies of our NaN - %nan1 = load double* %nan - %nan2 = load double* %nan + %nan1 = load double, double* %nan + %nan2 = load double, double* %nan ; 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 ) @@ -670,8 +674,8 @@ entry: call void @testFCmp( ) ; everything worked -- print a message saying so - %works_msg = getelementptr [20 x i8]* @.strWorks, i32 0, i32 0 - %ret = call i32 (i8*, ...)* @printf( i8* %works_msg ) + %works_msg = getelementptr [20 x i8], [20 x i8]* @.strWorks, i32 0, i32 0 + %ret = call i32 (i8*, ...) @printf( i8* %works_msg ) ret i32 0 } diff --git a/test/Concrete/GlobalInitializers.leq36.ll b/test/Concrete/GlobalInitializers.leq36.ll new file mode 100755 index 00000000..ba7e53eb --- /dev/null +++ b/test/Concrete/GlobalInitializers.leq36.ll @@ -0,0 +1,48 @@ +; REQUIRES: lt-llvm-3.7 +; RUN: %S/ConcreteTest.py --klee='%klee' --lli=%lli %s + +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/GlobalInitializers.ll b/test/Concrete/GlobalInitializers.ll index e3657dad..57e702dc 100755 --- a/test/Concrete/GlobalInitializers.ll +++ b/test/Concrete/GlobalInitializers.ll @@ -1,3 +1,6 @@ +; LLVM 3.7 requires a type as the first argument to 'getelementptr' +; LLVM 3.7 requires a type as the first argument to 'load' +; REQUIRES: geq-llvm-3.7 ; RUN: %S/ConcreteTest.py --klee='%klee' --lli=%lli %s declare void @print_i32(i32) @@ -10,25 +13,25 @@ declare void @print_i32(i32) 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 + %addr0 = getelementptr i32, i32* @gInt, i32 0 + %addr1 = getelementptr [2 x i32], [2 x i32]* @gInts, i32 0, i32 0 + %addr2 = getelementptr [2 x i32], [2 x i32]* @gInts, i32 0, i32 1 + %addr3 = getelementptr %simple, %simple* @gStruct, i32 0, i32 0 + %addr4 = getelementptr %simple, %simple* @gStruct, i32 0, i32 1 + %addr5 = getelementptr %simple, %simple* @gStruct, i32 0, i32 2 + %addr6 = getelementptr %simple, %simple* @gStruct, i32 0, i32 3 + %addr7 = getelementptr %simple, %simple* @gZero, i32 0, i32 2 + %contents0 = load i32, i32* %addr0 + %contents1 = load i32, i32* %addr1 + %contents2 = load i32, i32* %addr2 + %contents3tmp = load i8, i8* %addr3 %contents3 = zext i8 %contents3tmp to i32 - %contents4tmp = load i16* %addr4 + %contents4tmp = load i16, i16* %addr4 %contents4 = zext i16 %contents4tmp to i32 - %contents5 = load i32* %addr5 - %contents6tmp = load i64* %addr6 + %contents5 = load i32, i32* %addr5 + %contents6tmp = load i64, i64* %addr6 %contents6 = trunc i64 %contents6tmp to i32 - %contents7 = load i32* %addr7 + %contents7 = load i32, i32* %addr7 %tmp0 = mul i32 %contents0, %contents1 %tmp1 = mul i32 %tmp0, %contents2 %tmp2 = mul i32 %tmp1, %contents3 diff --git a/test/Concrete/SimpleStoreAndLoad.leq36.ll b/test/Concrete/SimpleStoreAndLoad.leq36.ll new file mode 100644 index 00000000..7bb65ea7 --- /dev/null +++ b/test/Concrete/SimpleStoreAndLoad.leq36.ll @@ -0,0 +1,20 @@ +; REQUIRES: lt-llvm-3.7 +; RUN: %S/ConcreteTest.py --klee='%klee' --lli=%lli %s + +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/SimpleStoreAndLoad.ll b/test/Concrete/SimpleStoreAndLoad.ll index 1edad038..951a474e 100644 --- a/test/Concrete/SimpleStoreAndLoad.ll +++ b/test/Concrete/SimpleStoreAndLoad.ll @@ -1,3 +1,6 @@ +; LLVM 3.7 requires a type as the first argument to 'getelementptr' +; LLVM 3.7 requires a type as the first argument to 'load' +; REQUIRES: geq-llvm-3.7 ; RUN: %S/ConcreteTest.py --klee='%klee' --lli=%lli %s declare void @print_i32(i32) @@ -5,9 +8,9 @@ declare void @print_i32(i32) define i32 @main() { entry: %a = alloca i32, i32 4 - %tmp1 = getelementptr i32* %a, i32 0 + %tmp1 = getelementptr i32, i32* %a, i32 0 store i32 0, i32* %tmp1 - %tmp2 = load i32* %tmp1 + %tmp2 = load i32, i32* %tmp1 %tmp3 = icmp eq i32 %tmp2, 0 br i1 %tmp3, label %exitTrue, label %exitFalse exitTrue: diff --git a/test/Feature/BitcastAlias.leq36.ll b/test/Feature/BitcastAlias.leq36.ll new file mode 100644 index 00000000..d203e52c --- /dev/null +++ b/test/Feature/BitcastAlias.leq36.ll @@ -0,0 +1,35 @@ +; REQUIRES: lt-llvm-3.7 +; RUN: llvm-as %s -f -o %t1.bc +; RUN: rm -rf %t.klee-out +; RUN: %klee --output-dir=%t.klee-out -disable-opt %t1.bc > %t2 +; RUN: grep PASS %t2 + +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" +target triple = "x86_64-unknown-linux-gnu" + +@foo = alias i32 (i32)* @__foo + +define i32 @__foo(i32 %i) nounwind { +entry: + ret i32 %i +} + +declare i32 @puts(i8*) + +@.passstr = private constant [5 x i8] c"PASS\00", align 1 +@.failstr = private constant [5 x i8] c"FAIL\00", align 1 + +define i32 @main(i32 %argc, i8** nocapture %argv) nounwind readnone { +entry: + %call = call i32 (i64)* bitcast (i32 (i32)* @foo to i32 (i64)*)(i64 52) + %r = icmp eq i32 %call, 52 + br i1 %r, label %bbtrue, label %bbfalse + +bbtrue: + %0 = call i32 @puts(i8* getelementptr inbounds ([5 x i8]* @.passstr, i64 0, i64 0)) nounwind + ret i32 0 + +bbfalse: + %1 = call i32 @puts(i8* getelementptr inbounds ([5 x i8]* @.failstr, i64 0, i64 0)) nounwind + ret i32 0 +} diff --git a/test/Feature/BitcastAlias.ll b/test/Feature/BitcastAlias.ll index e0e3653f..5bd30193 100644 --- a/test/Feature/BitcastAlias.ll +++ b/test/Feature/BitcastAlias.ll @@ -1,3 +1,6 @@ +; LLVM 3.7 requires a type as the first argument to 'getelementptr' +; LLVM 3.7 no longer accepts '*' with a 'call' +; REQUIRES: geq-llvm-3.7 ; RUN: llvm-as %s -f -o %t1.bc ; RUN: rm -rf %t.klee-out ; RUN: %klee --output-dir=%t.klee-out -disable-opt %t1.bc > %t2 @@ -20,15 +23,15 @@ declare i32 @puts(i8*) define i32 @main(i32 %argc, i8** nocapture %argv) nounwind readnone { entry: - %call = call i32 (i64)* bitcast (i32 (i32)* @foo to i32 (i64)*)(i64 52) + %call = call i32 (i64) bitcast (i32 (i32)* @foo to i32 (i64)*)(i64 52) %r = icmp eq i32 %call, 52 br i1 %r, label %bbtrue, label %bbfalse bbtrue: - %0 = call i32 @puts(i8* getelementptr inbounds ([5 x i8]* @.passstr, i64 0, i64 0)) nounwind + %0 = call i32 @puts(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.passstr, i64 0, i64 0)) nounwind ret i32 0 bbfalse: - %1 = call i32 @puts(i8* getelementptr inbounds ([5 x i8]* @.failstr, i64 0, i64 0)) nounwind + %1 = call i32 @puts(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.failstr, i64 0, i64 0)) nounwind ret i32 0 } diff --git a/test/Feature/BitcastAliasMD2U.leq36.ll b/test/Feature/BitcastAliasMD2U.leq36.ll new file mode 100644 index 00000000..cef8ac54 --- /dev/null +++ b/test/Feature/BitcastAliasMD2U.leq36.ll @@ -0,0 +1,35 @@ +; REQUIRES: lt-llvm-3.7 +; RUN: llvm-as %s -f -o %t1.bc +; RUN: rm -rf %t.klee-out +; RUN: %klee --output-dir=%t.klee-out -disable-opt -search=nurs:md2u %t1.bc > %t2 +; RUN: grep PASS %t2 + +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" +target triple = "x86_64-unknown-linux-gnu" + +@foo = alias i32 (i32)* @__foo + +define i32 @__foo(i32 %i) nounwind { +entry: + ret i32 %i +} + +declare i32 @puts(i8*) + +@.passstr = private constant [5 x i8] c"PASS\00", align 1 +@.failstr = private constant [5 x i8] c"FAIL\00", align 1 + +define i32 @main(i32 %argc, i8** nocapture %argv) nounwind readnone { +entry: + %call = call i32 (i64)* bitcast (i32 (i32)* @foo to i32 (i64)*)(i64 52) + %r = icmp eq i32 %call, 52 + br i1 %r, label %bbtrue, label %bbfalse + +bbtrue: + %0 = call i32 @puts(i8* getelementptr inbounds ([5 x i8]* @.passstr, i64 0, i64 0)) nounwind + ret i32 0 + +bbfalse: + %1 = call i32 @puts(i8* getelementptr inbounds ([5 x i8]* @.failstr, i64 0, i64 0)) nounwind + ret i32 0 +} diff --git a/test/Feature/BitcastAliasMD2U.ll b/test/Feature/BitcastAliasMD2U.ll index 24eabaa5..7eddd3d6 100644 --- a/test/Feature/BitcastAliasMD2U.ll +++ b/test/Feature/BitcastAliasMD2U.ll @@ -1,3 +1,6 @@ +; LLVM 3.7 requires a type as the first argument to 'getelementptr' +; LLVM 3.7 no longer accepts '*' with a 'call' +; REQUIRES: geq-llvm-3.7 ; RUN: llvm-as %s -f -o %t1.bc ; RUN: rm -rf %t.klee-out ; RUN: %klee --output-dir=%t.klee-out -disable-opt -search=nurs:md2u %t1.bc > %t2 @@ -20,15 +23,15 @@ declare i32 @puts(i8*) define i32 @main(i32 %argc, i8** nocapture %argv) nounwind readnone { entry: - %call = call i32 (i64)* bitcast (i32 (i32)* @foo to i32 (i64)*)(i64 52) + %call = call i32 (i64) bitcast (i32 (i32)* @foo to i32 (i64)*)(i64 52) %r = icmp eq i32 %call, 52 br i1 %r, label %bbtrue, label %bbfalse bbtrue: - %0 = call i32 @puts(i8* getelementptr inbounds ([5 x i8]* @.passstr, i64 0, i64 0)) nounwind + %0 = call i32 @puts(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.passstr, i64 0, i64 0)) nounwind ret i32 0 bbfalse: - %1 = call i32 @puts(i8* getelementptr inbounds ([5 x i8]* @.failstr, i64 0, i64 0)) nounwind + %1 = call i32 @puts(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.failstr, i64 0, i64 0)) nounwind ret i32 0 } diff --git a/test/Feature/ConstantArray.leq36.ll b/test/Feature/ConstantArray.leq36.ll new file mode 100644 index 00000000..a4986ff4 --- /dev/null +++ b/test/Feature/ConstantArray.leq36.ll @@ -0,0 +1,52 @@ +; REQUIRES: lt-llvm-3.7 +; RUN: llvm-as %s -f -o %t1.bc +; RUN: rm -rf %t.klee-out +; RUN: %klee --output-dir=%t.klee-out -disable-opt %t1.bc 2>&1 | FileCheck %s +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +@.str = private unnamed_addr constant [2 x i8] c"0\00", align 1 +@.str2 = private unnamed_addr constant [2 x i8] c"1\00", align 1 + +%struct.dirent = type { i32, i32, i16, i8 } +declare void @klee_print_expr(i8*, ...) + +define i32 @main() { +entry: + %a = alloca %struct.dirent + %tmp1 = getelementptr %struct.dirent* %a, i32 0 + %tmp2 = bitcast %struct.dirent* %tmp1 to <2 x i32>* + ; Initialize with constant vector + store <2 x i32> <i32 42, i32 4096>, <2 x i32>* %tmp2 + br label %exit +exit: + ; Print first initialized element + %idx = getelementptr %struct.dirent* %a, i32 0, i32 0 + %val = load i32* %idx + call void(i8*, ...)* @klee_print_expr(i8* getelementptr inbounds ([2 x i8]* @.str, i32 0, i32 0), i32 %val) + ; CHECK: 0:42 + + ; Print second initialized element + %idx2 = getelementptr %struct.dirent* %a, i32 0, i32 1 + %val2 = load i32* %idx2 + call void(i8*, ...)* @klee_print_expr(i8* getelementptr inbounds ([2 x i8]* @.str2, i32 0, i32 0), i32 %val2) + ; CHECK: 1:4096 + + ; Initialize with constant array + %array = alloca [2 x i32]; + store [2 x i32][i32 7, i32 9], [2 x i32]* %array + + ; Print first initialized element + %idx3 = getelementptr [2 x i32]* %array, i32 0, i32 0 + %val3 = load i32* %idx3 + call void(i8*, ...)* @klee_print_expr(i8* getelementptr inbounds ([2 x i8]* @.str, i32 0, i32 0), i32 %val3) + ; CHECK: 0:7 + + ; Print second initialized element + %idx4 = getelementptr [2 x i32]* %array, i32 0, i32 1 + %val4 = load i32* %idx4 + call void(i8*, ...)* @klee_print_expr(i8* getelementptr inbounds ([2 x i8]* @.str2, i32 0, i32 0), i32 %val4) + ; CHECK: 1:9 + + ret i32 0 +} diff --git a/test/Feature/ConstantArray.ll b/test/Feature/ConstantArray.ll index 161b2a16..195b4cb0 100644 --- a/test/Feature/ConstantArray.ll +++ b/test/Feature/ConstantArray.ll @@ -1,3 +1,7 @@ +; LLVM 3.7 requires a type as the first argument to 'getelementptr' +; LLVM 3.7 requires a type as the first argument to 'load' +; LLVM 3.7 no longer accepts '*' with a 'call' +; REQUIRES: geq-llvm-3.7 ; RUN: llvm-as %s -f -o %t1.bc ; RUN: rm -rf %t.klee-out ; RUN: %klee --output-dir=%t.klee-out -disable-opt %t1.bc 2>&1 | FileCheck %s @@ -13,22 +17,22 @@ declare void @klee_print_expr(i8*, ...) define i32 @main() { entry: %a = alloca %struct.dirent - %tmp1 = getelementptr %struct.dirent* %a, i32 0 + %tmp1 = getelementptr %struct.dirent, %struct.dirent* %a, i32 0 %tmp2 = bitcast %struct.dirent* %tmp1 to <2 x i32>* ; Initialize with constant vector store <2 x i32> <i32 42, i32 4096>, <2 x i32>* %tmp2 br label %exit exit: ; Print first initialized element - %idx = getelementptr %struct.dirent* %a, i32 0, i32 0 - %val = load i32* %idx - call void(i8*, ...)* @klee_print_expr(i8* getelementptr inbounds ([2 x i8]* @.str, i32 0, i32 0), i32 %val) + %idx = getelementptr %struct.dirent, %struct.dirent* %a, i32 0, i32 0 + %val = load i32, i32* %idx + call void(i8*, ...) @klee_print_expr(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str, i32 0, i32 0), i32 %val) ; CHECK: 0:42 ; Print second initialized element - %idx2 = getelementptr %struct.dirent* %a, i32 0, i32 1 - %val2 = load i32* %idx2 - call void(i8*, ...)* @klee_print_expr(i8* getelementptr inbounds ([2 x i8]* @.str2, i32 0, i32 0), i32 %val2) + %idx2 = getelementptr %struct.dirent, %struct.dirent* %a, i32 0, i32 1 + %val2 = load i32, i32* %idx2 + call void(i8*, ...) @klee_print_expr(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str2, i32 0, i32 0), i32 %val2) ; CHECK: 1:4096 ; Initialize with constant array @@ -36,16 +40,16 @@ exit: store [2 x i32][i32 7, i32 9], [2 x i32]* %array ; Print first initialized element - %idx3 = getelementptr [2 x i32]* %array, i32 0, i32 0 - %val3 = load i32* %idx3 - call void(i8*, ...)* @klee_print_expr(i8* getelementptr inbounds ([2 x i8]* @.str, i32 0, i32 0), i32 %val3) + %idx3 = getelementptr [2 x i32], [2 x i32]* %array, i32 0, i32 0 + %val3 = load i32, i32* %idx3 + call void(i8*, ...) @klee_print_expr(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str, i32 0, i32 0), i32 %val3) ; CHECK: 0:7 ; Print second initialized element - %idx4 = getelementptr [2 x i32]* %array, i32 0, i32 1 - %val4 = load i32* %idx4 - call void(i8*, ...)* @klee_print_expr(i8* getelementptr inbounds ([2 x i8]* @.str2, i32 0, i32 0), i32 %val4) + %idx4 = getelementptr [2 x i32], [2 x i32]* %array, i32 0, i32 1 + %val4 = load i32, i32* %idx4 + call void(i8*, ...) @klee_print_expr(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str2, i32 0, i32 0), i32 %val4) ; CHECK: 1:9 ret i32 0 -} \ No newline at end of file +} diff --git a/test/Feature/ConstantStruct.leq36.ll b/test/Feature/ConstantStruct.leq36.ll new file mode 100644 index 00000000..073544d3 --- /dev/null +++ b/test/Feature/ConstantStruct.leq36.ll @@ -0,0 +1,34 @@ +; REQUIRES: lt-llvm-3.7 +; RUN: llvm-as %s -f -o %t1.bc +; RUN: rm -rf %t.klee-out +; RUN: %klee --output-dir=%t.klee-out -disable-opt %t1.bc > %t2 +; RUN: grep PASS %t2 + +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" +target triple = "x86_64-unknown-linux-gnu" + +%struct.sfoo = type { i32, i64 } + +declare i32 @puts(i8*) +declare i32 @printf(i8*, ...) + +@.passstr = private constant [5 x i8] c"PASS\00", align 1 +@.failstr = private constant [5 x i8] c"FAIL\00", align 1 + +define i32 @main(i32 %argc, i8** nocapture %argv) nounwind readnone { +entry: + %f0 = extractvalue %struct.sfoo { i32 3, i64 1 }, 0 + %f1 = extractvalue %struct.sfoo { i32 3, i64 1 }, 1 + %xf0 = zext i32 %f0 to i64 + %f0mf1 = sub i64 %xf0, %f1 + %r = icmp eq i64 %f0mf1, 2 + br i1 %r, label %bbtrue, label %bbfalse + +bbtrue: + %0 = call i32 @puts(i8* getelementptr inbounds ([5 x i8]* @.passstr, i64 0, i64 0)) nounwind + ret i32 0 + +bbfalse: + %1 = call i32 @puts(i8* getelementptr inbounds ([5 x i8]* @.failstr, i64 0, i64 0)) nounwind + ret i32 0 +} diff --git a/test/Feature/ConstantStruct.ll b/test/Feature/ConstantStruct.ll index 4fe6b5d0..e4b3d07b 100644 --- a/test/Feature/ConstantStruct.ll +++ b/test/Feature/ConstantStruct.ll @@ -1,3 +1,5 @@ +; LLVM 3.7 requires a type as the first argument to 'getelementptr' +; REQUIRES: geq-llvm-3.7 ; RUN: llvm-as %s -f -o %t1.bc ; RUN: rm -rf %t.klee-out ; RUN: %klee --output-dir=%t.klee-out -disable-opt %t1.bc > %t2 @@ -24,10 +26,10 @@ entry: br i1 %r, label %bbtrue, label %bbfalse bbtrue: - %0 = call i32 @puts(i8* getelementptr inbounds ([5 x i8]* @.passstr, i64 0, i64 0)) nounwind + %0 = call i32 @puts(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.passstr, i64 0, i64 0)) nounwind ret i32 0 bbfalse: - %1 = call i32 @puts(i8* getelementptr inbounds ([5 x i8]* @.failstr, i64 0, i64 0)) nounwind + %1 = call i32 @puts(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.failstr, i64 0, i64 0)) nounwind ret i32 0 } diff --git a/test/Feature/GetElementPtr.leq36.ll b/test/Feature/GetElementPtr.leq36.ll new file mode 100644 index 00000000..43f33e27 --- /dev/null +++ b/test/Feature/GetElementPtr.leq36.ll @@ -0,0 +1,30 @@ +; REQUIRES: lt-llvm-3.7 +; RUN: llvm-as %s -f -o %t1.bc +; RUN: rm -rf %t.klee-out +; RUN: %klee --output-dir=%t.klee-out -disable-opt %t1.bc > %t2 +; RUN: grep PASS %t2 + +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" +target triple = "x86_64-unknown-linux-gnu" + +declare i32 @puts(i8*) + +@.passstr = private constant [5 x i8] c"PASS\00", align 1 +@.failstr = private constant [5 x i8] c"FAIL\00", align 1 + +define i32 @main() { +entry: + %addr = alloca i8, align 4 + %addrp1 = getelementptr i8* %addr, i32 1 + %addrp1m1 = getelementptr i8* %addrp1, i32 -1 + %test = icmp eq i8* %addr, %addrp1m1 + br i1 %test, label %bbtrue, label %bbfalse + +bbtrue: + %0 = call i32 @puts(i8* getelementptr inbounds ([5 x i8]* @.passstr, i64 0, i64 0)) nounwind + ret i32 0 + +bbfalse: + %1 = call i32 @puts(i8* getelementptr inbounds ([5 x i8]* @.failstr, i64 0, i64 0)) nounwind + ret i32 0 +} diff --git a/test/Feature/GetElementPtr.ll b/test/Feature/GetElementPtr.ll index da94441c..f7f8aada 100644 --- a/test/Feature/GetElementPtr.ll +++ b/test/Feature/GetElementPtr.ll @@ -1,3 +1,5 @@ +; LLVM 3.7 requires a type as the first argument to 'getelementptr' +; REQUIRES: geq-llvm-3.7 ; RUN: llvm-as %s -f -o %t1.bc ; RUN: rm -rf %t.klee-out ; RUN: %klee --output-dir=%t.klee-out -disable-opt %t1.bc > %t2 @@ -14,16 +16,16 @@ declare i32 @puts(i8*) define i32 @main() { entry: %addr = alloca i8, align 4 - %addrp1 = getelementptr i8* %addr, i32 1 - %addrp1m1 = getelementptr i8* %addrp1, i32 -1 + %addrp1 = getelementptr i8, i8* %addr, i32 1 + %addrp1m1 = getelementptr i8, i8* %addrp1, i32 -1 %test = icmp eq i8* %addr, %addrp1m1 br i1 %test, label %bbtrue, label %bbfalse bbtrue: - %0 = call i32 @puts(i8* getelementptr inbounds ([5 x i8]* @.passstr, i64 0, i64 0)) nounwind + %0 = call i32 @puts(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.passstr, i64 0, i64 0)) nounwind ret i32 0 bbfalse: - %1 = call i32 @puts(i8* getelementptr inbounds ([5 x i8]* @.failstr, i64 0, i64 0)) nounwind + %1 = call i32 @puts(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.failstr, i64 0, i64 0)) nounwind ret i32 0 } diff --git a/test/Feature/InsertExtractValue.leq36.ll b/test/Feature/InsertExtractValue.leq36.ll new file mode 100644 index 00000000..431e14c4 --- /dev/null +++ b/test/Feature/InsertExtractValue.leq36.ll @@ -0,0 +1,34 @@ +; REQUIRES: lt-llvm-3.7 +; RUN: llvm-as %s -f -o %t1.bc +; RUN: rm -rf %t.klee-out +; RUN: %klee --output-dir=%t.klee-out -disable-opt %t1.bc > %t2 +; RUN: grep PASS %t2 + +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" +target triple = "x86_64-unknown-linux-gnu" + +%struct.sfoo = type { i32, i32 } + +declare i32 @puts(i8*) + +@.passstr = private constant [5 x i8] c"PASS\00", align 1 +@.failstr = private constant [5 x i8] c"FAIL\00", align 1 + +define i32 @main(i32 %argc, i8** nocapture %argv) nounwind readnone { +entry: + %s0 = insertvalue %struct.sfoo undef, i32 3, 0 + %s1 = insertvalue %struct.sfoo %s0, i32 1, 1 + %f0 = extractvalue %struct.sfoo %s1, 0 + %f1 = extractvalue %struct.sfoo %s1, 1 + %f0mf1 = sub i32 %f0, %f1 + %r = icmp eq i32 %f0mf1, 2 + br i1 %r, label %bbtrue, label %bbfalse + +bbtrue: + %0 = call i32 @puts(i8* getelementptr inbounds ([5 x i8]* @.passstr, i64 0, i64 0)) nounwind + ret i32 0 + +bbfalse: + %1 = call i32 @puts(i8* getelementptr inbounds ([5 x i8]* @.failstr, i64 0, i64 0)) nounwind + ret i32 0 +} diff --git a/test/Feature/InsertExtractValue.ll b/test/Feature/InsertExtractValue.ll index 83e8f851..fff6da7c 100644 --- a/test/Feature/InsertExtractValue.ll +++ b/test/Feature/InsertExtractValue.ll @@ -1,3 +1,5 @@ +; LLVM 3.7 requires a type as the first argument to 'getelementptr' +; REQUIRES: geq-llvm-3.7 ; RUN: llvm-as %s -f -o %t1.bc ; RUN: rm -rf %t.klee-out ; RUN: %klee --output-dir=%t.klee-out -disable-opt %t1.bc > %t2 @@ -24,10 +26,10 @@ entry: br i1 %r, label %bbtrue, label %bbfalse bbtrue: - %0 = call i32 @puts(i8* getelementptr inbounds ([5 x i8]* @.passstr, i64 0, i64 0)) nounwind + %0 = call i32 @puts(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.passstr, i64 0, i64 0)) nounwind ret i32 0 bbfalse: - %1 = call i32 @puts(i8* getelementptr inbounds ([5 x i8]* @.failstr, i64 0, i64 0)) nounwind + %1 = call i32 @puts(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.failstr, i64 0, i64 0)) nounwind ret i32 0 } diff --git a/test/Feature/Overflow.leq36.ll b/test/Feature/Overflow.leq36.ll new file mode 100644 index 00000000..2ab04772 --- /dev/null +++ b/test/Feature/Overflow.leq36.ll @@ -0,0 +1,45 @@ +; REQUIRES: lt-llvm-3.7 +; RUN: llvm-as %s -f -o %t1.bc +; RUN: rm -rf %t.klee-out +; RUN: %klee --output-dir=%t.klee-out -disable-opt %t1.bc > %t2 +; RUN: grep PASS %t2 + +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" +target triple = "x86_64-unknown-linux-gnu" + +declare {i8, i1} @llvm.uadd.with.overflow.i8(i8 %a, i8 %b) + +declare i32 @puts(i8*) + +@.passstr = private constant [5 x i8] c"PASS\00", align 1 +@.failstr = private constant [5 x i8] c"FAIL\00", align 1 + +define i32 @main() { +bb0: + %s0 = call {i8, i1} @llvm.uadd.with.overflow.i8(i8 0, i8 -1) + %v0 = extractvalue {i8, i1} %s0, 0 + %c0 = icmp eq i8 %v0, -1 + br i1 %c0, label %bb0_1, label %bbfalse + +bb0_1: + %o0 = extractvalue {i8, i1} %s0, 1 + br i1 %o0, label %bbfalse, label %bb1 + +bb1: + %s1 = call {i8, i1} @llvm.uadd.with.overflow.i8(i8 1, i8 -1) + %v1 = extractvalue {i8, i1} %s1, 0 + %c1 = icmp eq i8 %v1, 0 + br i1 %c1, label %bb1_1, label %bbfalse + +bb1_1: + %o1 = extractvalue {i8, i1} %s1, 1 + br i1 %o1, label %bbtrue, label %bbfalse + +bbtrue: + %0 = call i32 @puts(i8* getelementptr inbounds ([5 x i8]* @.passstr, i64 0, i64 0)) nounwind + ret i32 0 + +bbfalse: + %1 = call i32 @puts(i8* getelementptr inbounds ([5 x i8]* @.failstr, i64 0, i64 0)) nounwind + ret i32 0 +} diff --git a/test/Feature/Overflow.ll b/test/Feature/Overflow.ll index 35dfbd10..1dbe1216 100644 --- a/test/Feature/Overflow.ll +++ b/test/Feature/Overflow.ll @@ -1,3 +1,5 @@ +; LLVM 3.7 requires a type as the first argument to 'getelementptr' +; REQUIRES: geq-llvm-3.7 ; RUN: llvm-as %s -f -o %t1.bc ; RUN: rm -rf %t.klee-out ; RUN: %klee --output-dir=%t.klee-out -disable-opt %t1.bc > %t2 @@ -35,10 +37,10 @@ bb1_1: br i1 %o1, label %bbtrue, label %bbfalse bbtrue: - %0 = call i32 @puts(i8* getelementptr inbounds ([5 x i8]* @.passstr, i64 0, i64 0)) nounwind + %0 = call i32 @puts(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.passstr, i64 0, i64 0)) nounwind ret i32 0 bbfalse: - %1 = call i32 @puts(i8* getelementptr inbounds ([5 x i8]* @.failstr, i64 0, i64 0)) nounwind + %1 = call i32 @puts(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.failstr, i64 0, i64 0)) nounwind ret i32 0 } diff --git a/test/Feature/OverflowMul.leq36.ll b/test/Feature/OverflowMul.leq36.ll new file mode 100644 index 00000000..1b14d380 --- /dev/null +++ b/test/Feature/OverflowMul.leq36.ll @@ -0,0 +1,45 @@ +; REQUIRES: lt-llvm-3.7 +; RUN: llvm-as %s -f -o %t1.bc +; RUN: rm -rf %t.klee-out +; RUN: %klee --output-dir=%t.klee-out -disable-opt %t1.bc > %t2 +; RUN: grep PASS %t2 + +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" +target triple = "x86_64-unknown-linux-gnu" + +declare {i8, i1} @llvm.umul.with.overflow.i8(i8 %a, i8 %b) + +declare i32 @puts(i8*) + +@.passstr = private constant [5 x i8] c"PASS\00", align 1 +@.failstr = private constant [5 x i8] c"FAIL\00", align 1 + +define i32 @main() { +bb0: + %s0 = call {i8, i1} @llvm.umul.with.overflow.i8(i8 1, i8 128) + %v0 = extractvalue {i8, i1} %s0, 0 + %c0 = icmp eq i8 %v0, 128 + br i1 %c0, label %bb0_1, label %bbfalse + +bb0_1: + %o0 = extractvalue {i8, i1} %s0, 1 + br i1 %o0, label %bbfalse, label %bb1 + +bb1: + %s1 = call {i8, i1} @llvm.umul.with.overflow.i8(i8 2, i8 128) + %v1 = extractvalue {i8, i1} %s1, 0 + %c1 = icmp eq i8 %v1, 0 + br i1 %c1, label %bb1_1, label %bbfalse + +bb1_1: + %o1 = extractvalue {i8, i1} %s1, 1 + br i1 %o1, label %bbtrue, label %bbfalse + +bbtrue: + %0 = call i32 @puts(i8* getelementptr inbounds ([5 x i8]* @.passstr, i64 0, i64 0)) nounwind + ret i32 0 + +bbfalse: + %1 = call i32 @puts(i8* getelementptr inbounds ([5 x i8]* @.failstr, i64 0, i64 0)) nounwind + ret i32 0 +} diff --git a/test/Feature/OverflowMul.ll b/test/Feature/OverflowMul.ll index 7026aa74..3173e43c 100644 --- a/test/Feature/OverflowMul.ll +++ b/test/Feature/OverflowMul.ll @@ -1,3 +1,5 @@ +; LLVM 3.7 requires a type as the first argument to 'getelementptr' +; REQUIRES: geq-llvm-3.7 ; RUN: llvm-as %s -f -o %t1.bc ; RUN: rm -rf %t.klee-out ; RUN: %klee --output-dir=%t.klee-out -disable-opt %t1.bc > %t2 @@ -35,10 +37,10 @@ bb1_1: br i1 %o1, label %bbtrue, label %bbfalse bbtrue: - %0 = call i32 @puts(i8* getelementptr inbounds ([5 x i8]* @.passstr, i64 0, i64 0)) nounwind + %0 = call i32 @puts(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.passstr, i64 0, i64 0)) nounwind ret i32 0 bbfalse: - %1 = call i32 @puts(i8* getelementptr inbounds ([5 x i8]* @.failstr, i64 0, i64 0)) nounwind + %1 = call i32 @puts(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.failstr, i64 0, i64 0)) nounwind ret i32 0 } diff --git a/test/Feature/_utils._ll b/test/Feature/_utils._ll index 32a73bb1..d825df3a 100644 --- a/test/Feature/_utils._ll +++ b/test/Feature/_utils._ll @@ -1,3 +1,6 @@ +; LLVM 3.7 requires a type as the first argument to 'getelementptr' +; LLVM 3.7 requires a type as the first argument to 'load' + define i32 @util_make_and_i1(i32 %a, i32 %b) { %a_i1 = icmp ne i32 %a, 0 %b_i1 = icmp ne i32 %b, 0 @@ -17,26 +20,26 @@ define i32 @util_make_or_i1(i32 %a, i32 %b) { define i16 @util_make_concat2(i8 %a, i8 %b) { %tmp = alloca i16 %tmp8 = bitcast i16* %tmp to i8* - %p0 = getelementptr i8* %tmp8, i32 0 - %p1 = getelementptr i8* %tmp8, i32 1 + %p0 = getelementptr i8, i8* %tmp8, i32 0 + %p1 = getelementptr i8, i8* %tmp8, i32 1 store i8 %b, i8* %p0 store i8 %a, i8* %p1 - %concat = load i16* %tmp + %concat = load i16, i16* %tmp ret i16 %concat } define i32 @util_make_concat4(i8 %a, i8 %b, i8 %c, i8 %d) { %tmp = alloca i32 %tmp8 = bitcast i32* %tmp to i8* - %p0 = getelementptr i8* %tmp8, i32 0 - %p1 = getelementptr i8* %tmp8, i32 1 - %p2 = getelementptr i8* %tmp8, i32 2 - %p3 = getelementptr i8* %tmp8, i32 3 + %p0 = getelementptr i8, i8* %tmp8, i32 0 + %p1 = getelementptr i8, i8* %tmp8, i32 1 + %p2 = getelementptr i8, i8* %tmp8, i32 2 + %p3 = getelementptr i8, i8* %tmp8, i32 3 store i8 %d, i8* %p0 store i8 %c, i8* %p1 store i8 %b, i8* %p2 store i8 %a, i8* %p3 - %concat = load i32* %tmp + %concat = load i32, i32* %tmp ret i32 %concat } @@ -44,14 +47,14 @@ define i64 @util_make_concat8(i8 %a, i8 %b, i8 %c, i8 %d, i8 %e, i8 %f, i8 %g, i8 %h) { %tmp = alloca i64 %tmp8 = bitcast i64* %tmp to i8* - %p0 = getelementptr i8* %tmp8, i32 0 - %p1 = getelementptr i8* %tmp8, i32 1 - %p2 = getelementptr i8* %tmp8, i32 2 - %p3 = getelementptr i8* %tmp8, i32 3 - %p4 = getelementptr i8* %tmp8, i32 4 - %p5 = getelementptr i8* %tmp8, i32 5 - %p6 = getelementptr i8* %tmp8, i32 6 - %p7 = getelementptr i8* %tmp8, i32 7 + %p0 = getelementptr i8, i8* %tmp8, i32 0 + %p1 = getelementptr i8, i8* %tmp8, i32 1 + %p2 = getelementptr i8, i8* %tmp8, i32 2 + %p3 = getelementptr i8, i8* %tmp8, i32 3 + %p4 = getelementptr i8, i8* %tmp8, i32 4 + %p5 = getelementptr i8, i8* %tmp8, i32 5 + %p6 = getelementptr i8, i8* %tmp8, i32 6 + %p7 = getelementptr i8, i8* %tmp8, i32 7 store i8 %h, i8* %p0 store i8 %g, i8* %p1 store i8 %f, i8* %p2 @@ -60,7 +63,7 @@ define i64 @util_make_concat8(i8 %a, i8 %b, i8 %c, i8 %d, store i8 %c, i8* %p5 store i8 %b, i8* %p6 store i8 %a, i8* %p7 - %concat = load i64* %tmp + %concat = load i64, i64* %tmp ret i64 %concat } @@ -68,4 +71,4 @@ define i32 @util_make_select(i32 %cond, i32 %t, i32 %f) { %cond_i1 = icmp ne i32 %cond, 0 %res = select i1 %cond_i1, i32 %t, i32 %f ret i32 %res -} \ No newline at end of file +} diff --git a/test/Feature/_utils.leq36._ll b/test/Feature/_utils.leq36._ll new file mode 100644 index 00000000..32a73bb1 --- /dev/null +++ b/test/Feature/_utils.leq36._ll @@ -0,0 +1,71 @@ +define i32 @util_make_and_i1(i32 %a, i32 %b) { + %a_i1 = icmp ne i32 %a, 0 + %b_i1 = icmp ne i32 %b, 0 + %res_i1 = and i1 %a_i1, %b_i1 + %res = zext i1 %res_i1 to i32 + ret i32 %res +} + +define i32 @util_make_or_i1(i32 %a, i32 %b) { + %a_i1 = icmp ne i32 %a, 0 + %b_i1 = icmp ne i32 %b, 0 + %res_i1 = or i1 %a_i1, %b_i1 + %res = zext i1 %res_i1 to i32 + ret i32 %res +} + +define i16 @util_make_concat2(i8 %a, i8 %b) { + %tmp = alloca i16 + %tmp8 = bitcast i16* %tmp to i8* + %p0 = getelementptr i8* %tmp8, i32 0 + %p1 = getelementptr i8* %tmp8, i32 1 + store i8 %b, i8* %p0 + store i8 %a, i8* %p1 + %concat = load i16* %tmp + ret i16 %concat +} + +define i32 @util_make_concat4(i8 %a, i8 %b, i8 %c, i8 %d) { + %tmp = alloca i32 + %tmp8 = bitcast i32* %tmp to i8* + %p0 = getelementptr i8* %tmp8, i32 0 + %p1 = getelementptr i8* %tmp8, i32 1 + %p2 = getelementptr i8* %tmp8, i32 2 + %p3 = getelementptr i8* %tmp8, i32 3 + store i8 %d, i8* %p0 + store i8 %c, i8* %p1 + store i8 %b, i8* %p2 + store i8 %a, i8* %p3 + %concat = load i32* %tmp + ret i32 %concat +} + +define i64 @util_make_concat8(i8 %a, i8 %b, i8 %c, i8 %d, + i8 %e, i8 %f, i8 %g, i8 %h) { + %tmp = alloca i64 + %tmp8 = bitcast i64* %tmp to i8* + %p0 = getelementptr i8* %tmp8, i32 0 + %p1 = getelementptr i8* %tmp8, i32 1 + %p2 = getelementptr i8* %tmp8, i32 2 + %p3 = getelementptr i8* %tmp8, i32 3 + %p4 = getelementptr i8* %tmp8, i32 4 + %p5 = getelementptr i8* %tmp8, i32 5 + %p6 = getelementptr i8* %tmp8, i32 6 + %p7 = getelementptr i8* %tmp8, i32 7 + store i8 %h, i8* %p0 + store i8 %g, i8* %p1 + store i8 %f, i8* %p2 + store i8 %e, i8* %p3 + store i8 %d, i8* %p4 + store i8 %c, i8* %p5 + store i8 %b, i8* %p6 + store i8 %a, i8* %p7 + %concat = load i64* %tmp + ret i64 %concat +} + +define i32 @util_make_select(i32 %cond, i32 %t, i32 %f) { + %cond_i1 = icmp ne i32 %cond, 0 + %res = select i1 %cond_i1, i32 %t, i32 %f + ret i32 %res +} \ No newline at end of file diff --git a/test/Intrinsics/objectsize.leq36.ll b/test/Intrinsics/objectsize.leq36.ll new file mode 100644 index 00000000..7ad4b6fc --- /dev/null +++ b/test/Intrinsics/objectsize.leq36.ll @@ -0,0 +1,33 @@ +; REQUIRES: lt-llvm-3.7 +; RUN: %llvmas %s -o=%t.bc +; RUN: rm -rf %t.klee-out +; RUN: %klee -exit-on-error --output-dir=%t.klee-out -disable-opt %t.bc +; ModuleID = 'objectsize.c' +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +define i32 @main() nounwind uwtable { +entry: + %a = alloca i8*, align 8 + %0 = load i8** %a, align 8 + %1 = call i64 @llvm.objectsize.i64.p0i8(i8* %0, i1 true) + %cmp = icmp ne i64 %1, 0 + br i1 %cmp, label %abort.block, label %continue.block + +continue.block: + %2 = load i8** %a, align 8 + %3 = call i64 @llvm.objectsize.i64.p0i8(i8* %2, i1 false) + %cmp1 = icmp ne i64 %3, -1 + br i1 %cmp1, label %abort.block, label %exit.block + +exit.block: + ret i32 0 + +abort.block: + call void @abort() + unreachable +} + +declare i64 @llvm.objectsize.i64.p0i8(i8*, i1) nounwind readnone + +declare void @abort() noreturn nounwind diff --git a/test/Intrinsics/objectsize.ll b/test/Intrinsics/objectsize.ll index 4bb59596..3a111f99 100644 --- a/test/Intrinsics/objectsize.ll +++ b/test/Intrinsics/objectsize.ll @@ -1,3 +1,8 @@ +; Unfortunately LLVM 2.9 has a different suffix for the ``llvm.objectsize`` instrinsic +; so this LLVM IR fails to verify for that version. +; +; LLVM 3.7 requires a type as the first argument to 'load' +; REQUIRES: geq-llvm-3.7 ; RUN: %llvmas %s -o=%t.bc ; RUN: rm -rf %t.klee-out ; RUN: %klee -exit-on-error --output-dir=%t.klee-out -disable-opt %t.bc @@ -8,13 +13,13 @@ target triple = "x86_64-unknown-linux-gnu" define i32 @main() nounwind uwtable { entry: %a = alloca i8*, align 8 - %0 = load i8** %a, align 8 + %0 = load i8*, i8** %a, align 8 %1 = call i64 @llvm.objectsize.i64.p0i8(i8* %0, i1 true) %cmp = icmp ne i64 %1, 0 br i1 %cmp, label %abort.block, label %continue.block continue.block: - %2 = load i8** %a, align 8 + %2 = load i8*, i8** %a, align 8 %3 = call i64 @llvm.objectsize.i64.p0i8(i8* %2, i1 false) %cmp1 = icmp ne i64 %3, -1 br i1 %cmp1, label %abort.block, label %exit.block diff --git a/test/lit.cfg b/test/lit.cfg index 00b429b6..e570f9b2 100644 --- a/test/lit.cfg +++ b/test/lit.cfg @@ -161,7 +161,7 @@ if int(config.llvm_version_major) == 2: # Add feature for the LLVM version in use, so it can be tested in REQUIRES and # XFAIL checks. We also add "not-XXX" variants, for the same reason. -known_llvm_versions = set(["3.4", "3.5", "3.6"]) +known_llvm_versions = set(["3.4", "3.5", "3.6", "3.7", "3.8", "3.9"]) current_llvm_version = "%s.%s" % (config.llvm_version_major, config.llvm_version_minor) config.available_features.add("llvm-" + current_llvm_version) diff --git a/test/regression/2007-08-16-invalid-constant-value.c b/test/regression/2007-08-16-invalid-constant-value.c index 5b17e68b..fd011f2e 100644 --- a/test/regression/2007-08-16-invalid-constant-value.c +++ b/test/regression/2007-08-16-invalid-constant-value.c @@ -1,3 +1,4 @@ +// REQUIRES: geq-llvm-3.7 // RUN: rm -f %t4.out %t4.err %t4.log // RUN: %llvmgcc %s -emit-llvm -O2 -c -o %t1.bc // RUN: llvm-as -f %p/../Feature/_utils._ll -o %t2.bc @@ -18,12 +19,12 @@ int main() { // value was being created when implied value did not // subtract using the proper type (so overflowed into // invalid bits) - if (util_make_concat2(a+0xCD,0xCD) == 0xABCD) { + if (util_make_concat2(a + 0xCD, 0xCD) == 0xABCD) { assert(!klee_is_symbolic(a)); printf("add constant case: %d\n", a); } - if (util_make_concat2(0x0B-a,0xCD) == 0xABCD) { + if (util_make_concat2(0x0B - a, 0xCD) == 0xABCD) { assert(!klee_is_symbolic(a)); printf("sub constant case: %d\n", a); } diff --git a/test/regression/2007-08-16-invalid-constant-value.leq36.c b/test/regression/2007-08-16-invalid-constant-value.leq36.c new file mode 100644 index 00000000..bf9f7561 --- /dev/null +++ b/test/regression/2007-08-16-invalid-constant-value.leq36.c @@ -0,0 +1,33 @@ +// REQUIRES: lt-llvm-3.7 +// RUN: rm -f %t4.out %t4.err %t4.log +// RUN: %llvmgcc %s -emit-llvm -O2 -c -o %t1.bc +// RUN: llvm-as -f %p/../Feature/_utils.leq36._ll -o %t2.bc +// RUN: llvm-link %t1.bc %t2.bc -o %t3.bc +// RUN: rm -rf %t.klee-out +// RUN: %klee --output-dir=%t.klee-out %t3.bc + +#include <assert.h> + +#include "../Feature/utils.h" + +int main() { + unsigned char a; + + klee_make_symbolic(&a, sizeof a, "a"); + + // demand was firing here because an invalid constant + // value was being created when implied value did not + // subtract using the proper type (so overflowed into + // invalid bits) + if (util_make_concat2(a+0xCD,0xCD) == 0xABCD) { + assert(!klee_is_symbolic(a)); + printf("add constant case: %d\n", a); + } + + if (util_make_concat2(0x0B-a,0xCD) == 0xABCD) { + assert(!klee_is_symbolic(a)); + printf("sub constant case: %d\n", a); + } + + return 0; +} |