[LLVMdev] poison and select

John Regehr regehr at cs.utah.edu
Tue Sep 9 06:50:16 PDT 2014


In the section about poison values, the LLVM language reference manual says:

   "Values other than phi nodes depend on their operands."

This implies that a select instruction's output can be poisoned by its 
not-selected argument value. If select were poisoned only by its 
selected argument, we would expect this fact to be mentioned 
specifically, as it is for phi.

Next I'll show how poisoning by the not-selected value can introduce a 
problem. Take this C program:

int printf(const char *, ...);
int foo(int x0) {
   int x3 = x0 >> 27;
   int x4 = x3 - 27;
   int x2 = x4 ? x4 : (1 >> x4);
   int x1 = x2 != 0;
   return x1;
}
int arg;
int main (void) {
   int x1 = foo(arg);
   printf("%x\n", x1);
   return 0;
}

This program has no UB and it should print "1'.

Clang at -O2 turns foo() into this:

define i32 @foo(i32 %x0) #0 {
entry:
   %shr = ashr i32 %x0, 27
   %sub = add nsw i32 %shr, -27
   %tobool = icmp ne i32 %sub, 0
   %shr1 = lshr i32 1, %sub
   %cond = select i1 %tobool, i32 %sub, i32 %shr1
   %cmp = icmp ne i32 %cond, 0
   %conv = zext i1 %cmp to i32
   ret i32 %conv
}

Although the translation is very straightforward, there's a problem: 
%shr1 is a poison value and although it is not selected, it propagates 
through the rest of the function and poisons the return value.

Obviously things are not going well if the source program contains no UB 
and the emitted code returns a poison value. Either there has been a 
miscompilation or else the LLVM documentation should be changed to make 
it clear that the select instruction only has a value dependence on the 
value that is selected.

The immediate problem here is that both Souper and Alive are happy for 
foo() to return 0 instead of 1. Souper actually does this optimization 
-- legally, of course, according to the reference manual.

Anyway this issue seemed tricky enough to bring up here instead of just 
filing a PR.

Thanks,

John



More information about the llvm-dev mailing list