Closed EmmetZC closed 8 years ago
I think you've stumped me in both counts!
On question 1: I don't see an obvious reason why getMetadata
wouldn't work in this case. Without digging deeper, I'm mystified.
2: I also don't exactly see why (a) that instruction would not be annotated, and (b) the pass would insert a check despite the missing annotation. Perhaps the annotation is getting lost at a later stage—can you inspect the IR before instrumentation?
Unfortunately, your guess for question 2 seems wrong.
To test this, I compile the test/codegen.c
manually in 2 steps:
NullChecks
pass, and both LLVM IR and disassembled result of LLVM BC show that instruction is not annotated.NullChecks
pass to that LLVM BC using opt
and the pass finds the correct instruction to addCheck()
.
This test implies, perhaps the annotation info gets lost while printing LLVM IR. I need to check how instruction is dumped.Very strange indeed! I've really never encountered a problem where the in-memory IR had data that was silently lost when dumping it to text or bitcode on disk.
Hey, I guess I've found out the "culprit" for this mismatch. As you know, I'm new to this project so all my tests are based on your example, nullness. Check out NullChecks.cpp:
Value *Ptr = nullptr;
if (auto *LI = dyn_cast<LoadInst>(&I)) {
Ptr = LI->getPointerOperand(); // line 34
} else if (auto *SI = dyn_cast<StoreInst>(&I)) {
Ptr = SI->getPointerOperand(); // line 36
}
...
...
if (Ptr) {
if (AI.hasAnnotation(Ptr, "nullable")) { // line 42
addCheck(*Ptr, I);
modified = true;
}
}
From line 34/36 we can see that Ptr
stores the first operand of StoreInst
/LoadInst
, instead of the Inst itself, and obviously the operand is not annotated when we declare it as low level annotated in Question 1.
So now we have (a) the LLVM IR metadata shows the annotation info of the Instruction, while (b) the hasAnnotation()
call checks the annotation info of the operand of the Instruction.
This could explain Question 2, too.
Aha, of course—thanks for sorting out my own thinking for me. :flushed: The point, of course, is to prevent loads through null pointers, not to prevent loads that produce null results.
Question One:
Source:
IR:
From IR we can see, Inst
store i32 4, i32* %0, align 4, !tyann !1
has metadata tyann, but when I call functionhasAnnotation()
for this Inst,the value of
MD
isnullptr
, which means it cannot find metadata for that Inst, why does the annotation info get lost?Besides, I'm a little bit confused about the metadata
i8 0
in!1 = !{!"nullable", i8 0}
, I thoughti8 0
should indicate the top level of Annotation, andi8 1
should mean the lower level, while I find out that the reality seems to be just the reverse.Question Two:
In Nullable Codegen.cpp test, if we generate LL IR for test/codegen.c, we get this:
In Pass
NullChecks
, we know that this pass willaddCheck()
before annotated Store/Load inst. Obviously the pass adds check before%1 = load i32, i32* %0, align 4
, which is not shown annoated. Does this means the annotation info is not properly shown is LL IR?Is there anything misunderstood by me?