Index: lib/Transforms/Utils/SimplifyCFG.cpp =================================================================== --- lib/Transforms/Utils/SimplifyCFG.cpp +++ lib/Transforms/Utils/SimplifyCFG.cpp @@ -4192,10 +4192,13 @@ Changed = true; } } else { + Value* Cond = BI->getCondition(); if (BI->getSuccessor(0) == BB) { + Builder.CreateAssumption(Builder.CreateNot(Cond)); Builder.CreateBr(BI->getSuccessor(1)); EraseTerminatorAndDCECond(BI); } else if (BI->getSuccessor(1) == BB) { + Builder.CreateAssumption(Cond); Builder.CreateBr(BI->getSuccessor(0)); EraseTerminatorAndDCECond(BI); Changed = true; Index: test/Analysis/ValueTracking/select-pattern.ll =================================================================== --- test/Analysis/ValueTracking/select-pattern.ll +++ test/Analysis/ValueTracking/select-pattern.ll @@ -1,3 +1,4 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt -simplifycfg < %s -S | FileCheck %s ; The dead code would cause a select that had itself @@ -7,6 +8,8 @@ define void @PR36045(i1 %t, i32* %b) { ; CHECK-LABEL: @PR36045( ; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[T:%.*]], true +; CHECK-NEXT: call void @llvm.assume(i1 [[TMP0]]) ; CHECK-NEXT: ret void ; entry: Index: test/Transforms/CallSiteSplitting/split-loop.ll =================================================================== --- test/Transforms/CallSiteSplitting/split-loop.ll +++ test/Transforms/CallSiteSplitting/split-loop.ll @@ -5,7 +5,9 @@ ; CHECK-LABEL: @test1( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 undef, i16 1, i16 0 -; CHECK-NEXT: call void @callee(i16 0) +; CHECK-NEXT: [[TOBOOL18:%.*]] = icmp ne i16 [[SPEC_SELECT]], 0 +; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[TOBOOL18]], true +; CHECK-NEXT: call void @llvm.assume(i1 [[TMP0]]) ; CHECK-NEXT: br label [[FOR_COND12:%.*]] ; CHECK: for.cond12: ; CHECK-NEXT: call void @callee(i16 [[SPEC_SELECT]]) @@ -28,12 +30,14 @@ ; CHECK-LABEL: @test2( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[S:%.*]] = select i1 undef, i16 1, i16 0 -; CHECK-NEXT: call void @callee(i16 0) +; CHECK-NEXT: [[TOBOOL18:%.*]] = icmp ne i16 [[S]], 0 +; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[TOBOOL18]], true +; CHECK-NEXT: call void @llvm.assume(i1 [[TMP0]]) ; CHECK-NEXT: br label [[FOR_COND12:%.*]] ; CHECK: for.cond12: +; CHECK-NEXT: call void @callee(i16 [[S]]) ; CHECK-NEXT: [[ADD:%.*]] = add i16 [[S]], 10 ; CHECK-NEXT: [[ADD2:%.*]] = add i16 [[S]], 10 -; CHECK-NEXT: call void @callee(i16 [[S]]) ; CHECK-NEXT: br label [[FOR_COND12]] ; entry: @@ -55,20 +59,20 @@ ; CHECK-LABEL: @test3( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[S:%.*]] = select i1 undef, i16 1, i16 0 -; CHECK-NEXT: call void @callee(i16 0) +; CHECK-NEXT: [[TOBOOL18:%.*]] = icmp ne i16 [[S]], 0 +; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[TOBOOL18]], true +; CHECK-NEXT: call void @llvm.assume(i1 [[TMP0]]) ; CHECK-NEXT: br label [[FOR_COND12:%.*]] ; CHECK: for.cond12: +; CHECK-NEXT: call void @callee(i16 [[S]]) ; CHECK-NEXT: [[ADD:%.*]] = add i16 [[S]], 10 ; CHECK-NEXT: [[ADD2:%.*]] = add i16 [[ADD]], 10 -; CHECK-NEXT: br i1 undef, label [[FOR_COND12_SPLIT:%.*]], label [[EXIT:%.*]] -; CHECK: for.cond12.split: -; CHECK-NEXT: call void @callee(i16 [[S]]) -; CHECK-NEXT: br label [[FOR_COND12]] +; CHECK-NEXT: br i1 undef, label [[FOR_COND12]], label [[EXIT:%.*]] ; CHECK: exit: ; CHECK-NEXT: ret i16 [[ADD2]] ; entry: - %s= select i1 undef, i16 1, i16 0 + %s = select i1 undef, i16 1, i16 0 %tobool18 = icmp ne i16 %s, 0 br i1 %tobool18, label %for.cond12.us, label %for.cond12 @@ -85,6 +89,4 @@ ret i16 %add2 } -define internal void @callee(i16 %flag) { - ret void -} +declare void @callee(i16 %flag) Index: test/Transforms/LoopVectorize/if-pred-stores.ll =================================================================== --- test/Transforms/LoopVectorize/if-pred-stores.ll +++ test/Transforms/LoopVectorize/if-pred-stores.ll @@ -1,3 +1,4 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt -S -vectorize-num-stores-pred=1 -force-vector-width=1 -force-vector-interleave=2 -loop-vectorize -verify-loop-info -simplifycfg < %s | FileCheck %s --check-prefix=UNROLL ; RUN: opt -S -vectorize-num-stores-pred=1 -force-vector-width=1 -force-vector-interleave=2 -loop-vectorize -verify-loop-info < %s | FileCheck %s --check-prefix=UNROLL-NOSIMPLIFY ; RUN: opt -S -vectorize-num-stores-pred=1 -force-vector-width=2 -force-vector-interleave=1 -loop-vectorize -verify-loop-info -simplifycfg < %s | FileCheck %s --check-prefix=VEC @@ -6,62 +7,166 @@ ; Test predication of stores. define i32 @test(i32* nocapture %f) #0 { +; UNROLL-LABEL: @test( +; UNROLL-NEXT: entry: +; UNROLL-NEXT: br label [[VECTOR_BODY:%.*]] +; UNROLL: vector.body: +; UNROLL-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDEX_NEXT:%.*]], [[PRED_STORE_CONTINUE3:%.*]] ] +; UNROLL-NEXT: [[INDUCTION:%.*]] = add i64 [[INDEX]], 0 +; UNROLL-NEXT: [[INDUCTION1:%.*]] = add i64 [[INDEX]], 1 +; UNROLL-NEXT: [[TMP0:%.*]] = getelementptr inbounds i32, i32* [[F:%.*]], i64 [[INDUCTION]] +; UNROLL-NEXT: [[TMP1:%.*]] = getelementptr inbounds i32, i32* [[F]], i64 [[INDUCTION1]] +; UNROLL-NEXT: [[TMP2:%.*]] = load i32, i32* [[TMP0]], align 4 +; UNROLL-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP1]], align 4 +; UNROLL-NEXT: [[TMP4:%.*]] = icmp sgt i32 [[TMP2]], 100 +; UNROLL-NEXT: [[TMP5:%.*]] = icmp sgt i32 [[TMP3]], 100 +; UNROLL-NEXT: br i1 [[TMP4]], label [[PRED_STORE_IF:%.*]], label [[PRED_STORE_CONTINUE:%.*]] +; UNROLL: pred.store.if: +; UNROLL-NEXT: [[TMP6:%.*]] = add nsw i32 [[TMP2]], 20 +; UNROLL-NEXT: store i32 [[TMP6]], i32* [[TMP0]], align 4 +; UNROLL-NEXT: br label [[PRED_STORE_CONTINUE]] +; UNROLL: pred.store.continue: +; UNROLL-NEXT: br i1 [[TMP5]], label [[PRED_STORE_IF2:%.*]], label [[PRED_STORE_CONTINUE3]] +; UNROLL: pred.store.if2: +; UNROLL-NEXT: [[TMP7:%.*]] = add nsw i32 [[TMP3]], 20 +; UNROLL-NEXT: store i32 [[TMP7]], i32* [[TMP1]], align 4 +; UNROLL-NEXT: br label [[PRED_STORE_CONTINUE3]] +; UNROLL: pred.store.continue3: +; UNROLL-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 2 +; UNROLL-NEXT: [[TMP8:%.*]] = icmp eq i64 [[INDEX_NEXT]], 128 +; UNROLL-NEXT: br i1 [[TMP8]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop !0 +; UNROLL: middle.block: +; UNROLL-NEXT: [[CMP_N:%.*]] = icmp eq i64 128, 128 +; UNROLL-NEXT: br i1 [[CMP_N]], label [[FOR_END:%.*]], label [[FOR_BODY:%.*]] +; UNROLL: for.body: +; UNROLL-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_INC:%.*]] ], [ 128, [[MIDDLE_BLOCK]] ] +; UNROLL-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[F]], i64 [[INDVARS_IV]] +; UNROLL-NEXT: [[TMP9:%.*]] = load i32, i32* [[ARRAYIDX]], align 4 +; UNROLL-NEXT: [[CMP1:%.*]] = icmp sgt i32 [[TMP9]], 100 +; UNROLL-NEXT: br i1 [[CMP1]], label [[IF_THEN:%.*]], label [[FOR_INC]] +; UNROLL: if.then: +; UNROLL-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP9]], 20 +; UNROLL-NEXT: store i32 [[ADD]], i32* [[ARRAYIDX]], align 4 +; UNROLL-NEXT: br label [[FOR_INC]] +; UNROLL: for.inc: +; UNROLL-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 +; UNROLL-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], 128 +; UNROLL-NEXT: br i1 [[EXITCOND]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop !2 +; UNROLL: for.end: +; UNROLL-NEXT: ret i32 0 +; +; UNROLL-NOSIMPLIFY-LABEL: @test( +; UNROLL-NOSIMPLIFY-NEXT: entry: +; UNROLL-NOSIMPLIFY-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] +; UNROLL-NOSIMPLIFY: vector.ph: +; UNROLL-NOSIMPLIFY-NEXT: br label [[VECTOR_BODY:%.*]] +; UNROLL-NOSIMPLIFY: vector.body: +; UNROLL-NOSIMPLIFY-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[PRED_STORE_CONTINUE3:%.*]] ] +; UNROLL-NOSIMPLIFY-NEXT: [[INDUCTION:%.*]] = add i64 [[INDEX]], 0 +; UNROLL-NOSIMPLIFY-NEXT: [[INDUCTION1:%.*]] = add i64 [[INDEX]], 1 +; UNROLL-NOSIMPLIFY-NEXT: [[TMP0:%.*]] = getelementptr inbounds i32, i32* [[F:%.*]], i64 [[INDUCTION]] +; UNROLL-NOSIMPLIFY-NEXT: [[TMP1:%.*]] = getelementptr inbounds i32, i32* [[F]], i64 [[INDUCTION1]] +; UNROLL-NOSIMPLIFY-NEXT: [[TMP2:%.*]] = load i32, i32* [[TMP0]], align 4 +; UNROLL-NOSIMPLIFY-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP1]], align 4 +; UNROLL-NOSIMPLIFY-NEXT: [[TMP4:%.*]] = icmp sgt i32 [[TMP2]], 100 +; UNROLL-NOSIMPLIFY-NEXT: [[TMP5:%.*]] = icmp sgt i32 [[TMP3]], 100 +; UNROLL-NOSIMPLIFY-NEXT: br i1 [[TMP4]], label [[PRED_STORE_IF:%.*]], label [[PRED_STORE_CONTINUE:%.*]] +; UNROLL-NOSIMPLIFY: pred.store.if: +; UNROLL-NOSIMPLIFY-NEXT: [[TMP6:%.*]] = add nsw i32 [[TMP2]], 20 +; UNROLL-NOSIMPLIFY-NEXT: store i32 [[TMP6]], i32* [[TMP0]], align 4 +; UNROLL-NOSIMPLIFY-NEXT: br label [[PRED_STORE_CONTINUE]] +; UNROLL-NOSIMPLIFY: pred.store.continue: +; UNROLL-NOSIMPLIFY-NEXT: br i1 [[TMP5]], label [[PRED_STORE_IF2:%.*]], label [[PRED_STORE_CONTINUE3]] +; UNROLL-NOSIMPLIFY: pred.store.if2: +; UNROLL-NOSIMPLIFY-NEXT: [[TMP7:%.*]] = add nsw i32 [[TMP3]], 20 +; UNROLL-NOSIMPLIFY-NEXT: store i32 [[TMP7]], i32* [[TMP1]], align 4 +; UNROLL-NOSIMPLIFY-NEXT: br label [[PRED_STORE_CONTINUE3]] +; UNROLL-NOSIMPLIFY: pred.store.continue3: +; UNROLL-NOSIMPLIFY-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 2 +; UNROLL-NOSIMPLIFY-NEXT: [[TMP8:%.*]] = icmp eq i64 [[INDEX_NEXT]], 128 +; UNROLL-NOSIMPLIFY-NEXT: br i1 [[TMP8]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop !0 +; UNROLL-NOSIMPLIFY: middle.block: +; UNROLL-NOSIMPLIFY-NEXT: [[CMP_N:%.*]] = icmp eq i64 128, 128 +; UNROLL-NOSIMPLIFY-NEXT: br i1 [[CMP_N]], label [[FOR_END:%.*]], label [[SCALAR_PH]] +; UNROLL-NOSIMPLIFY: scalar.ph: +; UNROLL-NOSIMPLIFY-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 128, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ] +; UNROLL-NOSIMPLIFY-NEXT: br label [[FOR_BODY:%.*]] +; UNROLL-NOSIMPLIFY: for.body: +; UNROLL-NOSIMPLIFY-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_INC:%.*]] ] +; UNROLL-NOSIMPLIFY-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[F]], i64 [[INDVARS_IV]] +; UNROLL-NOSIMPLIFY-NEXT: [[TMP9:%.*]] = load i32, i32* [[ARRAYIDX]], align 4 +; UNROLL-NOSIMPLIFY-NEXT: [[CMP1:%.*]] = icmp sgt i32 [[TMP9]], 100 +; UNROLL-NOSIMPLIFY-NEXT: br i1 [[CMP1]], label [[IF_THEN:%.*]], label [[FOR_INC]] +; UNROLL-NOSIMPLIFY: if.then: +; UNROLL-NOSIMPLIFY-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP9]], 20 +; UNROLL-NOSIMPLIFY-NEXT: store i32 [[ADD]], i32* [[ARRAYIDX]], align 4 +; UNROLL-NOSIMPLIFY-NEXT: br label [[FOR_INC]] +; UNROLL-NOSIMPLIFY: for.inc: +; UNROLL-NOSIMPLIFY-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 +; UNROLL-NOSIMPLIFY-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], 128 +; UNROLL-NOSIMPLIFY-NEXT: br i1 [[EXITCOND]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop !2 +; UNROLL-NOSIMPLIFY: for.end: +; UNROLL-NOSIMPLIFY-NEXT: ret i32 0 +; +; VEC-LABEL: @test( +; VEC-NEXT: entry: +; VEC-NEXT: br label [[VECTOR_BODY:%.*]] +; VEC: vector.body: +; VEC-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDEX_NEXT:%.*]], [[PRED_STORE_CONTINUE2:%.*]] ] +; VEC-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement <2 x i64> undef, i64 [[INDEX]], i32 0 +; VEC-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector <2 x i64> [[BROADCAST_SPLATINSERT]], <2 x i64> undef, <2 x i32> zeroinitializer +; VEC-NEXT: [[INDUCTION:%.*]] = add <2 x i64> [[BROADCAST_SPLAT]], +; VEC-NEXT: [[TMP0:%.*]] = add i64 [[INDEX]], 0 +; VEC-NEXT: [[TMP1:%.*]] = getelementptr inbounds i32, i32* [[F:%.*]], i64 [[TMP0]] +; VEC-NEXT: [[TMP2:%.*]] = getelementptr inbounds i32, i32* [[TMP1]], i32 0 +; VEC-NEXT: [[TMP3:%.*]] = bitcast i32* [[TMP2]] to <2 x i32>* +; VEC-NEXT: [[WIDE_LOAD:%.*]] = load <2 x i32>, <2 x i32>* [[TMP3]], align 4 +; VEC-NEXT: [[TMP4:%.*]] = icmp sgt <2 x i32> [[WIDE_LOAD]], +; VEC-NEXT: [[TMP5:%.*]] = extractelement <2 x i1> [[TMP4]], i32 0 +; VEC-NEXT: br i1 [[TMP5]], label [[PRED_STORE_IF:%.*]], label [[PRED_STORE_CONTINUE:%.*]] +; VEC: pred.store.if: +; VEC-NEXT: [[TMP6:%.*]] = extractelement <2 x i32> [[WIDE_LOAD]], i32 0 +; VEC-NEXT: [[TMP7:%.*]] = add nsw i32 [[TMP6]], 20 +; VEC-NEXT: store i32 [[TMP7]], i32* [[TMP1]], align 4 +; VEC-NEXT: br label [[PRED_STORE_CONTINUE]] +; VEC: pred.store.continue: +; VEC-NEXT: [[TMP8:%.*]] = extractelement <2 x i1> [[TMP4]], i32 1 +; VEC-NEXT: br i1 [[TMP8]], label [[PRED_STORE_IF1:%.*]], label [[PRED_STORE_CONTINUE2]] +; VEC: pred.store.if1: +; VEC-NEXT: [[TMP9:%.*]] = extractelement <2 x i32> [[WIDE_LOAD]], i32 1 +; VEC-NEXT: [[TMP10:%.*]] = add nsw i32 [[TMP9]], 20 +; VEC-NEXT: [[TMP11:%.*]] = add i64 [[INDEX]], 1 +; VEC-NEXT: [[TMP12:%.*]] = getelementptr inbounds i32, i32* [[F]], i64 [[TMP11]] +; VEC-NEXT: store i32 [[TMP10]], i32* [[TMP12]], align 4 +; VEC-NEXT: br label [[PRED_STORE_CONTINUE2]] +; VEC: pred.store.continue2: +; VEC-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 2 +; VEC-NEXT: [[TMP13:%.*]] = icmp eq i64 [[INDEX_NEXT]], 128 +; VEC-NEXT: br i1 [[TMP13]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop !0 +; VEC: middle.block: +; VEC-NEXT: [[CMP_N:%.*]] = icmp eq i64 128, 128 +; VEC-NEXT: br i1 [[CMP_N]], label [[FOR_END:%.*]], label [[FOR_BODY:%.*]] +; VEC: for.body: +; VEC-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_INC:%.*]] ], [ 128, [[MIDDLE_BLOCK]] ] +; VEC-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[F]], i64 [[INDVARS_IV]] +; VEC-NEXT: [[TMP14:%.*]] = load i32, i32* [[ARRAYIDX]], align 4 +; VEC-NEXT: [[CMP1:%.*]] = icmp sgt i32 [[TMP14]], 100 +; VEC-NEXT: br i1 [[CMP1]], label [[IF_THEN:%.*]], label [[FOR_INC]] +; VEC: if.then: +; VEC-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP14]], 20 +; VEC-NEXT: store i32 [[ADD]], i32* [[ARRAYIDX]], align 4 +; VEC-NEXT: br label [[FOR_INC]] +; VEC: for.inc: +; VEC-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 +; VEC-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], 128 +; VEC-NEXT: br i1 [[EXITCOND]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop !2 +; VEC: for.end: +; VEC-NEXT: ret i32 0 +; entry: br label %for.body -; VEC-LABEL: test -; VEC: %[[v0:.+]] = add i64 %index, 0 -; VEC: %[[v2:.+]] = getelementptr inbounds i32, i32* %f, i64 %[[v0]] -; VEC: %[[v8:.+]] = icmp sgt <2 x i32> %{{.*}}, -; VEC: %[[v11:.+]] = extractelement <2 x i1> %[[v8]], i32 0 -; VEC: br i1 %[[v11]], label %[[cond:.+]], label %[[else:.+]] -; -; VEC: [[cond]]: -; VEC: %[[v13:.+]] = extractelement <2 x i32> %wide.load, i32 0 -; VEC: %[[v9a:.+]] = add nsw i32 %[[v13]], 20 -; VEC: store i32 %[[v9a]], i32* %[[v2]], align 4 -; VEC: br label %[[else:.+]] -; -; VEC: [[else]]: -; VEC: %[[v15:.+]] = extractelement <2 x i1> %[[v8]], i32 1 -; VEC: br i1 %[[v15]], label %[[cond2:.+]], label %[[else2:.+]] -; -; VEC: [[cond2]]: -; VEC: %[[v17:.+]] = extractelement <2 x i32> %wide.load, i32 1 -; VEC: %[[v9b:.+]] = add nsw i32 %[[v17]], 20 -; VEC: %[[v1:.+]] = add i64 %index, 1 -; VEC: %[[v4:.+]] = getelementptr inbounds i32, i32* %f, i64 %[[v1]] -; VEC: store i32 %[[v9b]], i32* %[[v4]], align 4 -; VEC: br label %[[else2:.+]] -; -; VEC: [[else2]]: - -; UNROLL-LABEL: test -; UNROLL: vector.body: -; UNROLL: %[[IND:[a-zA-Z0-9]+]] = add i64 %{{.*}}, 0 -; UNROLL: %[[IND1:[a-zA-Z0-9]+]] = add i64 %{{.*}}, 1 -; UNROLL: %[[v0:[a-zA-Z0-9]+]] = getelementptr inbounds i32, i32* %f, i64 %[[IND]] -; UNROLL: %[[v1:[a-zA-Z0-9]+]] = getelementptr inbounds i32, i32* %f, i64 %[[IND1]] -; UNROLL: %[[v2:[a-zA-Z0-9]+]] = load i32, i32* %[[v0]], align 4 -; UNROLL: %[[v3:[a-zA-Z0-9]+]] = load i32, i32* %[[v1]], align 4 -; UNROLL: %[[v4:[a-zA-Z0-9]+]] = icmp sgt i32 %[[v2]], 100 -; UNROLL: %[[v5:[a-zA-Z0-9]+]] = icmp sgt i32 %[[v3]], 100 -; UNROLL: br i1 %[[v4]], label %[[cond:[a-zA-Z0-9.]+]], label %[[else:[a-zA-Z0-9.]+]] -; -; UNROLL: [[cond]]: -; UNROLL: %[[v6:[a-zA-Z0-9]+]] = add nsw i32 %[[v2]], 20 -; UNROLL: store i32 %[[v6]], i32* %[[v0]], align 4 -; UNROLL: br label %[[else]] -; -; UNROLL: [[else]]: -; UNROLL: br i1 %[[v5]], label %[[cond2:[a-zA-Z0-9.]+]], label %[[else2:[a-zA-Z0-9.]+]] -; -; UNROLL: [[cond2]]: -; UNROLL: %[[v7:[a-zA-Z0-9]+]] = add nsw i32 %[[v3]], 20 -; UNROLL: store i32 %[[v7]], i32* %[[v1]], align 4 -; UNROLL: br label %[[else2]] -; -; UNROLL: [[else2]]: + for.body: %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.inc ] @@ -94,6 +199,86 @@ ; UNROLL-NOSIMPLIFY: store i32 define void @bug18724() { +; UNROLL-LABEL: @bug18724( +; UNROLL-NEXT: entry: +; UNROLL-NEXT: unreachable +; +; UNROLL-NOSIMPLIFY-LABEL: @bug18724( +; UNROLL-NOSIMPLIFY-NEXT: entry: +; UNROLL-NOSIMPLIFY-NEXT: br label [[FOR_BODY9:%.*]] +; UNROLL-NOSIMPLIFY: for.body9: +; UNROLL-NOSIMPLIFY-NEXT: br i1 undef, label [[FOR_INC26:%.*]], label [[FOR_BODY14_PREHEADER:%.*]] +; UNROLL-NOSIMPLIFY: for.body14.preheader: +; UNROLL-NOSIMPLIFY-NEXT: br i1 true, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] +; UNROLL-NOSIMPLIFY: vector.ph: +; UNROLL-NOSIMPLIFY-NEXT: br label [[VECTOR_BODY:%.*]] +; UNROLL-NOSIMPLIFY: vector.body: +; UNROLL-NOSIMPLIFY-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[PRED_STORE_CONTINUE4:%.*]] ] +; UNROLL-NOSIMPLIFY-NEXT: [[VEC_PHI:%.*]] = phi i32 [ undef, [[VECTOR_PH]] ], [ [[PREDPHI:%.*]], [[PRED_STORE_CONTINUE4]] ] +; UNROLL-NOSIMPLIFY-NEXT: [[VEC_PHI2:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[PREDPHI5:%.*]], [[PRED_STORE_CONTINUE4]] ] +; UNROLL-NOSIMPLIFY-NEXT: [[OFFSET_IDX:%.*]] = add i64 undef, [[INDEX]] +; UNROLL-NOSIMPLIFY-NEXT: [[INDUCTION:%.*]] = add i64 [[OFFSET_IDX]], 0 +; UNROLL-NOSIMPLIFY-NEXT: [[INDUCTION1:%.*]] = add i64 [[OFFSET_IDX]], 1 +; UNROLL-NOSIMPLIFY-NEXT: [[TMP0:%.*]] = getelementptr inbounds [768 x i32], [768 x i32]* undef, i64 0, i64 [[INDUCTION]] +; UNROLL-NOSIMPLIFY-NEXT: [[TMP1:%.*]] = getelementptr inbounds [768 x i32], [768 x i32]* undef, i64 0, i64 [[INDUCTION1]] +; UNROLL-NOSIMPLIFY-NEXT: [[TMP2:%.*]] = load i32, i32* [[TMP0]], align 4 +; UNROLL-NOSIMPLIFY-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP1]], align 4 +; UNROLL-NOSIMPLIFY-NEXT: br i1 undef, label [[PRED_STORE_IF:%.*]], label [[PRED_STORE_CONTINUE:%.*]] +; UNROLL-NOSIMPLIFY: pred.store.if: +; UNROLL-NOSIMPLIFY-NEXT: store i32 2, i32* [[TMP0]], align 4 +; UNROLL-NOSIMPLIFY-NEXT: br label [[PRED_STORE_CONTINUE]] +; UNROLL-NOSIMPLIFY: pred.store.continue: +; UNROLL-NOSIMPLIFY-NEXT: br i1 undef, label [[PRED_STORE_IF3:%.*]], label [[PRED_STORE_CONTINUE4]] +; UNROLL-NOSIMPLIFY: pred.store.if3: +; UNROLL-NOSIMPLIFY-NEXT: store i32 2, i32* [[TMP1]], align 4 +; UNROLL-NOSIMPLIFY-NEXT: br label [[PRED_STORE_CONTINUE4]] +; UNROLL-NOSIMPLIFY: pred.store.continue4: +; UNROLL-NOSIMPLIFY-NEXT: [[TMP4:%.*]] = add nsw i32 [[VEC_PHI]], 1 +; UNROLL-NOSIMPLIFY-NEXT: [[TMP5:%.*]] = add nsw i32 [[VEC_PHI2]], 1 +; UNROLL-NOSIMPLIFY-NEXT: [[PREDPHI]] = select i1 undef, i32 [[VEC_PHI]], i32 [[TMP4]] +; UNROLL-NOSIMPLIFY-NEXT: [[PREDPHI5]] = select i1 undef, i32 [[VEC_PHI2]], i32 [[TMP5]] +; UNROLL-NOSIMPLIFY-NEXT: [[OFFSET_IDX6:%.*]] = add i64 undef, [[INDEX]] +; UNROLL-NOSIMPLIFY-NEXT: [[TMP6:%.*]] = trunc i64 [[OFFSET_IDX6]] to i32 +; UNROLL-NOSIMPLIFY-NEXT: [[INDUCTION7:%.*]] = add i32 [[TMP6]], 0 +; UNROLL-NOSIMPLIFY-NEXT: [[INDUCTION8:%.*]] = add i32 [[TMP6]], 1 +; UNROLL-NOSIMPLIFY-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 2 +; UNROLL-NOSIMPLIFY-NEXT: [[TMP7:%.*]] = icmp eq i64 [[INDEX_NEXT]], 0 +; UNROLL-NOSIMPLIFY-NEXT: br i1 [[TMP7]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop !3 +; UNROLL-NOSIMPLIFY: middle.block: +; UNROLL-NOSIMPLIFY-NEXT: [[BIN_RDX:%.*]] = add i32 [[PREDPHI5]], [[PREDPHI]] +; UNROLL-NOSIMPLIFY-NEXT: [[CMP_N:%.*]] = icmp eq i64 1, 0 +; UNROLL-NOSIMPLIFY-NEXT: br i1 [[CMP_N]], label [[FOR_INC26_LOOPEXIT:%.*]], label [[SCALAR_PH]] +; UNROLL-NOSIMPLIFY: scalar.ph: +; UNROLL-NOSIMPLIFY-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ undef, [[MIDDLE_BLOCK]] ], [ undef, [[FOR_BODY14_PREHEADER]] ] +; UNROLL-NOSIMPLIFY-NEXT: [[BC_MERGE_RDX:%.*]] = phi i32 [ undef, [[FOR_BODY14_PREHEADER]] ], [ [[BIN_RDX]], [[MIDDLE_BLOCK]] ] +; UNROLL-NOSIMPLIFY-NEXT: br label [[FOR_BODY14:%.*]] +; UNROLL-NOSIMPLIFY: for.body14: +; UNROLL-NOSIMPLIFY-NEXT: [[INDVARS_IV3:%.*]] = phi i64 [ [[INDVARS_IV_NEXT4:%.*]], [[FOR_INC23:%.*]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ] +; UNROLL-NOSIMPLIFY-NEXT: [[INEWCHUNKS_120:%.*]] = phi i32 [ [[INEWCHUNKS_2:%.*]], [[FOR_INC23]] ], [ [[BC_MERGE_RDX]], [[SCALAR_PH]] ] +; UNROLL-NOSIMPLIFY-NEXT: [[ARRAYIDX16:%.*]] = getelementptr inbounds [768 x i32], [768 x i32]* undef, i64 0, i64 [[INDVARS_IV3]] +; UNROLL-NOSIMPLIFY-NEXT: [[TMP:%.*]] = load i32, i32* [[ARRAYIDX16]], align 4 +; UNROLL-NOSIMPLIFY-NEXT: br i1 undef, label [[IF_THEN18:%.*]], label [[FOR_INC23]] +; UNROLL-NOSIMPLIFY: if.then18: +; UNROLL-NOSIMPLIFY-NEXT: store i32 2, i32* [[ARRAYIDX16]], align 4 +; UNROLL-NOSIMPLIFY-NEXT: [[INC21:%.*]] = add nsw i32 [[INEWCHUNKS_120]], 1 +; UNROLL-NOSIMPLIFY-NEXT: br label [[FOR_INC23]] +; UNROLL-NOSIMPLIFY: for.inc23: +; UNROLL-NOSIMPLIFY-NEXT: [[INEWCHUNKS_2]] = phi i32 [ [[INC21]], [[IF_THEN18]] ], [ [[INEWCHUNKS_120]], [[FOR_BODY14]] ] +; UNROLL-NOSIMPLIFY-NEXT: [[INDVARS_IV_NEXT4]] = add nsw i64 [[INDVARS_IV3]], 1 +; UNROLL-NOSIMPLIFY-NEXT: [[TMP1:%.*]] = trunc i64 [[INDVARS_IV3]] to i32 +; UNROLL-NOSIMPLIFY-NEXT: [[CMP13:%.*]] = icmp slt i32 [[TMP1]], 0 +; UNROLL-NOSIMPLIFY-NEXT: br i1 [[CMP13]], label [[FOR_BODY14]], label [[FOR_INC26_LOOPEXIT]], !llvm.loop !4 +; UNROLL-NOSIMPLIFY: for.inc26.loopexit: +; UNROLL-NOSIMPLIFY-NEXT: [[INEWCHUNKS_2_LCSSA:%.*]] = phi i32 [ [[INEWCHUNKS_2]], [[FOR_INC23]] ], [ [[BIN_RDX]], [[MIDDLE_BLOCK]] ] +; UNROLL-NOSIMPLIFY-NEXT: br label [[FOR_INC26]] +; UNROLL-NOSIMPLIFY: for.inc26: +; UNROLL-NOSIMPLIFY-NEXT: [[INEWCHUNKS_1_LCSSA:%.*]] = phi i32 [ undef, [[FOR_BODY9]] ], [ [[INEWCHUNKS_2_LCSSA]], [[FOR_INC26_LOOPEXIT]] ] +; UNROLL-NOSIMPLIFY-NEXT: unreachable +; +; VEC-LABEL: @bug18724( +; VEC-NEXT: entry: +; VEC-NEXT: unreachable +; entry: br label %for.body9 @@ -151,6 +336,179 @@ ; VEC: br i1 {{.*}}, label %middle.block, label %vector.body ; define void @minimal_bit_widths(i1 %c) { +; UNROLL-LABEL: @minimal_bit_widths( +; UNROLL-NEXT: entry: +; UNROLL-NEXT: br label [[VECTOR_BODY:%.*]] +; UNROLL: vector.body: +; UNROLL-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDEX_NEXT:%.*]], [[PRED_STORE_CONTINUE6:%.*]] ] +; UNROLL-NEXT: [[OFFSET_IDX:%.*]] = sub i64 undef, [[INDEX]] +; UNROLL-NEXT: [[INDUCTION3:%.*]] = add i64 [[OFFSET_IDX]], 0 +; UNROLL-NEXT: [[INDUCTION4:%.*]] = add i64 [[OFFSET_IDX]], -1 +; UNROLL-NEXT: br i1 [[C:%.*]], label [[PRED_STORE_IF:%.*]], label [[PRED_STORE_CONTINUE6]] +; UNROLL: pred.store.if: +; UNROLL-NEXT: [[INDUCTION:%.*]] = add i64 [[INDEX]], 0 +; UNROLL-NEXT: [[TMP0:%.*]] = getelementptr i8, i8* undef, i64 [[INDUCTION]] +; UNROLL-NEXT: [[TMP1:%.*]] = load i8, i8* [[TMP0]], align 1 +; UNROLL-NEXT: [[TMP2:%.*]] = zext i8 [[TMP1]] to i32 +; UNROLL-NEXT: [[TMP3:%.*]] = trunc i32 [[TMP2]] to i8 +; UNROLL-NEXT: store i8 [[TMP3]], i8* [[TMP0]], align 1 +; UNROLL-NEXT: [[INDUCTION2:%.*]] = add i64 [[INDEX]], 1 +; UNROLL-NEXT: [[TMP4:%.*]] = getelementptr i8, i8* undef, i64 [[INDUCTION2]] +; UNROLL-NEXT: [[TMP5:%.*]] = load i8, i8* [[TMP4]], align 1 +; UNROLL-NEXT: [[TMP6:%.*]] = zext i8 [[TMP5]] to i32 +; UNROLL-NEXT: [[TMP7:%.*]] = trunc i32 [[TMP6]] to i8 +; UNROLL-NEXT: store i8 [[TMP7]], i8* [[TMP4]], align 1 +; UNROLL-NEXT: br label [[PRED_STORE_CONTINUE6]] +; UNROLL: pred.store.continue6: +; UNROLL-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 2 +; UNROLL-NEXT: [[TMP8:%.*]] = icmp eq i64 [[INDEX_NEXT]], undef +; UNROLL-NEXT: br i1 [[TMP8]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop !3 +; UNROLL: middle.block: +; UNROLL-NEXT: [[CMP_N:%.*]] = icmp eq i64 undef, undef +; UNROLL-NEXT: br i1 [[CMP_N]], label [[FOR_END:%.*]], label [[FOR_BODY:%.*]] +; UNROLL: for.body: +; UNROLL-NEXT: [[TMP0:%.*]] = phi i64 [ [[TMP6:%.*]], [[FOR_INC:%.*]] ], [ undef, [[MIDDLE_BLOCK]] ] +; UNROLL-NEXT: [[TMP1:%.*]] = phi i64 [ [[TMP7:%.*]], [[FOR_INC]] ], [ undef, [[MIDDLE_BLOCK]] ] +; UNROLL-NEXT: [[TMP2:%.*]] = getelementptr i8, i8* undef, i64 [[TMP0]] +; UNROLL-NEXT: [[TMP3:%.*]] = load i8, i8* [[TMP2]], align 1 +; UNROLL-NEXT: br i1 [[C]], label [[IF_THEN:%.*]], label [[FOR_INC]] +; UNROLL: if.then: +; UNROLL-NEXT: [[TMP4:%.*]] = zext i8 [[TMP3]] to i32 +; UNROLL-NEXT: [[TMP5:%.*]] = trunc i32 [[TMP4]] to i8 +; UNROLL-NEXT: store i8 [[TMP5]], i8* [[TMP2]], align 1 +; UNROLL-NEXT: br label [[FOR_INC]] +; UNROLL: for.inc: +; UNROLL-NEXT: [[TMP6]] = add nuw nsw i64 [[TMP0]], 1 +; UNROLL-NEXT: [[TMP7]] = add i64 [[TMP1]], -1 +; UNROLL-NEXT: [[TMP8:%.*]] = icmp eq i64 [[TMP7]], 0 +; UNROLL-NEXT: br i1 [[TMP8]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop !4 +; UNROLL: for.end: +; UNROLL-NEXT: ret void +; +; UNROLL-NOSIMPLIFY-LABEL: @minimal_bit_widths( +; UNROLL-NOSIMPLIFY-NEXT: entry: +; UNROLL-NOSIMPLIFY-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] +; UNROLL-NOSIMPLIFY: vector.ph: +; UNROLL-NOSIMPLIFY-NEXT: br label [[VECTOR_BODY:%.*]] +; UNROLL-NOSIMPLIFY: vector.body: +; UNROLL-NOSIMPLIFY-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[PRED_STORE_CONTINUE6:%.*]] ] +; UNROLL-NOSIMPLIFY-NEXT: [[OFFSET_IDX:%.*]] = sub i64 undef, [[INDEX]] +; UNROLL-NOSIMPLIFY-NEXT: [[INDUCTION3:%.*]] = add i64 [[OFFSET_IDX]], 0 +; UNROLL-NOSIMPLIFY-NEXT: [[INDUCTION4:%.*]] = add i64 [[OFFSET_IDX]], -1 +; UNROLL-NOSIMPLIFY-NEXT: br i1 [[C:%.*]], label [[PRED_STORE_IF:%.*]], label [[PRED_STORE_CONTINUE:%.*]] +; UNROLL-NOSIMPLIFY: pred.store.if: +; UNROLL-NOSIMPLIFY-NEXT: [[INDUCTION:%.*]] = add i64 [[INDEX]], 0 +; UNROLL-NOSIMPLIFY-NEXT: [[TMP0:%.*]] = getelementptr i8, i8* undef, i64 [[INDUCTION]] +; UNROLL-NOSIMPLIFY-NEXT: [[TMP1:%.*]] = load i8, i8* [[TMP0]], align 1 +; UNROLL-NOSIMPLIFY-NEXT: [[TMP2:%.*]] = zext i8 [[TMP1]] to i32 +; UNROLL-NOSIMPLIFY-NEXT: [[TMP3:%.*]] = trunc i32 [[TMP2]] to i8 +; UNROLL-NOSIMPLIFY-NEXT: store i8 [[TMP3]], i8* [[TMP0]], align 1 +; UNROLL-NOSIMPLIFY-NEXT: br label [[PRED_STORE_CONTINUE]] +; UNROLL-NOSIMPLIFY: pred.store.continue: +; UNROLL-NOSIMPLIFY-NEXT: br i1 [[C]], label [[PRED_STORE_IF5:%.*]], label [[PRED_STORE_CONTINUE6]] +; UNROLL-NOSIMPLIFY: pred.store.if5: +; UNROLL-NOSIMPLIFY-NEXT: [[INDUCTION2:%.*]] = add i64 [[INDEX]], 1 +; UNROLL-NOSIMPLIFY-NEXT: [[TMP4:%.*]] = getelementptr i8, i8* undef, i64 [[INDUCTION2]] +; UNROLL-NOSIMPLIFY-NEXT: [[TMP5:%.*]] = load i8, i8* [[TMP4]], align 1 +; UNROLL-NOSIMPLIFY-NEXT: [[TMP6:%.*]] = zext i8 [[TMP5]] to i32 +; UNROLL-NOSIMPLIFY-NEXT: [[TMP7:%.*]] = trunc i32 [[TMP6]] to i8 +; UNROLL-NOSIMPLIFY-NEXT: store i8 [[TMP7]], i8* [[TMP4]], align 1 +; UNROLL-NOSIMPLIFY-NEXT: br label [[PRED_STORE_CONTINUE6]] +; UNROLL-NOSIMPLIFY: pred.store.continue6: +; UNROLL-NOSIMPLIFY-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 2 +; UNROLL-NOSIMPLIFY-NEXT: [[TMP8:%.*]] = icmp eq i64 [[INDEX_NEXT]], undef +; UNROLL-NOSIMPLIFY-NEXT: br i1 [[TMP8]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop !5 +; UNROLL-NOSIMPLIFY: middle.block: +; UNROLL-NOSIMPLIFY-NEXT: [[CMP_N:%.*]] = icmp eq i64 undef, undef +; UNROLL-NOSIMPLIFY-NEXT: br i1 [[CMP_N]], label [[FOR_END:%.*]], label [[SCALAR_PH]] +; UNROLL-NOSIMPLIFY: scalar.ph: +; UNROLL-NOSIMPLIFY-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ undef, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ] +; UNROLL-NOSIMPLIFY-NEXT: [[BC_RESUME_VAL1:%.*]] = phi i64 [ undef, [[MIDDLE_BLOCK]] ], [ undef, [[ENTRY]] ] +; UNROLL-NOSIMPLIFY-NEXT: br label [[FOR_BODY:%.*]] +; UNROLL-NOSIMPLIFY: for.body: +; UNROLL-NOSIMPLIFY-NEXT: [[TMP0:%.*]] = phi i64 [ [[TMP6:%.*]], [[FOR_INC:%.*]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ] +; UNROLL-NOSIMPLIFY-NEXT: [[TMP1:%.*]] = phi i64 [ [[TMP7:%.*]], [[FOR_INC]] ], [ [[BC_RESUME_VAL1]], [[SCALAR_PH]] ] +; UNROLL-NOSIMPLIFY-NEXT: [[TMP2:%.*]] = getelementptr i8, i8* undef, i64 [[TMP0]] +; UNROLL-NOSIMPLIFY-NEXT: [[TMP3:%.*]] = load i8, i8* [[TMP2]], align 1 +; UNROLL-NOSIMPLIFY-NEXT: br i1 [[C]], label [[IF_THEN:%.*]], label [[FOR_INC]] +; UNROLL-NOSIMPLIFY: if.then: +; UNROLL-NOSIMPLIFY-NEXT: [[TMP4:%.*]] = zext i8 [[TMP3]] to i32 +; UNROLL-NOSIMPLIFY-NEXT: [[TMP5:%.*]] = trunc i32 [[TMP4]] to i8 +; UNROLL-NOSIMPLIFY-NEXT: store i8 [[TMP5]], i8* [[TMP2]], align 1 +; UNROLL-NOSIMPLIFY-NEXT: br label [[FOR_INC]] +; UNROLL-NOSIMPLIFY: for.inc: +; UNROLL-NOSIMPLIFY-NEXT: [[TMP6]] = add nuw nsw i64 [[TMP0]], 1 +; UNROLL-NOSIMPLIFY-NEXT: [[TMP7]] = add i64 [[TMP1]], -1 +; UNROLL-NOSIMPLIFY-NEXT: [[TMP8:%.*]] = icmp eq i64 [[TMP7]], 0 +; UNROLL-NOSIMPLIFY-NEXT: br i1 [[TMP8]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop !6 +; UNROLL-NOSIMPLIFY: for.end: +; UNROLL-NOSIMPLIFY-NEXT: ret void +; +; VEC-LABEL: @minimal_bit_widths( +; VEC-NEXT: entry: +; VEC-NEXT: [[BROADCAST_SPLATINSERT5:%.*]] = insertelement <2 x i1> undef, i1 [[C:%.*]], i32 0 +; VEC-NEXT: [[BROADCAST_SPLAT6:%.*]] = shufflevector <2 x i1> [[BROADCAST_SPLATINSERT5]], <2 x i1> undef, <2 x i32> zeroinitializer +; VEC-NEXT: br label [[VECTOR_BODY:%.*]] +; VEC: vector.body: +; VEC-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDEX_NEXT:%.*]], [[PRED_STORE_CONTINUE8:%.*]] ] +; VEC-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement <2 x i64> undef, i64 [[INDEX]], i32 0 +; VEC-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector <2 x i64> [[BROADCAST_SPLATINSERT]], <2 x i64> undef, <2 x i32> zeroinitializer +; VEC-NEXT: [[INDUCTION:%.*]] = add <2 x i64> [[BROADCAST_SPLAT]], +; VEC-NEXT: [[TMP0:%.*]] = add i64 [[INDEX]], 0 +; VEC-NEXT: [[OFFSET_IDX:%.*]] = sub i64 undef, [[INDEX]] +; VEC-NEXT: [[BROADCAST_SPLATINSERT2:%.*]] = insertelement <2 x i64> undef, i64 [[OFFSET_IDX]], i32 0 +; VEC-NEXT: [[BROADCAST_SPLAT3:%.*]] = shufflevector <2 x i64> [[BROADCAST_SPLATINSERT2]], <2 x i64> undef, <2 x i32> zeroinitializer +; VEC-NEXT: [[INDUCTION4:%.*]] = add <2 x i64> [[BROADCAST_SPLAT3]], +; VEC-NEXT: [[TMP1:%.*]] = add i64 [[OFFSET_IDX]], 0 +; VEC-NEXT: [[TMP2:%.*]] = getelementptr i8, i8* undef, i64 [[TMP0]] +; VEC-NEXT: [[TMP3:%.*]] = getelementptr i8, i8* [[TMP2]], i32 0 +; VEC-NEXT: [[TMP4:%.*]] = bitcast i8* [[TMP3]] to <2 x i8>* +; VEC-NEXT: [[WIDE_LOAD:%.*]] = load <2 x i8>, <2 x i8>* [[TMP4]], align 1 +; VEC-NEXT: [[TMP5:%.*]] = extractelement <2 x i1> [[BROADCAST_SPLAT6]], i32 0 +; VEC-NEXT: br i1 [[TMP5]], label [[PRED_STORE_IF:%.*]], label [[PRED_STORE_CONTINUE:%.*]] +; VEC: pred.store.if: +; VEC-NEXT: [[TMP6:%.*]] = extractelement <2 x i8> [[WIDE_LOAD]], i32 0 +; VEC-NEXT: [[TMP7:%.*]] = zext i8 [[TMP6]] to i32 +; VEC-NEXT: [[TMP8:%.*]] = trunc i32 [[TMP7]] to i8 +; VEC-NEXT: store i8 [[TMP8]], i8* [[TMP2]], align 1 +; VEC-NEXT: br label [[PRED_STORE_CONTINUE]] +; VEC: pred.store.continue: +; VEC-NEXT: [[TMP9:%.*]] = extractelement <2 x i1> [[BROADCAST_SPLAT6]], i32 1 +; VEC-NEXT: br i1 [[TMP9]], label [[PRED_STORE_IF7:%.*]], label [[PRED_STORE_CONTINUE8]] +; VEC: pred.store.if7: +; VEC-NEXT: [[TMP10:%.*]] = extractelement <2 x i8> [[WIDE_LOAD]], i32 1 +; VEC-NEXT: [[TMP11:%.*]] = zext i8 [[TMP10]] to i32 +; VEC-NEXT: [[TMP12:%.*]] = trunc i32 [[TMP11]] to i8 +; VEC-NEXT: [[TMP13:%.*]] = add i64 [[INDEX]], 1 +; VEC-NEXT: [[TMP14:%.*]] = getelementptr i8, i8* undef, i64 [[TMP13]] +; VEC-NEXT: store i8 [[TMP12]], i8* [[TMP14]], align 1 +; VEC-NEXT: br label [[PRED_STORE_CONTINUE8]] +; VEC: pred.store.continue8: +; VEC-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 2 +; VEC-NEXT: [[TMP15:%.*]] = icmp eq i64 [[INDEX_NEXT]], undef +; VEC-NEXT: br i1 [[TMP15]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop !4 +; VEC: middle.block: +; VEC-NEXT: [[CMP_N:%.*]] = icmp eq i64 undef, undef +; VEC-NEXT: br i1 [[CMP_N]], label [[FOR_END:%.*]], label [[FOR_BODY:%.*]] +; VEC: for.body: +; VEC-NEXT: [[TMP0:%.*]] = phi i64 [ [[TMP6:%.*]], [[FOR_INC:%.*]] ], [ undef, [[MIDDLE_BLOCK]] ] +; VEC-NEXT: [[TMP1:%.*]] = phi i64 [ [[TMP7:%.*]], [[FOR_INC]] ], [ undef, [[MIDDLE_BLOCK]] ] +; VEC-NEXT: [[TMP2:%.*]] = getelementptr i8, i8* undef, i64 [[TMP0]] +; VEC-NEXT: [[TMP3:%.*]] = load i8, i8* [[TMP2]], align 1 +; VEC-NEXT: br i1 [[C]], label [[IF_THEN:%.*]], label [[FOR_INC]] +; VEC: if.then: +; VEC-NEXT: [[TMP4:%.*]] = zext i8 [[TMP3]] to i32 +; VEC-NEXT: [[TMP5:%.*]] = trunc i32 [[TMP4]] to i8 +; VEC-NEXT: store i8 [[TMP5]], i8* [[TMP2]], align 1 +; VEC-NEXT: br label [[FOR_INC]] +; VEC: for.inc: +; VEC-NEXT: [[TMP6]] = add nuw nsw i64 [[TMP0]], 1 +; VEC-NEXT: [[TMP7]] = add i64 [[TMP1]], -1 +; VEC-NEXT: [[TMP8:%.*]] = icmp eq i64 [[TMP7]], 0 +; VEC-NEXT: br i1 [[TMP8]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop !5 +; VEC: for.end: +; VEC-NEXT: ret void +; entry: br label %for.body Index: test/Transforms/SimplifyCFG/PR30210.ll =================================================================== --- test/Transforms/SimplifyCFG/PR30210.ll +++ test/Transforms/SimplifyCFG/PR30210.ll @@ -1,3 +1,4 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt -S -simplifycfg < %s | FileCheck %s target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" @@ -5,6 +6,14 @@ declare i32* @fn1(i32* returned) define i32 @test1(i1 %B) { +; CHECK-LABEL: @test1( +; CHECK-NEXT: entry: +; CHECK-NEXT: br label [[FOR_COND_US:%.*]] +; CHECK: for.cond.us: +; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[B:%.*]], true +; CHECK-NEXT: call void @llvm.assume(i1 [[TMP0]]) +; CHECK-NEXT: br label [[FOR_COND_US]] +; entry: br label %for.cond.us Index: test/Transforms/SimplifyCFG/UnreachableEliminate.ll =================================================================== --- test/Transforms/SimplifyCFG/UnreachableEliminate.ll +++ test/Transforms/SimplifyCFG/UnreachableEliminate.ll @@ -1,53 +1,59 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt < %s -simplifycfg -S | FileCheck %s define void @test1(i1 %C, i1* %BP) { ; CHECK-LABEL: @test1( -; CHECK: entry: -; CHECK-NEXT: ret void +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[C:%.*]], true +; CHECK-NEXT: call void @llvm.assume(i1 [[TMP0]]) +; CHECK-NEXT: ret void +; entry: - br i1 %C, label %T, label %F + br i1 %C, label %T, label %F T: - store i1 %C, i1* %BP - unreachable + store i1 %C, i1* %BP + unreachable F: - ret void + ret void } define void @test2() personality i32 (...)* @__gxx_personality_v0 { ; CHECK-LABEL: @test2( -; CHECK: entry: -; CHECK-NEXT: call void @test2() -; CHECK-NEXT: ret void +; CHECK-NEXT: entry: +; CHECK-NEXT: call void @test2() +; CHECK-NEXT: ret void +; entry: - invoke void @test2( ) - to label %N unwind label %U + invoke void @test2( ) + to label %N unwind label %U U: %res = landingpad { i8* } - cleanup - unreachable + cleanup + unreachable N: - ret void + ret void } declare i32 @__gxx_personality_v0(...) define i32 @test3(i32 %v) { ; CHECK-LABEL: @test3( -; CHECK: entry: -; CHECK-NEXT: [[CMP:%[A-Za-z0-9]+]] = icmp eq i32 %v, 2 -; CHECK-NEXT: select i1 [[CMP]], i32 2, i32 1 -; CHECK-NEXT: ret -entry: - switch i32 %v, label %default [ - i32 1, label %U - i32 2, label %T - ] +; CHECK-NEXT: entry: +; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[V:%.*]], 2 +; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[COND]], i32 2, i32 1 +; CHECK-NEXT: ret i32 [[SPEC_SELECT]] +; +entry: + switch i32 %v, label %default [ + i32 1, label %U + i32 2, label %T + ] default: - ret i32 1 + ret i32 1 U: - unreachable + unreachable T: - ret i32 2 + ret i32 2 } @@ -56,21 +62,22 @@ ;; the latter. define void @test5(i1 %cond, i8* %ptr) { - -; CHECK-LABEL: test5 -; CHECK: entry: -; CHECK-NOT: select -; CHECK: store i8 2, i8* %ptr -; CHECK: ret +; CHECK-LABEL: @test5( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[COND:%.*]], true +; CHECK-NEXT: call void @llvm.assume(i1 [[TMP0]]) +; CHECK-NEXT: store i8 2, i8* [[PTR:%.*]], align 8 +; CHECK-NEXT: ret void +; entry: br i1 %cond, label %bb1, label %bb3 bb3: - br label %bb2 + br label %bb2 bb1: - br label %bb2 + br label %bb2 bb2: %ptr.2 = phi i8* [ %ptr, %bb3 ], [ null, %bb1 ] @@ -79,34 +86,35 @@ } define void @test5_no_null_opt(i1 %cond, i8* %ptr) #0 { - -; CHECK-LABEL: test5_no_null_opt -; CHECK: entry: -; CHECK: %[[SEL:.*]] = select i1 %cond, i8* null, i8* %ptr -; CHECK: store i8 2, i8* %[[SEL]] +; CHECK-LABEL: @test5_no_null_opt( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[DOTPTR:%.*]] = select i1 [[COND:%.*]], i8* null, i8* [[PTR:%.*]] +; CHECK-NEXT: store i8 2, i8* [[DOTPTR]], align 8 +; CHECK-NEXT: ret void +; entry: br i1 %cond, label %bb1, label %bb3 bb3: - br label %bb2 + br label %bb2 bb1: - br label %bb2 + br label %bb2 bb2: %ptr.2 = phi i8* [ %ptr, %bb3 ], [ null, %bb1 ] store i8 2, i8* %ptr.2, align 8 ret void } - -; CHECK-LABEL: test6 -; CHECK: entry: -; CHECK-NOT: select -; CHECK: store i8 2, i8* %ptr -; CHECK: ret - define void @test6(i1 %cond, i8* %ptr) { +; CHECK-LABEL: @test6( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[COND:%.*]], true +; CHECK-NEXT: call void @llvm.assume(i1 [[TMP0]]) +; CHECK-NEXT: store i8 2, i8* [[PTR:%.*]], align 8 +; CHECK-NEXT: ret void +; entry: br i1 %cond, label %bb1, label %bb2 @@ -119,12 +127,13 @@ ret void } -; CHECK-LABEL: test6_no_null_opt -; CHECK: entry: -; CHECK: %[[SEL:.*]] = select i1 %cond, i8* null, i8* %ptr -; CHECK: store i8 2, i8* %[[SEL]] - define void @test6_no_null_opt(i1 %cond, i8* %ptr) #0 { +; CHECK-LABEL: @test6_no_null_opt( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[COND:%.*]], i8* null, i8* [[PTR:%.*]] +; CHECK-NEXT: store i8 2, i8* [[SPEC_SELECT]], align 8 +; CHECK-NEXT: ret void +; entry: br i1 %cond, label %bb1, label %bb2 @@ -139,6 +148,12 @@ define i32 @test7(i1 %X) { +; CHECK-LABEL: @test7( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[X:%.*]], true +; CHECK-NEXT: call void @llvm.assume(i1 [[TMP0]]) +; CHECK-NEXT: ret i32 0 +; entry: br i1 %X, label %if, label %else @@ -150,11 +165,15 @@ %phi = phi i32 [ 0, %entry ], [ 1, %if ] ret i32 %phi } -; CHECK-LABEL: define i32 @test7( -; CHECK-NOT: call -; CHECK: ret i32 0 define void @test8(i1 %X, void ()* %Y) { +; CHECK-LABEL: @test8( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[X:%.*]], true +; CHECK-NEXT: call void @llvm.assume(i1 [[TMP0]]) +; CHECK-NEXT: call void [[Y:%.*]]() +; CHECK-NEXT: ret void +; entry: br i1 %X, label %if, label %else @@ -166,10 +185,14 @@ call void %phi() ret void } -; CHECK-LABEL: define void @test8( -; CHECK: call void %Y( define void @test8_no_null_opt(i1 %X, void ()* %Y) #0 { +; CHECK-LABEL: @test8_no_null_opt( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[X:%.*]], void ()* null, void ()* [[Y:%.*]] +; CHECK-NEXT: call void [[SPEC_SELECT]]() +; CHECK-NEXT: ret void +; entry: br i1 %X, label %if, label %else @@ -181,8 +204,5 @@ call void %phi() ret void } -attributes #0 = { "null-pointer-is-valid"="true" } -; CHECK-LABEL: define void @test8_no_null_opt( -; CHECK: %[[SEL:.*]] = select i1 %X, void ()* null, void ()* %Y -; CHECK: call void %[[SEL]] +attributes #0 = { "null-pointer-is-valid"="true" } Index: test/Transforms/SimplifyCFG/unreachable_assume.ll =================================================================== --- test/Transforms/SimplifyCFG/unreachable_assume.ll +++ test/Transforms/SimplifyCFG/unreachable_assume.ll @@ -0,0 +1,45 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt %s -simplifycfg -instcombine -S | FileCheck %s +define i32 @assume1(i32 %p) { +; CHECK-LABEL: @assume1( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[P:%.*]], 0 +; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]]) +; CHECK-NEXT: ret i32 [[P]] +; +entry: + %cmp = icmp sle i32 %p, 0 + br i1 %cmp, label %if.then, label %if.end + +if.then: + unreachable + +if.end: + %call = call i32 @abs(i32 %p) + ret i32 %call +} + + +define i32 @assume2(i32 %p) { +; CHECK-LABEL: @assume2( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[P:%.*]], 0 +; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]]) +; CHECK-NEXT: ret i32 [[P]] +; +entry: + %cmp = icmp sgt i32 %p, 0 + br i1 %cmp, label %if.then, label %if.else + +if.then: + br label %if.end + +if.else: + unreachable + +if.end: + %call = call i32 @abs(i32 %p) + ret i32 %call +} + +declare i32 @abs(i32)