[llvm-dev] Loop Strength Reduction and lost "nsw" flag
Jonas Paulsson via llvm-dev
llvm-dev at lists.llvm.org
Mon Sep 2 07:47:07 PDT 2019
Hi,
I was looking a bit at the handling of "nsw" flags, and found one case I
am not sure what to do about. Function @f4 in
test/CodeGen/SystemZ/loop-01.ll contains an add instruction which
decrements the IV with 1. This result is then compared to against zero
in the loop latch, but it also has another user.
I find that if i add "nsw" on that add instruction (as done in
attachement), LSR will create an identical instruction without the flag
for the other (non-IV) user. The problem is then that during isel, the
"nsw" flag is lost - it seems that only one add node without it is created.
Any ideas how this could be fixed?
Thanks,
Jonas
bin/llc -mtriple=s390x-linux-gnu -mcpu=z14 f4.ll
cat f4.ll
---
define void @f4(i32* %src, i32* %dest, i64* %dest2, i64 %count) {
entry:
br label %loop
loop: ; preds = %loop.next,
%entry
%left = phi i64 [ %count, %entry ], [ %next, %loop.next ]
store volatile i64 %left, i64* %dest2
%val = load volatile i32, i32* %src
%cmp = icmp eq i32 %val, 0
br i1 %cmp, label %loop.next, label %loop.store
loop.store: ; preds = %loop
%add = add i32 %val, 1
store volatile i32 %add, i32* %dest
br label %loop.next
loop.next: ; preds = %loop.store,
%loop
%next = add nsw i64 %left, -1
%ext = zext i32 %val to i64
%shl = shl i64 %ext, 32
%and = and i64 %next, 4294967295
%or = or i64 %shl, %and
store volatile i64 %or, i64* %dest2
%cont = icmp ne i64 %next, 0
br i1 %cont, label %loop, label %exit
exit: ; preds = %loop.next
ret void
}
---
*** IR Dump After Loop Strength Reduction ***
loop.next: ; preds = %loop.store,
%loop
%next = add nsw i64 %left, -1
%0 = add i64 %left, -1
%ext = zext i32 %val to i64
%shl = shl i64 %ext, 32
%and = and i64 %0, 4294967295
%or = or i64 %shl, %and
store volatile i64 %or, i64* %dest2
%cont = icmp ne i64 %next, 0
br i1 %cont, label %loop, label %exit
-------------- next part --------------
define void @f4(i32* %src, i32* %dest, i64* %dest2, i64 %count) {
entry:
br label %loop
loop: ; preds = %loop.next, %entry
%left = phi i64 [ %count, %entry ], [ %next, %loop.next ]
store volatile i64 %left, i64* %dest2
%val = load volatile i32, i32* %src
%cmp = icmp eq i32 %val, 0
br i1 %cmp, label %loop.next, label %loop.store
loop.store: ; preds = %loop
%add = add i32 %val, 1
store volatile i32 %add, i32* %dest
br label %loop.next
loop.next: ; preds = %loop.store, %loop
%next = add nsw i64 %left, -1
%ext = zext i32 %val to i64
%shl = shl i64 %ext, 32
%and = and i64 %next, 4294967295
%or = or i64 %shl, %and
store volatile i64 %or, i64* %dest2
%cont = icmp ne i64 %next, 0
br i1 %cont, label %loop, label %exit
exit: ; preds = %loop.next
ret void
}
More information about the llvm-dev
mailing list