Reputation: 7112
I have some simple C loop code, and I want to simplify it as much as possible. Here is the original C file:
#include <stdio.h>
char *foo(char *s)
{
while (*s == 'a' || *s == 'b')
{
s++;
}
return s;
}
int main(int argc, char **argv)
{
char *s1 = argv[1];
char *s2 = foo(s1);
return 0;
}
I've tried using opt
with the -licm
flag, which is supposed to:
remove as much code from the body of a loop as possible. It does this by either hoisting code into the preheader block
But when I look at the loop body, I see that lines 21 and 22 are really redundant, as %s.addr
did not change, and so lines 21 and 22 can be safely deleted, and instead of %tmp3
we can use %tmp1
from line 23
onward.
13 while.cond: ; preds = %while.body, %entry
14 %tmp = load i8*, i8** %s.addr, align 8
15 %tmp1 = load i8, i8* %tmp, align 1
16 %conv = sext i8 %tmp1 to i32
17 %cmp = icmp eq i32 %conv, 97
18 br i1 %cmp, label %lor.end, label %lor.rhs
19
20 lor.rhs: ; preds = %while.cond
21 %tmp2 = load i8*, i8** %s.addr, align 8
22 %tmp3 = load i8, i8* %tmp2, align 1
23 %conv2 = sext i8 %tmp3 to i32
24 %cmp3 = icmp eq i32 %conv2, 98
25 br label %lor.end
What am I missing? is there some other pass to achieve this goal?
Upvotes: 2
Views: 1713
Reputation: 3871
You are missing that %s.addr
is not invariant in the while loop. The loop invariant code motion optimization identifies expressions that do not change between iterations and try to lift them out of the loop. What you are looking for is something like common subexpression elimination. This optimization identifies repeated computation of the same subexpression and tries to remove all but one.
In my version of opt
this optimization is enabled by the -early-cse
switch.
Upvotes: 2