1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-24 11:42:57 +01:00
llvm-mirror/test/Analysis/ScalarEvolution/truncate.ll
Max Kazantsev 78e21c99d5 [SCEV] Fix buggy behavior in getAddExpr with truncs
SCEV tries to constant-fold arguments of trunc operands in SCEVAddExpr, and when it does
that, it passes wrong flags into the recursion. It is only valid to pass flags that are proved for
narrow type into a computation in wider type if we can prove that trunc instruction doesn't
actually change the value. If it did lose some meaningful bits, we may end up proving wrong
no-wrap flags for sum of arguments of trunc.

In the provided test we end up with `nuw` where it shouldn't be because of this bug.

The solution is to conservatively pass `SCEV::FlagAnyWrap` which is always a valid thing to do.

Reviewed By: sanjoy
Differential Revision: https://reviews.llvm.org/D49471

llvm-svn: 337435
2018-07-19 01:46:21 +00:00

110 lines
3.5 KiB
LLVM

; RUN: opt < %s -analyze -scalar-evolution 2>&1 | FileCheck %s
; RUN: opt < %s -passes='print<scalar-evolution>' -S 2>&1 | FileCheck %s
; Regression test for assert ScalarEvolution::getTruncateExpr.
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128-ni:1"
target triple = "x86_64-unknown-linux-gnu"
define void @snork(i8* %arg, i8 %arg1, i64 %arg2) {
; CHECK-LABEL: Classifying expressions for: @snork
bb:
br label %bb12
bb3: ; preds = %bb34
br i1 true, label %bb4, label %bb12
bb4: ; preds = %bb3
br label %bb6
bb5: ; preds = %bb6
ret void
bb6: ; preds = %bb6, %bb4
%tmp = phi i64 [ %tmp28, %bb4 ], [ %tmp10, %bb6 ]
%tmp7 = phi i32 [ 3, %bb4 ], [ %tmp11, %bb6 ]
%tmp8 = trunc i64 %tmp to i32
%tmp9 = sdiv i32 %tmp8, %tmp7
%tmp10 = add i64 %tmp, -1
%tmp11 = add i32 %tmp9, %tmp7
br i1 true, label %bb5, label %bb6
bb12: ; preds = %bb3, %bb
br label %bb13
bb13: ; preds = %bb34, %bb12
%tmp14 = phi i64 [ %arg2, %bb12 ], [ %tmp28, %bb34 ]
%tmp15 = phi i8 [ %arg1, %bb12 ], [ %tmp26, %bb34 ]
%tmp16 = phi i32 [ 1, %bb12 ], [ %tmp35, %bb34 ]
%tmp17 = add i8 %tmp15, -1
%tmp18 = sext i8 %tmp17 to i64
%tmp19 = sub i64 1, %tmp14
%tmp20 = add i64 %tmp19, %tmp18
%tmp21 = trunc i64 %tmp20 to i32
%tmp22 = icmp eq i32 %tmp21, 0
br i1 %tmp22, label %bb32, label %bb23
bb23: ; preds = %bb13
br i1 true, label %bb25, label %bb24
bb24: ; preds = %bb23
br label %bb25
bb25: ; preds = %bb24, %bb23
%tmp26 = add i8 %tmp15, -2
%tmp27 = sext i8 %tmp26 to i64
%tmp28 = sub i64 %tmp27, %tmp20
%tmp29 = trunc i64 %tmp28 to i32
%tmp30 = icmp eq i32 %tmp29, 0
br i1 %tmp30, label %bb31, label %bb34
bb31: ; preds = %bb25
br label %bb33
bb32: ; preds = %bb13
br label %bb33
bb33: ; preds = %bb32, %bb31
unreachable
bb34: ; preds = %bb25
%tmp35 = add nuw nsw i32 %tmp16, 2
%tmp36 = icmp ugt i32 %tmp16, 52
br i1 %tmp36, label %bb3, label %bb13
}
; Make sure that no nuw flag is assigned to %tmp27, otherwise we will have a
; poisoned value.
define void @no_nuw(i64 %param) {
; CHECK-LABEL: Classifying expressions for: @no_nuw
; CHECK: %tmp27 = add i64 %tmp20, -1
; CHECK-NOT: (-1 + %tmp20)<nuw>
; CHECK-NEXT: --> (-1 + %tmp20) U:
bb:
%shift = shl i64 %param, 58
br label %bb18
bb18: ; preds = %bb36, %bb
%tmp20 = phi i64 [ %shift, %bb ], [ 0, %bb36 ]
%tmp21 = phi i64 [ 0, %bb ], [ %tmp24, %bb36 ]
%tmp22 = phi i32 [ -6, %bb ], [ %tmp46, %bb36 ]
%tmp25 = add i32 %tmp22, 1
%tmp26 = sext i32 %tmp25 to i64
%tmp27 = add i64 %tmp20, -1
%tmp28 = mul i64 %tmp27, %tmp26
%tmp29 = icmp ult i64 %tmp21, 1048576
br i1 %tmp29, label %bb36, label %bb30
bb30: ; preds = %bb18
ret void
bb36: ; preds = %bb18
%tmp24 = add nuw i64 %tmp21, 1
%tmp45 = trunc i64 %tmp28 to i32
%tmp46 = sub i32 %tmp22, %tmp45
br label %bb18
}