Nikita Popov efe4e7a026
[SCEV] Fix incorrect nsw inference for multiply of addrec (#66500)
SCEV currently preserves the nsw flag when performing an nsw multiply of
an nsw addrec. While this is legal for nuw, this is not generally the
case for nsw.

This is because nsw mul does not distribute over nsw add:
https://alive2.llvm.org/ce/z/mergCt

Instead, we need either both nuw and nsw to be set
(https://alive2.llvm.org/ce/z/7wpgGc) or explicitly prove that the
distributed multiplications are also nsw
(https://alive2.llvm.org/ce/z/wef9su).

Fixes https://github.com/llvm/llvm-project/issues/66066.
2023-09-18 08:23:10 +02:00

35 lines
1009 B
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 3
; RUN: opt -S -passes=indvars < %s | FileCheck %s
; The comparison should not get folded to false.
define void @test() {
; CHECK-LABEL: define void @test() {
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[IV:%.*]] = phi i8 [ 1, [[ENTRY:%.*]] ], [ [[IV_DEC:%.*]], [[LOOP]] ]
; CHECK-NEXT: [[IV_DEC]] = add nsw i8 [[IV]], -1
; CHECK-NEXT: [[SHL:%.*]] = shl i8 [[IV]], 7
; CHECK-NEXT: call void @use(i8 [[SHL]])
; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[SHL]], 0
; CHECK-NEXT: br i1 [[CMP1]], label [[EXIT:%.*]], label [[LOOP]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
entry:
br label %loop
loop:
%iv = phi i8 [ 1, %entry ], [ %iv.dec, %loop ]
%iv.dec = add i8 %iv, -1
%shl = shl i8 %iv, 7
call void @use(i8 %shl)
%cmp1 = icmp eq i8 %shl, 0
br i1 %cmp1, label %exit, label %loop
exit:
ret void
}
declare void @use(i32)