-
Notifications
You must be signed in to change notification settings - Fork 178
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
error: unsupported llvm instruction fneg #197
Comments
i think the following patch can solve this issue, but i have no idea about whether it is the best way to solve it diff --git a/frontend/llvm/src/import/function.cpp b/frontend/llvm/src/import/function.cpp
index a09ffb8..9c3d7f4 100644
--- a/frontend/llvm/src/import/function.cpp
+++ b/frontend/llvm/src/import/function.cpp
@@ -375,6 +375,13 @@ void FunctionImporter::translate_instruction(
} else if (llvm::isa< llvm::SwitchInst >(inst)) {
// The preprocessor should use the -lowerswitch pass
throw ImportError("llvm switch instructions are not supported");
+ } else if (inst->getOpcode() == llvm::Instruction::FNeg) {
+ auto* binary_inst = llvm::BinaryOperator::Create(llvm::BinaryOperator::FSub,
+ llvm::ConstantFP::getNegativeZero(inst->getOperand(0)->getType()),
+ inst->getOperand(0));
+ inst->replaceAllUsesWith(binary_inst);
+ binary_inst->setDebugLoc(inst->getDebugLoc());
+ this->translate_binary_operator(bb_translation, binary_inst);
} else {
std::ostringstream buf;
buf << "unsupported llvm instruction: " << inst->getOpcodeName() << " [1]";
@@ -2019,6 +2026,10 @@ FunctionImporter::TypeHint FunctionImporter::infer_type_hint_use(
return {}; // no hint
} else if (llvm::isa< llvm::ResumeInst >(user)) {
return {}; // no hint
+ } else if (llvm::isa< llvm::Instruction >(user)
+ && llvm::cast< llvm::Instruction >(user)->getOpcode() ==
+ llvm::Instruction::FNeg) {
+ return {}; // no hint
} else if (llvm::isa< llvm::SelectInst >(user)) {
// The preprocessor should use the -lower-select pass
throw ImportError("llvm select instructions are not supported"); |
I can replicate this in the |
From the LLVM Language reference manual
Using compiler explorer to test: FNeg just seems to toggle the sign bit in the floating point while preserving the rest of the bits. Not sure if it is important to conserve that behaviour. Would probably be ideal. |
I tried to implement this patch previously and found this error: "ikos: error: exited with signal SIGIOT". I'm on RHEL 8.9, I ran
|
Quick update to this, I was able to partially isolate the issue, I made two small c programs, one uses math.h and one does not. I have identical makefiles for both c programs. When I call ikos-scan on the makefile associated with the c program that uses math.h and subsequent functions like "tanf()" ikos-scan outputs the ikos SIGIOT error above. I'm assuming this is likely a linking issue in the makefile, or something like that, but still not sure. At least, I can confirm that the patch mentioned earlier does in fact work, assuming proper linkage in the makefile. Still running some tests however. |
It looks like this patch does not address all edge cases. It will get rid of the fneg error, but can cause issues with llvm later on. I had a similar issue in which a I was incorrect about my makefile being at fault. My apologies. |
Thanks for checking all of this!!! |
Unfortunately, there's no equivalent for integers that we can base this patch on, since the LLVM BC produced when an integer is negated is just subtracting from zero. For floats, however, LLVM does use a dedicated instruction When llvm compiles this to object code, is just does an As for modeling the behavior in ikos, I wonder if we'll need to introduce a new function that each abstract domain implements, since the actual meaning will depend on the type of the element, the abstract value, and the abstract domain (somewhere in |
@arthaud This issue has come up a few times, so I would not mind getting rid of it for the next release of IKOS. Let me know if you have any thoughts or initial pointers. |
The
For options 2 and 3, I'd recommend putting a warning message so that it isn't forgotten that the implementation is less than ideal. At present, I can't quite use iKos due to the Alas, I'm not smart enough to implement option 1 myself. Might be able to implement 2 & 3. |
Hi @PhilipBotha
In which cases is (-1.0)* different from changing the sign bit? I can only think of cases where the input is a form of Inf, a form of NaN or a form of zero. Are any of the current abstract domains able to capture Inf or NaN (positive or negative), or -0.0?
I'd love it if you could contribute the solution we opt for :) |
Greetings! @ivanperez-keera
I think
There is some work on Inf and NaNs, but more in the sense of detecting their occurrence. I think the
Ha! So would I. Though don't hold your breath. This stuff is a bit (i.e. a lot) above my usual work. |
A first approximation could be similar to this, except that instead of What is missing if we de-sugar it that way? |
Yes, that is what I was thinking of using as well. Should be a good starting point. |
Ok. Well, if you want to send a draft/preliminary PR, we can help and see what else would need to change. No pressure, and no rush, just let me know if there's something you want me to take a look at. It doesn't have to be perfect or even compile to start having a discussion on a PR :) |
Good day all. Created a draft PR. Location and running of test cases needs work. |
Hi,
I have got a strange behaviour of the ikos analyzer with the following C++ class of a simple vector.
I get the error:
However, if I change the line
into
everything works fine. I also got similar behaviours with other expressions using the binary "-" operator when self-defined classes are involved...
any help would be really appreciated.
Here comes an extract of my sample program vector.cpp
KR
Ingo
The text was updated successfully, but these errors were encountered: