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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With