(original) (raw)

Thanks for explaining. I think I have get the meaning of this optimzation.And I also find this pattern changed to the "not eq" by "induction variable canonicalize".
Thank all again.

\~Rock



At 2021-08-11 04:24:15, "Craig Topper" wrote:

There are a couple things going on.

InstCombine prefers to canonicalize ule/uge/sle/sge compares with constants to ult/ugt/slt/sgt by adjusting the constant. This allows transforms in InstCombine and other passes to not need to check for two forms of equivalent operations. The backends sometimes have to reverse this to get better code.

There's a second transform that's turning the signed compare into an unsigned compare because the loop counter starts at zero and counts up to a positive number so the value will never be negative. Unsigned compares are easier for some optimizations to reason about so the compiler tries to make unsigned compares when it can.

\~Craig


On Tue, Aug 10, 2021 at 4:54 AM zbh via llvm-dev <llvm-dev@lists.llvm.org> wrote:


I understand it's equivalent.But I don't know the benefit. And I don't understand why this statement changed to
not eq in the last either.
������
%exitcond = icmp ne i32 %inc, 129

������


Thanks
Rock



At 2021-08-10 19:23:59, "Dimitry Andric" <dimitry@andric.com> wrote: \>On 10 Aug 2021, at 13:16, zbh via llvm-dev <llvm-dev@lists.llvm.org> wrote: \>> \>> I find the value 128 chaned to 129\. So I want to know what's the purpose to changed the form?Can you give some example? \> \>(icmp reference: <https://llvm.org/docs/LangRef.html#id303f>) \> \>Before, it uses "icmp sle" which is "signed <=", so effectively "<= 128". \> \>After, it uses "icmp ult" which is "unsigned <", so effectively "< 129". \> \>These are equivalent. \>
>-Dimitry

-------------------------------------------------------------

Hi all:

I write C code like this:

\`\`\`
for (int i =0; i< 128; i++) {
printf("hello");
}
\`\`\`
I use this command to compile the above code.
\`\`
clang -Xclang -disable-O0-optnone -O0 -emit-llvm -S main.c
opt -O2 --print-after-all main.ll -S -o main.mid.ll
\`\`
And I find the LLVM IR have this changed after instCombine optimization.

\`\`\`
\*\*\* IR Dump After Dead Argument Elimination \*\*\*
; Function Attrs: noinline nounwind uwtable
define dso\_local i32 @main(i32 %argc, i8\*\* %argv) local\_unnamed\_addr #0 {
entry:
br label %for.cond

for.cond: ; preds = %for.body, %entry
%i.0 = phi i32 \[ 0, %entry \], \[ %inc, %for.body \]
%cmp = icmp sle i32 %i.0, 128
br i1 %cmp, label %for.body, label %for.end

for.body: ; preds = %for.cond
%call = call i32 (i8\*, ...) @printf(i8\* getelementptr inbounds (\[6 x i8\], \[6 x i8\]\* @.str, i64 0, i64 0))
%inc = add nsw i32 %i.0, 1
br label %for.cond

for.end: ; preds = %for.cond
ret i32 0
}

\*\*\* IR Dump After Combine redundant instructions \*\*\*
; Function Attrs: noinline nounwind uwtable
define dso\_local i32 @main(i32 %argc, i8\*\* %argv) local\_unnamed\_addr #0 {
entry:
br label %for.cond

for.cond: ; preds = %for.body, %entry
%i.0 = phi i32 \[ 0, %entry \], \[ %inc, %for.body \]
%cmp = icmp ult i32 %i.0, 129
br i1 %cmp, label %for.body, label %for.end

for.body: ; preds = %for.cond
%call = call i32 (i8\*, ...) @printf(i8\* nonnull dereferenceable(1) getelementptr inbounds (\[6 x i8\], \[6 x i8\]\* @.str, i64 0, i64 0))
%inc = add nuw nsw i32 %i.0, 1
br label %for.cond

for.end: ; preds = %for.cond
ret i32 0
}

������
I find the value 128 chaned to 129\. So I want to know what's the purpose to changed the form?Can you give some example?

Thanks
Rock



\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_
LLVM Developers mailing list
llvm-dev@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev