From ffe695c29915cf8605b2fb807cd083cdcc769d47 Mon Sep 17 00:00:00 2001 From: Dan Liew Date: Tue, 18 Jul 2017 16:04:19 +0100 Subject: Replace assertions of types on LLVM instructions in the Executor with a pass that checks these assertions. This improves several things. * This pass provides more friendly messages than assertions in that it just emits a warning and carries on checking the rest of the instructions. * The takes the checks outside of the Executor's hot path and so avoids checking the same instruction multiple times. Now each instruction is only checked once just before execution starts. The disadvantage of this approach is the check for invariants we expect to hold have been pulled far away from where we expect them to hold. After discussion with @ccadar and @MartinNowack it was decided we will take this hit to readability for better performance and simpler code in the Executor. --- lib/Core/Executor.cpp | 111 +------------------------------------------------- 1 file changed, 1 insertion(+), 110 deletions(-) (limited to 'lib/Core/Executor.cpp') diff --git a/lib/Core/Executor.cpp b/lib/Core/Executor.cpp index 96181a3d..884f388d 100644 --- a/lib/Core/Executor.cpp +++ b/lib/Core/Executor.cpp @@ -1922,12 +1922,7 @@ void Executor::executeInstruction(ExecutionState &state, KInstruction *ki) { // Special instructions case Instruction::Select: { - assert(i->getOperand(0)->getType()->isIntegerTy() && - "Invalid operand type"); - assert((i->getOperand(1)->getType() == i->getOperand(2)->getType()) && - "true and false operands to Select have mismatching types"); - // NOTE: We are do not check that operands 1 and 2 are not of vector type - // because the scalarizer pass might not remove these. + // NOTE: It is not required that operands 1 and 2 be of scalar type. ref cond = eval(ki, 0, state).value; ref tExpr = eval(ki, 1, state).value; ref fExpr = eval(ki, 2, state).value; @@ -1943,10 +1938,6 @@ void Executor::executeInstruction(ExecutionState &state, KInstruction *ki) { // Arithmetic / logical case Instruction::Add: { - assert(i->getOperand(0)->getType()->isIntegerTy() && - "Invalid operand type"); - assert(i->getOperand(1)->getType()->isIntegerTy() && - "Invalid operand type"); ref left = eval(ki, 0, state).value; ref right = eval(ki, 1, state).value; bindLocal(ki, state, AddExpr::create(left, right)); @@ -1954,10 +1945,6 @@ void Executor::executeInstruction(ExecutionState &state, KInstruction *ki) { } case Instruction::Sub: { - assert(i->getOperand(0)->getType()->isIntegerTy() && - "Invalid operand type"); - assert(i->getOperand(1)->getType()->isIntegerTy() && - "Invalid operand type"); ref left = eval(ki, 0, state).value; ref right = eval(ki, 1, state).value; bindLocal(ki, state, SubExpr::create(left, right)); @@ -1965,10 +1952,6 @@ void Executor::executeInstruction(ExecutionState &state, KInstruction *ki) { } case Instruction::Mul: { - assert(i->getOperand(0)->getType()->isIntegerTy() && - "Invalid operand type"); - assert(i->getOperand(1)->getType()->isIntegerTy() && - "Invalid operand type"); ref left = eval(ki, 0, state).value; ref right = eval(ki, 1, state).value; bindLocal(ki, state, MulExpr::create(left, right)); @@ -1976,10 +1959,6 @@ void Executor::executeInstruction(ExecutionState &state, KInstruction *ki) { } case Instruction::UDiv: { - assert(i->getOperand(0)->getType()->isIntegerTy() && - "Invalid operand type"); - assert(i->getOperand(1)->getType()->isIntegerTy() && - "Invalid operand type"); ref left = eval(ki, 0, state).value; ref right = eval(ki, 1, state).value; ref result = UDivExpr::create(left, right); @@ -1988,10 +1967,6 @@ void Executor::executeInstruction(ExecutionState &state, KInstruction *ki) { } case Instruction::SDiv: { - assert(i->getOperand(0)->getType()->isIntegerTy() && - "Invalid operand type"); - assert(i->getOperand(1)->getType()->isIntegerTy() && - "Invalid operand type"); ref left = eval(ki, 0, state).value; ref right = eval(ki, 1, state).value; ref result = SDivExpr::create(left, right); @@ -2000,10 +1975,6 @@ void Executor::executeInstruction(ExecutionState &state, KInstruction *ki) { } case Instruction::URem: { - assert(i->getOperand(0)->getType()->isIntegerTy() && - "Invalid operand type"); - assert(i->getOperand(1)->getType()->isIntegerTy() && - "Invalid operand type"); ref left = eval(ki, 0, state).value; ref right = eval(ki, 1, state).value; ref result = URemExpr::create(left, right); @@ -2012,10 +1983,6 @@ void Executor::executeInstruction(ExecutionState &state, KInstruction *ki) { } case Instruction::SRem: { - assert(i->getOperand(0)->getType()->isIntegerTy() && - "Invalid operand type"); - assert(i->getOperand(1)->getType()->isIntegerTy() && - "Invalid operand type"); ref left = eval(ki, 0, state).value; ref right = eval(ki, 1, state).value; ref result = SRemExpr::create(left, right); @@ -2024,10 +1991,6 @@ void Executor::executeInstruction(ExecutionState &state, KInstruction *ki) { } case Instruction::And: { - assert(i->getOperand(0)->getType()->isIntegerTy() && - "Invalid operand type"); - assert(i->getOperand(1)->getType()->isIntegerTy() && - "Invalid operand type"); ref left = eval(ki, 0, state).value; ref right = eval(ki, 1, state).value; ref result = AndExpr::create(left, right); @@ -2036,10 +1999,6 @@ void Executor::executeInstruction(ExecutionState &state, KInstruction *ki) { } case Instruction::Or: { - assert(i->getOperand(0)->getType()->isIntegerTy() && - "Invalid operand type"); - assert(i->getOperand(1)->getType()->isIntegerTy() && - "Invalid operand type"); ref left = eval(ki, 0, state).value; ref right = eval(ki, 1, state).value; ref result = OrExpr::create(left, right); @@ -2048,10 +2007,6 @@ void Executor::executeInstruction(ExecutionState &state, KInstruction *ki) { } case Instruction::Xor: { - assert(i->getOperand(0)->getType()->isIntegerTy() && - "Invalid operand type"); - assert(i->getOperand(1)->getType()->isIntegerTy() && - "Invalid operand type"); ref left = eval(ki, 0, state).value; ref right = eval(ki, 1, state).value; ref result = XorExpr::create(left, right); @@ -2060,10 +2015,6 @@ void Executor::executeInstruction(ExecutionState &state, KInstruction *ki) { } case Instruction::Shl: { - assert(i->getOperand(0)->getType()->isIntegerTy() && - "Invalid operand type"); - assert(i->getOperand(1)->getType()->isIntegerTy() && - "Invalid operand type"); ref left = eval(ki, 0, state).value; ref right = eval(ki, 1, state).value; ref result = ShlExpr::create(left, right); @@ -2072,10 +2023,6 @@ void Executor::executeInstruction(ExecutionState &state, KInstruction *ki) { } case Instruction::LShr: { - assert(i->getOperand(0)->getType()->isIntegerTy() && - "Invalid operand type"); - assert(i->getOperand(1)->getType()->isIntegerTy() && - "Invalid operand type"); ref left = eval(ki, 0, state).value; ref right = eval(ki, 1, state).value; ref result = LShrExpr::create(left, right); @@ -2084,10 +2031,6 @@ void Executor::executeInstruction(ExecutionState &state, KInstruction *ki) { } case Instruction::AShr: { - assert(i->getOperand(0)->getType()->isIntegerTy() && - "Invalid operand type"); - assert(i->getOperand(1)->getType()->isIntegerTy() && - "Invalid operand type"); ref left = eval(ki, 0, state).value; ref right = eval(ki, 1, state).value; ref result = AShrExpr::create(left, right); @@ -2098,12 +2041,6 @@ void Executor::executeInstruction(ExecutionState &state, KInstruction *ki) { // Compare case Instruction::ICmp: { - assert((i->getOperand(0)->getType()->isIntegerTy() || - i->getOperand(0)->getType()->isPointerTy()) && - "Invalid operand type"); - assert((i->getOperand(1)->getType()->isIntegerTy() || - i->getOperand(1)->getType()->isPointerTy()) && - "Invalid operand type"); CmpInst *ci = cast(i); ICmpInst *ii = cast(ci); @@ -2243,8 +2180,6 @@ void Executor::executeInstruction(ExecutionState &state, KInstruction *ki) { // Conversion case Instruction::Trunc: { - assert(i->getOperand(0)->getType()->isIntegerTy() && - "Invalid operand type"); CastInst *ci = cast(i); ref result = ExtractExpr::create(eval(ki, 0, state).value, 0, @@ -2253,8 +2188,6 @@ void Executor::executeInstruction(ExecutionState &state, KInstruction *ki) { break; } case Instruction::ZExt: { - assert(i->getOperand(0)->getType()->isIntegerTy() && - "Invalid operand type"); CastInst *ci = cast(i); ref result = ZExtExpr::create(eval(ki, 0, state).value, getWidthForLLVMType(ci->getType())); @@ -2262,8 +2195,6 @@ void Executor::executeInstruction(ExecutionState &state, KInstruction *ki) { break; } case Instruction::SExt: { - assert(i->getOperand(0)->getType()->isIntegerTy() && - "Invalid operand type"); CastInst *ci = cast(i); ref result = SExtExpr::create(eval(ki, 0, state).value, getWidthForLLVMType(ci->getType())); @@ -2272,8 +2203,6 @@ void Executor::executeInstruction(ExecutionState &state, KInstruction *ki) { } case Instruction::IntToPtr: { - assert(i->getOperand(0)->getType()->isIntegerTy() && - "Invalid operand type"); CastInst *ci = cast(i); Expr::Width pType = getWidthForLLVMType(ci->getType()); ref arg = eval(ki, 0, state).value; @@ -2281,8 +2210,6 @@ void Executor::executeInstruction(ExecutionState &state, KInstruction *ki) { break; } case Instruction::PtrToInt: { - assert(i->getOperand(0)->getType()->isPointerTy() && - "Invalid operand type"); CastInst *ci = cast(i); Expr::Width iType = getWidthForLLVMType(ci->getType()); ref arg = eval(ki, 0, state).value; @@ -2299,10 +2226,6 @@ void Executor::executeInstruction(ExecutionState &state, KInstruction *ki) { // Floating point instructions case Instruction::FAdd: { - assert(i->getOperand(0)->getType()->isFloatingPointTy() && - "Invalid operand type"); - assert(i->getOperand(1)->getType()->isFloatingPointTy() && - "Invalid operand type"); ref left = toConstant(state, eval(ki, 0, state).value, "floating point"); ref right = toConstant(state, eval(ki, 1, state).value, @@ -2323,10 +2246,6 @@ void Executor::executeInstruction(ExecutionState &state, KInstruction *ki) { } case Instruction::FSub: { - assert(i->getOperand(0)->getType()->isFloatingPointTy() && - "Invalid operand type"); - assert(i->getOperand(1)->getType()->isFloatingPointTy() && - "Invalid operand type"); ref left = toConstant(state, eval(ki, 0, state).value, "floating point"); ref right = toConstant(state, eval(ki, 1, state).value, @@ -2346,10 +2265,6 @@ void Executor::executeInstruction(ExecutionState &state, KInstruction *ki) { } case Instruction::FMul: { - assert(i->getOperand(0)->getType()->isFloatingPointTy() && - "Invalid operand type"); - assert(i->getOperand(1)->getType()->isFloatingPointTy() && - "Invalid operand type"); ref left = toConstant(state, eval(ki, 0, state).value, "floating point"); ref right = toConstant(state, eval(ki, 1, state).value, @@ -2370,10 +2285,6 @@ void Executor::executeInstruction(ExecutionState &state, KInstruction *ki) { } case Instruction::FDiv: { - assert(i->getOperand(0)->getType()->isFloatingPointTy() && - "Invalid operand type"); - assert(i->getOperand(1)->getType()->isFloatingPointTy() && - "Invalid operand type"); ref left = toConstant(state, eval(ki, 0, state).value, "floating point"); ref right = toConstant(state, eval(ki, 1, state).value, @@ -2394,10 +2305,6 @@ void Executor::executeInstruction(ExecutionState &state, KInstruction *ki) { } case Instruction::FRem: { - assert(i->getOperand(0)->getType()->isFloatingPointTy() && - "Invalid operand type"); - assert(i->getOperand(1)->getType()->isFloatingPointTy() && - "Invalid operand type"); ref left = toConstant(state, eval(ki, 0, state).value, "floating point"); ref right = toConstant(state, eval(ki, 1, state).value, @@ -2418,8 +2325,6 @@ void Executor::executeInstruction(ExecutionState &state, KInstruction *ki) { } case Instruction::FPTrunc: { - assert(i->getOperand(0)->getType()->isFloatingPointTy() && - "Invalid operand type"); FPTruncInst *fi = cast(i); Expr::Width resultType = getWidthForLLVMType(fi->getType()); ref arg = toConstant(state, eval(ki, 0, state).value, @@ -2441,8 +2346,6 @@ void Executor::executeInstruction(ExecutionState &state, KInstruction *ki) { } case Instruction::FPExt: { - assert(i->getOperand(0)->getType()->isFloatingPointTy() && - "Invalid operand type"); FPExtInst *fi = cast(i); Expr::Width resultType = getWidthForLLVMType(fi->getType()); ref arg = toConstant(state, eval(ki, 0, state).value, @@ -2463,8 +2366,6 @@ void Executor::executeInstruction(ExecutionState &state, KInstruction *ki) { } case Instruction::FPToUI: { - assert(i->getOperand(0)->getType()->isFloatingPointTy() && - "Invalid operand type"); FPToUIInst *fi = cast(i); Expr::Width resultType = getWidthForLLVMType(fi->getType()); ref arg = toConstant(state, eval(ki, 0, state).value, @@ -2486,8 +2387,6 @@ void Executor::executeInstruction(ExecutionState &state, KInstruction *ki) { } case Instruction::FPToSI: { - assert(i->getOperand(0)->getType()->isFloatingPointTy() && - "Invalid operand type"); FPToSIInst *fi = cast(i); Expr::Width resultType = getWidthForLLVMType(fi->getType()); ref arg = toConstant(state, eval(ki, 0, state).value, @@ -2509,8 +2408,6 @@ void Executor::executeInstruction(ExecutionState &state, KInstruction *ki) { } case Instruction::UIToFP: { - assert(i->getOperand(0)->getType()->isIntegerTy() && - "Invalid operand type"); UIToFPInst *fi = cast(i); Expr::Width resultType = getWidthForLLVMType(fi->getType()); ref arg = toConstant(state, eval(ki, 0, state).value, @@ -2527,8 +2424,6 @@ void Executor::executeInstruction(ExecutionState &state, KInstruction *ki) { } case Instruction::SIToFP: { - assert(i->getOperand(0)->getType()->isIntegerTy() && - "Invalid operand type"); SIToFPInst *fi = cast(i); Expr::Width resultType = getWidthForLLVMType(fi->getType()); ref arg = toConstant(state, eval(ki, 0, state).value, @@ -2545,10 +2440,6 @@ void Executor::executeInstruction(ExecutionState &state, KInstruction *ki) { } case Instruction::FCmp: { - assert(i->getOperand(0)->getType()->isFloatingPointTy() && - "Invalid operand type"); - assert(i->getOperand(1)->getType()->isFloatingPointTy() && - "Invalid operand type"); FCmpInst *fi = cast(i); ref left = toConstant(state, eval(ki, 0, state).value, "floating point"); -- cgit 1.4.1