The rules for inbounds are a bit subtle, so I'd appreciate another set of eyes. Please review the usage of getUnderlyingObject and getObjectSize carefully; my intent is to factor this out for use in inferring inbounds from the optimizer in the near future, so having it be correct is important.
Diff Detail
Event Timeline
Three comments, though I need to look at it when I'm actually awake.
lib/Transforms/Instrumentation/PoisonChecking.cpp | ||
---|---|---|
208 | GlobalVariable is another easy one, and isMallocLikeFn. | |
213 | You use GetUnderlyingObject to get a base which is used in checks later but you look at the indices of this GEP only. I think that is not OK, e.g., if you have two geps, one all positive indices and the one before negative ones. | |
234 |
You might need to adjust SizeInBytes by one, though it's late. |
lib/Transforms/Instrumentation/PoisonChecking.cpp | ||
---|---|---|
237 | Doing these pointer comparisons isn't legal, and LLVM can fold "out_of_bonds_ptr >= valid_ptr" to poison. |
lib/Transforms/Instrumentation/PoisonChecking.cpp | ||
---|---|---|
208 | GlobalVariable was a bit unclear to me since I haven't studied the rules for conflicting definitions in different modules. isMallocLikeFn is definitely valid, but requires TLI (which this pass currently doesn't have). I was planning on doing that in a follow up. | |
213 | Good catch! Yeah, definitely needs fixed. | |
234 | This should be handled by using UGT not UGE right? | |
237 | Can you cite where in the LangRef it says this? I think you're quite possibly right, but a) I didn't find the wording with a quick search and b) the output seems to survive the optimizer in simple cases which is maybe a hint we don't implement it that way? |
lib/Transforms/Instrumentation/PoisonChecking.cpp | ||
---|---|---|
208 | That is fine with me. | |
217 | While I now thing this is correct, we might want to make it less restrictive using existing functionality to accumulate and strip pointer stuff, e.g., along the lines of: const Value *Base = GEP->stripAndAccumulateConstantOffsets(const DataLayout &DL, APInt &Offset, bool AllowNonInbounds); IsNonNegativeOffset = (Base == Obj) && Offset >= 0; | |
234 | Yes. An offset of one in the right direction, compared to what you have now, is required. Either change is fine. | |
237 | I would have thought the reasoning described by @nlopes is only valid for inbounds GEPs. "Normal" GEPs should be allowed to go out-of-bounds without producing poison (IMHO). |
lib/Transforms/Instrumentation/PoisonChecking.cpp | ||
---|---|---|
234 | Is this case covered as well? a = alloca i32 // 4 bytes p1 = gep a, -1 p2 = gep inbounds p1, 2 p2 is poison because p1 is not in-bounds pointer. | |
300 | A silly question: where is the poison-ness of operands of GEP checked at? |
lib/Transforms/Instrumentation/PoisonChecking.cpp | ||
---|---|---|
300 | I think this is relates to your other question: nowhere yet (I think) Though, this is a really good point. The check for an inbound gep could include one to ensure a valid base pointer. How to do that is tricky though. If the base allocation is known, one can substract the base pointer from the base allocation and do diff >= 0 && diff <= length. If the base allocation is not known, we would need to track more information throughout the program. There are different ways to do this but I guess the first case should be covered next. |
Just indicating in the review state that the next action item here is mine. Probably not going to get back to this for a bit, so want that to be clear to reviewers.
Address comments in advance of patch refresh.
lib/Transforms/Instrumentation/PoisonChecking.cpp | ||
---|---|---|
217 | Your proposal is less powerful than the existing code as it's restricted to constants where the current code is didn't. Did you have a particular missed case in mind? | |
234 | Hadn't been handled in the original patch, see forthcoming refresh. | |
300 | I think nlopes question was actually about one of the operands being directly poison. Which is handled via the propagatesFullPoison code. |
lib/Transforms/Instrumentation/PoisonChecking.cpp | ||
---|---|---|
217 | I think, though I don't quite remember, I wanted to simplify the code. It was only a suggestion anyway. |
GlobalVariable is another easy one, and isMallocLikeFn.