OrenIshShalom
OrenIshShalom

Reputation: 7102

LLVM IR temporaries use

I'm trying to find out whether LLVM IR temporaries can be used outside a loop in which they were defined. For that, I compiled the following simple C code:

while (*s == 'a')
{
    c = *s++;
}
*s = c;

and like I suspected, the final write outside the loop (*s = c) is done with another temporary (%tmp5) than the one read to inside the loop (%tmp4)

while.body:      ; preds = %while.cond
  %tmp3 = load i8*, i8** %s.addr, align 8
  %incdec.ptr = getelementptr inbounds i8, i8* %tmp3, i32 1
  store i8* %incdec.ptr, i8** %s.addr, align 8
  %tmp4 = load i8, i8* %tmp3, align 1
  store i8 %tmp4, i8* %c, align 1
  br label %while.cond

while.end:       ; preds = %while.cond
  %tmp5 = load i8, i8* %c, align 1
  %tmp6 = load i8*, i8** %s.addr, align 8
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  ; store i8 %tmp4, i8* %tmp6, align 1 ;
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  store i8 %tmp5, i8* %tmp6, align 1

When I edit the *.ll file and manually replace %tmp5 with %tmp4, then llvm-as is unhappy:

$ llvm-as modified.ll
Instruction does not dominate all uses!
%tmp4 = load i8, i8* %tmp3, align 1
store i8 %tmp4, i8* %tmp6, align 1

Is there any example where a temporary will be defined inside a loop and used outside of it? Thanks!

Upvotes: 0

Views: 500

Answers (2)

arnt
arnt

Reputation: 9675

LLVM doesn't really have temporaries, it uses SSA. That's short for static single assignment, and the key word here is single. Everything is a value and the value must always be assigned once.

Anything can use any value which necessarily has been assigned by the time it's used. "Dominates" means "provably comes before" in the error message you got, ie. LLVM sees that the input string is "b", the code will jump straight from while.cond to while.end, past while.body.

When you do use values from within loop after the end of the loop, things can get a little confusing. You may need to think hard and close the Slack and Facebook tabs. But LLVM doesn't mind.

Upvotes: 3

arrowd
arrowd

Reputation: 34391

The while.end basic block has only while.cond block as its predecessor. Thus, you can't access variables defined in while.body. It is like you want to access a variable defined in one branch from another:

if(...)
   int x = ...;
else
   print(x);

Instead, declare whatever variables you need in loop entry block and then use it from both while.body and while.end.

Upvotes: 0

Related Questions