Files
llvm/test/Transforms/LoopVectorize/if-conversion.ll
T
Sanjay Patel 3b56d63bde [LoopVectorize] auto-generate complete checks; NFC
I'm looking at a cmp transform in InstCombine that would affect these tests,
but it's hard to know if it makes things better or worse without seeing the
full IR. OTOH, maybe these tests shouldn't be running a bunch of transform
passes in the first place?



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@307475 91177308-0d34-0410-b5e6-96231b3b80d8
2017-07-08 16:10:42 +00:00

346 lines
17 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -loop-vectorize -force-vector-interleave=1 -force-vector-width=4 -enable-if-conversion -dce -instcombine -S | FileCheck %s
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
; This is the loop in this example:
;
;int function0(int *a, int *b, int start, int end) {
;
; for (int i=start; i<end; ++i) {
; unsigned k = a[i];
;
; if (a[i] > b[i]) <------ notice the IF inside the loop.
; k = k * 5 + 3;
;
; a[i] = k; <---- K is a phi node that becomes vector-select.
; }
;}
define i32 @function0(i32* nocapture %a, i32* nocapture %b, i32 %start, i32 %end) nounwind uwtable ssp {
; CHECK-LABEL: @function0(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CMP16:%.*]] = icmp slt i32 [[START:%.*]], [[END:%.*]]
; CHECK-NEXT: br i1 [[CMP16]], label [[FOR_BODY_LR_PH:%.*]], label [[FOR_END:%.*]]
; CHECK: for.body.lr.ph:
; CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[START]] to i64
; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[END]], -1
; CHECK-NEXT: [[TMP2:%.*]] = sub i32 [[TMP1]], [[START]]
; CHECK-NEXT: [[TMP3:%.*]] = zext i32 [[TMP2]] to i64
; CHECK-NEXT: [[TMP4:%.*]] = add nuw nsw i64 [[TMP3]], 1
; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[TMP4]], 4
; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[MIN_ITERS_CHECKED:%.*]]
; CHECK: min.iters.checked:
; CHECK-NEXT: [[TMP5:%.*]] = add i32 [[TMP2]], 1
; CHECK-NEXT: [[TMP6:%.*]] = and i32 [[TMP5]], 3
; CHECK-NEXT: [[N_MOD_VF:%.*]] = zext i32 [[TMP6]] to i64
; CHECK-NEXT: [[N_VEC:%.*]] = sub nsw i64 [[TMP4]], [[N_MOD_VF]]
; CHECK-NEXT: [[CMP_ZERO:%.*]] = icmp eq i64 [[N_VEC]], 0
; CHECK-NEXT: br i1 [[CMP_ZERO]], label [[SCALAR_PH]], label [[VECTOR_MEMCHECK:%.*]]
; CHECK: vector.memcheck:
; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr i32, i32* [[A:%.*]], i64 [[TMP0]]
; CHECK-NEXT: [[TMP7:%.*]] = add i32 [[END]], -1
; CHECK-NEXT: [[TMP8:%.*]] = sub i32 [[TMP7]], [[START]]
; CHECK-NEXT: [[TMP9:%.*]] = zext i32 [[TMP8]] to i64
; CHECK-NEXT: [[TMP10:%.*]] = add nsw i64 [[TMP0]], [[TMP9]]
; CHECK-NEXT: [[TMP11:%.*]] = add nsw i64 [[TMP10]], 1
; CHECK-NEXT: [[SCEVGEP2:%.*]] = getelementptr i32, i32* [[A]], i64 [[TMP11]]
; CHECK-NEXT: [[SCEVGEP4:%.*]] = getelementptr i32, i32* [[B:%.*]], i64 [[TMP0]]
; CHECK-NEXT: [[SCEVGEP6:%.*]] = getelementptr i32, i32* [[B]], i64 [[TMP11]]
; CHECK-NEXT: [[BOUND0:%.*]] = icmp ult i32* [[SCEVGEP]], [[SCEVGEP6]]
; CHECK-NEXT: [[BOUND1:%.*]] = icmp ult i32* [[SCEVGEP4]], [[SCEVGEP2]]
; CHECK-NEXT: [[MEMCHECK_CONFLICT:%.*]] = and i1 [[BOUND0]], [[BOUND1]]
; CHECK-NEXT: [[IND_END:%.*]] = add nsw i64 [[N_VEC]], [[TMP0]]
; CHECK-NEXT: br i1 [[MEMCHECK_CONFLICT]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
; CHECK: vector.ph:
; CHECK-NEXT: br label [[VECTOR_BODY:%.*]]
; CHECK: vector.body:
; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
; CHECK-NEXT: [[TMP12:%.*]] = add i64 [[INDEX]], [[TMP0]]
; CHECK-NEXT: [[TMP13:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[TMP12]]
; CHECK-NEXT: [[TMP14:%.*]] = bitcast i32* [[TMP13]] to <4 x i32>*
; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x i32>, <4 x i32>* [[TMP14]], align 4, !alias.scope !0, !noalias !3
; CHECK-NEXT: [[TMP15:%.*]] = getelementptr inbounds i32, i32* [[B]], i64 [[TMP12]]
; CHECK-NEXT: [[TMP16:%.*]] = bitcast i32* [[TMP15]] to <4 x i32>*
; CHECK-NEXT: [[WIDE_LOAD8:%.*]] = load <4 x i32>, <4 x i32>* [[TMP16]], align 4, !alias.scope !3
; CHECK-NEXT: [[TMP17:%.*]] = mul <4 x i32> [[WIDE_LOAD]], <i32 5, i32 5, i32 5, i32 5>
; CHECK-NEXT: [[TMP18:%.*]] = add <4 x i32> [[TMP17]], <i32 3, i32 3, i32 3, i32 3>
; CHECK-NEXT: [[TMP19:%.*]] = icmp sgt <4 x i32> [[WIDE_LOAD]], [[WIDE_LOAD8]]
; CHECK-NEXT: [[PREDPHI:%.*]] = select <4 x i1> [[TMP19]], <4 x i32> [[TMP18]], <4 x i32> [[WIDE_LOAD]]
; CHECK-NEXT: [[TMP20:%.*]] = bitcast i32* [[TMP13]] to <4 x i32>*
; CHECK-NEXT: store <4 x i32> [[PREDPHI]], <4 x i32>* [[TMP20]], align 4, !alias.scope !0, !noalias !3
; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 4
; CHECK-NEXT: [[TMP21:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
; CHECK-NEXT: br i1 [[TMP21]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop !5
; CHECK: middle.block:
; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i32 [[TMP6]], 0
; CHECK-NEXT: br i1 [[CMP_N]], label [[FOR_END_LOOPEXIT:%.*]], label [[SCALAR_PH]]
; CHECK: scalar.ph:
; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[IND_END]], [[MIDDLE_BLOCK]] ], [ [[TMP0]], [[FOR_BODY_LR_PH]] ], [ [[TMP0]], [[MIN_ITERS_CHECKED]] ], [ [[TMP0]], [[VECTOR_MEMCHECK]] ]
; CHECK-NEXT: br label [[FOR_BODY:%.*]]
; CHECK: for.body:
; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[INDVARS_IV_NEXT:%.*]], [[IF_END:%.*]] ]
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV]]
; CHECK-NEXT: [[TMP22:%.*]] = load i32, i32* [[ARRAYIDX]], align 4
; CHECK-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds i32, i32* [[B]], i64 [[INDVARS_IV]]
; CHECK-NEXT: [[TMP23:%.*]] = load i32, i32* [[ARRAYIDX4]], align 4
; CHECK-NEXT: [[CMP5:%.*]] = icmp sgt i32 [[TMP22]], [[TMP23]]
; CHECK-NEXT: br i1 [[CMP5]], label [[IF_THEN:%.*]], label [[IF_END]]
; CHECK: if.then:
; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[TMP22]], 5
; CHECK-NEXT: [[ADD:%.*]] = add i32 [[MUL]], 3
; CHECK-NEXT: br label [[IF_END]]
; CHECK: if.end:
; CHECK-NEXT: [[K_0:%.*]] = phi i32 [ [[ADD]], [[IF_THEN]] ], [ [[TMP22]], [[FOR_BODY]] ]
; CHECK-NEXT: store i32 [[K_0]], i32* [[ARRAYIDX]], align 4
; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add i64 [[INDVARS_IV]], 1
; CHECK-NEXT: [[TMP24:%.*]] = trunc i64 [[INDVARS_IV_NEXT]] to i32
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP24]], [[END]]
; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END_LOOPEXIT]], !llvm.loop !8
; CHECK: for.end.loopexit:
; CHECK-NEXT: br label [[FOR_END]]
; CHECK: for.end:
; CHECK-NEXT: ret i32 undef
;
entry:
%cmp16 = icmp slt i32 %start, %end
br i1 %cmp16, label %for.body.lr.ph, label %for.end
for.body.lr.ph:
%0 = sext i32 %start to i64
br label %for.body
for.body:
%indvars.iv = phi i64 [ %0, %for.body.lr.ph ], [ %indvars.iv.next, %if.end ]
%arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
%1 = load i32, i32* %arrayidx, align 4
%arrayidx4 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
%2 = load i32, i32* %arrayidx4, align 4
%cmp5 = icmp sgt i32 %1, %2
br i1 %cmp5, label %if.then, label %if.end
if.then:
%mul = mul i32 %1, 5
%add = add i32 %mul, 3
br label %if.end
if.end:
%k.0 = phi i32 [ %add, %if.then ], [ %1, %for.body ]
store i32 %k.0, i32* %arrayidx, align 4
%indvars.iv.next = add i64 %indvars.iv, 1
%3 = trunc i64 %indvars.iv.next to i32
%cmp = icmp slt i32 %3, %end
br i1 %cmp, label %for.body, label %for.end
for.end:
ret i32 undef
}
; int func(int *A, int n) {
; unsigned sum = 0;
; for (int i = 0; i < n; ++i)
; if (A[i] > 30)
; sum += A[i] + 2;
;
; return sum;
; }
define i32 @reduction_func(i32* nocapture %A, i32 %n) nounwind uwtable readonly ssp {
; CHECK-LABEL: @reduction_func(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CMP10:%.*]] = icmp sgt i32 [[N:%.*]], 0
; CHECK-NEXT: br i1 [[CMP10]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_END:%.*]]
; CHECK: for.body.preheader:
; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[N]], -1
; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[TMP0]] to i64
; CHECK-NEXT: [[TMP2:%.*]] = add nuw nsw i64 [[TMP1]], 1
; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[TMP2]], 4
; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[MIN_ITERS_CHECKED:%.*]]
; CHECK: min.iters.checked:
; CHECK-NEXT: [[TMP3:%.*]] = and i32 [[N]], 3
; CHECK-NEXT: [[N_MOD_VF:%.*]] = zext i32 [[TMP3]] to i64
; CHECK-NEXT: [[N_VEC:%.*]] = sub nsw i64 [[TMP2]], [[N_MOD_VF]]
; CHECK-NEXT: [[CMP_ZERO:%.*]] = icmp eq i64 [[N_VEC]], 0
; CHECK-NEXT: br i1 [[CMP_ZERO]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
; CHECK: vector.ph:
; CHECK-NEXT: br label [[VECTOR_BODY:%.*]]
; CHECK: vector.body:
; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
; CHECK-NEXT: [[VEC_PHI:%.*]] = phi <4 x i32> [ zeroinitializer, [[VECTOR_PH]] ], [ [[PREDPHI:%.*]], [[VECTOR_BODY]] ]
; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i64 [[INDEX]]
; CHECK-NEXT: [[TMP5:%.*]] = bitcast i32* [[TMP4]] to <4 x i32>*
; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x i32>, <4 x i32>* [[TMP5]], align 4
; CHECK-NEXT: [[TMP6:%.*]] = add <4 x i32> [[VEC_PHI]], <i32 2, i32 2, i32 2, i32 2>
; CHECK-NEXT: [[TMP7:%.*]] = add <4 x i32> [[TMP6]], [[WIDE_LOAD]]
; CHECK-NEXT: [[TMP8:%.*]] = icmp slt <4 x i32> [[WIDE_LOAD]], <i32 31, i32 31, i32 31, i32 31>
; CHECK-NEXT: [[PREDPHI]] = select <4 x i1> [[TMP8]], <4 x i32> [[VEC_PHI]], <4 x i32> [[TMP7]]
; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 4
; CHECK-NEXT: [[TMP9:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
; CHECK-NEXT: br i1 [[TMP9]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop !9
; CHECK: middle.block:
; CHECK-NEXT: [[RDX_SHUF:%.*]] = shufflevector <4 x i32> [[PREDPHI]], <4 x i32> undef, <4 x i32> <i32 2, i32 3, i32 undef, i32 undef>
; CHECK-NEXT: [[BIN_RDX:%.*]] = add <4 x i32> [[PREDPHI]], [[RDX_SHUF]]
; CHECK-NEXT: [[RDX_SHUF1:%.*]] = shufflevector <4 x i32> [[BIN_RDX]], <4 x i32> undef, <4 x i32> <i32 1, i32 undef, i32 undef, i32 undef>
; CHECK-NEXT: [[BIN_RDX2:%.*]] = add <4 x i32> [[BIN_RDX]], [[RDX_SHUF1]]
; CHECK-NEXT: [[TMP10:%.*]] = extractelement <4 x i32> [[BIN_RDX2]], i32 0
; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i32 [[TMP3]], 0
; CHECK-NEXT: br i1 [[CMP_N]], label [[FOR_END_LOOPEXIT:%.*]], label [[SCALAR_PH]]
; CHECK: scalar.ph:
; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[FOR_BODY_PREHEADER]] ], [ 0, [[MIN_ITERS_CHECKED]] ]
; CHECK-NEXT: [[BC_MERGE_RDX:%.*]] = phi i32 [ [[TMP10]], [[MIDDLE_BLOCK]] ], [ 0, [[FOR_BODY_PREHEADER]] ], [ 0, [[MIN_ITERS_CHECKED]] ]
; CHECK-NEXT: br label [[FOR_BODY:%.*]]
; CHECK: for.body:
; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_INC:%.*]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ]
; CHECK-NEXT: [[SUM_011:%.*]] = phi i32 [ [[SUM_1:%.*]], [[FOR_INC]] ], [ [[BC_MERGE_RDX]], [[SCALAR_PH]] ]
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 [[INDVARS_IV]]
; CHECK-NEXT: [[TMP11:%.*]] = load i32, i32* [[ARRAYIDX]], align 4
; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i32 [[TMP11]], 30
; CHECK-NEXT: br i1 [[CMP1]], label [[IF_THEN:%.*]], label [[FOR_INC]]
; CHECK: if.then:
; CHECK-NEXT: [[ADD:%.*]] = add i32 [[SUM_011]], 2
; CHECK-NEXT: [[ADD4:%.*]] = add i32 [[ADD]], [[TMP11]]
; CHECK-NEXT: br label [[FOR_INC]]
; CHECK: for.inc:
; CHECK-NEXT: [[SUM_1]] = phi i32 [ [[ADD4]], [[IF_THEN]] ], [ [[SUM_011]], [[FOR_BODY]] ]
; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add i64 [[INDVARS_IV]], 1
; CHECK-NEXT: [[LFTR_WIDEIV:%.*]] = trunc i64 [[INDVARS_IV_NEXT]] to i32
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i32 [[LFTR_WIDEIV]], [[N]]
; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_END_LOOPEXIT]], label [[FOR_BODY]], !llvm.loop !10
; CHECK: for.end.loopexit:
; CHECK-NEXT: [[SUM_1_LCSSA:%.*]] = phi i32 [ [[SUM_1]], [[FOR_INC]] ], [ [[TMP10]], [[MIDDLE_BLOCK]] ]
; CHECK-NEXT: br label [[FOR_END]]
; CHECK: for.end:
; CHECK-NEXT: [[SUM_0_LCSSA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[SUM_1_LCSSA]], [[FOR_END_LOOPEXIT]] ]
; CHECK-NEXT: ret i32 [[SUM_0_LCSSA]]
;
entry:
%cmp10 = icmp sgt i32 %n, 0
br i1 %cmp10, label %for.body, label %for.end
for.body: ; preds = %entry, %for.inc
%indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
%sum.011 = phi i32 [ %sum.1, %for.inc ], [ 0, %entry ]
%arrayidx = getelementptr inbounds i32, i32* %A, i64 %indvars.iv
%0 = load i32, i32* %arrayidx, align 4
%cmp1 = icmp sgt i32 %0, 30
br i1 %cmp1, label %if.then, label %for.inc
if.then: ; preds = %for.body
%add = add i32 %sum.011, 2
%add4 = add i32 %add, %0
br label %for.inc
for.inc: ; preds = %for.body, %if.then
%sum.1 = phi i32 [ %add4, %if.then ], [ %sum.011, %for.body ]
%indvars.iv.next = add i64 %indvars.iv, 1
%lftr.wideiv = trunc i64 %indvars.iv.next to i32
%exitcond = icmp eq i32 %lftr.wideiv, %n
br i1 %exitcond, label %for.end, label %for.body
for.end: ; preds = %for.inc, %entry
%sum.0.lcssa = phi i32 [ 0, %entry ], [ %sum.1, %for.inc ]
ret i32 %sum.0.lcssa
}
@a = common global [1 x i32*] zeroinitializer, align 8
@c = common global i32* null, align 8
; We use to if convert this loop. This is not safe because there is a trapping
; constant expression.
; PR16729
define i32 @trapping_constant_expression() {
; CHECK-LABEL: @trapping_constant_expression(
; CHECK-NEXT: entry:
; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[MIN_ITERS_CHECKED:%.*]]
; CHECK: min.iters.checked:
; CHECK-NEXT: br i1 false, label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
; CHECK: vector.ph:
; CHECK-NEXT: br label [[VECTOR_BODY:%.*]]
; CHECK: vector.body:
; CHECK-NEXT: [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
; CHECK-NEXT: [[INDEX_NEXT]] = add i32 [[INDEX]], 4
; CHECK-NEXT: [[TMP0:%.*]] = icmp eq i32 [[INDEX_NEXT]], 128
; CHECK-NEXT: br i1 [[TMP0]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop !12
; CHECK: middle.block:
; CHECK-NEXT: br i1 true, label [[FOR_END:%.*]], label [[SCALAR_PH]]
; CHECK: scalar.ph:
; CHECK-NEXT: br label [[FOR_BODY:%.*]]
; CHECK: for.body:
; CHECK-NEXT: br i1 false, label [[COND_FALSE:%.*]], label [[COND_END:%.*]]
; CHECK: cond.false:
; CHECK-NEXT: br label [[COND_END]]
; CHECK: cond.end:
; CHECK-NEXT: br i1 undef, label [[FOR_BODY]], label [[FOR_END]], !llvm.loop !13
; CHECK: for.end:
; CHECK-NEXT: ret i32 0
;
entry:
br label %for.body
for.body:
%inc3 = phi i32 [ 0, %entry ], [ %inc, %cond.end ]
%or2 = phi i32 [ 0, %entry ], [ %or, %cond.end ]
br i1 icmp eq (i32** getelementptr inbounds ([1 x i32*], [1 x i32*]* @a, i64 0, i64 0), i32** @c), label %cond.false, label %cond.end
cond.false:
br label %cond.end
cond.end:
%cond = phi i32 [ sdiv (i32 1, i32 zext (i1 icmp eq (i32** getelementptr inbounds ([1 x i32*], [1 x i32*]* @a, i64 0, i64 0), i32** @c) to i32)), %cond.false ], [ 0, %for.body ]
%or = or i32 %or2, %cond
%inc = add nsw i32 %inc3, 1
%cmp = icmp slt i32 %inc, 128
br i1 %cmp, label %for.body, label %for.end
for.end:
ret i32 %or
}
; Neither should we if-convert if there is an instruction operand that is a
; trapping constant expression.
; PR16729
define i32 @trapping_constant_expression2() {
; CHECK-LABEL: @trapping_constant_expression2(
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[FOR_BODY:%.*]]
; CHECK: for.body:
; CHECK-NEXT: [[INC3:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[COND_END:%.*]] ]
; CHECK-NEXT: [[OR2:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[OR:%.*]], [[COND_END]] ]
; CHECK-NEXT: br i1 false, label [[COND_FALSE:%.*]], label [[COND_END]]
; CHECK: cond.false:
; CHECK-NEXT: br label [[COND_END]]
; CHECK: cond.end:
; CHECK-NEXT: [[OR]] = or i32 [[OR2]], [[INC3]]
; CHECK-NEXT: [[INC]] = add nsw i32 [[INC3]], 1
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[INC3]], 127
; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
; CHECK: for.end:
; CHECK-NEXT: ret i32 [[OR]]
;
entry:
br label %for.body
for.body:
%inc3 = phi i32 [ 0, %entry ], [ %inc, %cond.end ]
%or2 = phi i32 [ 0, %entry ], [ %or, %cond.end ]
br i1 icmp eq (i32** getelementptr inbounds ([1 x i32*], [1 x i32*]* @a, i64 0, i64 0), i32** @c), label %cond.false, label %cond.end
cond.false:
%cond.1 = or i32 %inc3, sdiv (i32 1, i32 zext (i1 icmp eq (i32** getelementptr inbounds ([1 x i32*], [1 x i32*]* @a, i64 0, i64 1), i32** @c) to i32))
br label %cond.end
cond.end:
%cond = phi i32 [ %cond.1, %cond.false ], [ %inc3, %for.body ]
%or = or i32 %or2, %cond
%inc = add nsw i32 %inc3, 1
%cmp = icmp slt i32 %inc, 128
br i1 %cmp, label %for.body, label %for.end
for.end:
ret i32 %or
}