Files
archived-llvm/test/Transforms/LoopVectorize/pr39160.ll
Max Kazantsev eb3fd4c932 [LV] Do not create SCEVs on broken IR in emitTransformedIndex. PR39160
At the point when we perform `emitTransformedIndex`, we have a broken IR (in
particular, we have Phis for which not every incoming value is properly set). On
such IR, it is illegal to create SCEV expressions, because their internal
simplification process may try to prove some predicates and break when it
stumbles across some broken IR.

The only purpose of using SCEV in this particular place is attempt to simplify
the generated code slightly. It seems that the result isn't worth it, because
some trivial cases (like addition of zero and multiplication by 1) can be
handled separately if needed, but more generally InstCombine is able to achieve
the goals we want to achieve by using SCEV.

This patch fixes a functional crash described in PR39160, and as side-effect it
also generates a bit smarter code in some simple cases. It also may cause some
optimality loss (i.e. we will now generate `mul` by power of `2` instead of
shift etc), but there is nothing what InstCombine could not handle later. In
case of dire need, we can support more trivial cases just in place.

Note that this patch only fixes one particular case of the general problem that
LV misuses SCEV, attempting to create SCEVs or prove predicates on invalid IR.
The general solution, however, seems complex enough.

Differential Revision: https://reviews.llvm.org/D52881
Reviewed By: fhahn, hsaito


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@343954 91177308-0d34-0410-b5e6-96231b3b80d8
2018-10-08 05:46:29 +00:00

99 lines
3.0 KiB
LLVM

; RUN: opt -loop-vectorize -S < %s 2>&1 | FileCheck %s
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128-ni:1"
target triple = "x86_64-unknown-linux-gnu"
; Make sure that we can compile the test without crash.
define void @barney() {
; CHECK-LABEL: @barney(
; CHECK: middle.block:
bb:
br label %bb2
bb2: ; preds = %bb2, %bb
%tmp4 = icmp slt i32 undef, 0
br i1 %tmp4, label %bb2, label %bb5
bb5: ; preds = %bb2
br label %bb19
bb18: ; preds = %bb33
ret void
bb19: ; preds = %bb36, %bb5
%tmp21 = phi i64 [ undef, %bb36 ], [ 2, %bb5 ]
%tmp22 = phi i32 [ %tmp65, %bb36 ], [ undef, %bb5 ]
br label %bb50
bb33: ; preds = %bb62
br i1 undef, label %bb18, label %bb36
bb36: ; preds = %bb33
br label %bb19
bb46: ; preds = %bb50
br i1 undef, label %bb48, label %bb59
bb48: ; preds = %bb46
%tmp49 = add i32 %tmp52, 14
ret void
bb50: ; preds = %bb50, %bb19
%tmp52 = phi i32 [ %tmp55, %bb50 ], [ %tmp22, %bb19 ]
%tmp53 = phi i64 [ %tmp56, %bb50 ], [ 1, %bb19 ]
%tmp54 = add i32 %tmp52, 12
%tmp55 = add i32 %tmp52, 13
%tmp56 = add nuw nsw i64 %tmp53, 1
%tmp58 = icmp ult i64 %tmp53, undef
br i1 %tmp58, label %bb50, label %bb46
bb59: ; preds = %bb46
br label %bb62
bb62: ; preds = %bb68, %bb59
%tmp63 = phi i32 [ %tmp65, %bb68 ], [ %tmp55, %bb59 ]
%tmp64 = phi i64 [ %tmp66, %bb68 ], [ %tmp56, %bb59 ]
%tmp65 = add i32 %tmp63, 13
%tmp66 = add nuw nsw i64 %tmp64, 1
%tmp67 = icmp ult i64 %tmp66, %tmp21
br i1 %tmp67, label %bb68, label %bb33
bb68: ; preds = %bb62
br label %bb62
}
define i32 @foo(i32 addrspace(1)* %p) {
; CHECK-LABEL: foo
; CHECK: middle.block:
entry:
br label %outer
outer: ; preds = %outer_latch, %entry
%iv = phi i64 [ 2, %entry ], [ %iv.next, %outer_latch ]
br label %inner
inner: ; preds = %inner, %outer
%0 = phi i32 [ %2, %inner ], [ 0, %outer ]
%a = phi i32 [ %3, %inner ], [ 1, %outer ]
%b = phi i32 [ %1, %inner ], [ 6, %outer ]
%1 = add i32 %b, 2
%2 = or i32 %0, %b
%3 = add nuw nsw i32 %a, 1
%4 = zext i32 %3 to i64
%5 = icmp ugt i64 %iv, %4
br i1 %5, label %inner, label %outer_latch
outer_latch: ; preds = %inner
store atomic i32 %2, i32 addrspace(1)* %p unordered, align 4
%iv.next = add nuw nsw i64 %iv, 1
%6 = icmp ugt i64 %iv, 63
br i1 %6, label %exit, label %outer
exit: ; preds = %outer_latch
ret i32 0
}