diff options
Diffstat (limited to 'test/Transforms')
| -rw-r--r-- | test/Transforms/CodeGenPrepare/X86/sink-addrmode-select.ll | 19 | ||||
| -rw-r--r-- | test/Transforms/GVNHoist/pr35222-hoist-load.ll | 45 | ||||
| -rw-r--r-- | test/Transforms/JumpThreading/ddt-crash3.ll | 43 | ||||
| -rw-r--r-- | test/Transforms/JumpThreading/ddt-crash4.ll | 75 | ||||
| -rw-r--r-- | test/Transforms/LoopVectorize/pr35773.ll | 53 | ||||
| -rw-r--r-- | test/Transforms/SLPVectorizer/X86/PR35628_1.ll | 74 | ||||
| -rw-r--r-- | test/Transforms/SLPVectorizer/X86/PR35628_2.ll | 64 | ||||
| -rw-r--r-- | test/Transforms/SLPVectorizer/X86/PR35777.ll | 48 | ||||
| -rw-r--r-- | test/Transforms/SLPVectorizer/X86/PR35865.ll | 27 | ||||
| -rw-r--r-- | test/Transforms/SLPVectorizer/X86/insert-element-build-vector.ll | 220 | ||||
| -rw-r--r-- | test/Transforms/SLPVectorizer/X86/insertvalue.ll | 162 | ||||
| -rw-r--r-- | test/Transforms/SLPVectorizer/X86/value-bug.ll | 48 | ||||
| -rw-r--r-- | test/Transforms/StructurizeCFG/AMDGPU/backedge-id-bug-xfail.ll | 77 | ||||
| -rw-r--r-- | test/Transforms/StructurizeCFG/AMDGPU/backedge-id-bug.ll | 163 | ||||
| -rw-r--r-- | test/Transforms/StructurizeCFG/AMDGPU/lit.local.cfg | 2 | ||||
| -rw-r--r-- | test/Transforms/StructurizeCFG/nested-loop-order.ll | 83 |
16 files changed, 1035 insertions, 168 deletions
diff --git a/test/Transforms/CodeGenPrepare/X86/sink-addrmode-select.ll b/test/Transforms/CodeGenPrepare/X86/sink-addrmode-select.ll new file mode 100644 index 000000000000..b153a8b1e53f --- /dev/null +++ b/test/Transforms/CodeGenPrepare/X86/sink-addrmode-select.ll @@ -0,0 +1,19 @@ +; RUN: opt -S -codegenprepare -disable-complex-addr-modes=false -addr-sink-new-select=true %s | FileCheck %s --check-prefix=CHECK +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" +target triple = "x86_64-unknown-linux-gnu" + +; Select when both offset and scale reg are present. +define i64 @test1(i1 %c, i64* %b, i64 %scale) { +; CHECK-LABEL: @test1 +entry: +; CHECK-LABEL: entry: + %g = getelementptr inbounds i64, i64* %b, i64 %scale + %g1 = getelementptr inbounds i64, i64* %g, i64 8 + %g2 = getelementptr inbounds i64, i64* %g, i64 16 + %s = select i1 %c, i64* %g1, i64* %g2 +; CHECK-NOT: sunkaddr + %v = load i64 , i64* %s, align 8 + ret i64 %v +} + diff --git a/test/Transforms/GVNHoist/pr35222-hoist-load.ll b/test/Transforms/GVNHoist/pr35222-hoist-load.ll index 7e9c62006162..b9b1a870a59b 100644 --- a/test/Transforms/GVNHoist/pr35222-hoist-load.ll +++ b/test/Transforms/GVNHoist/pr35222-hoist-load.ll @@ -1,4 +1,5 @@ ; RUN: opt -S -gvn-hoist < %s | FileCheck %s +; CHECK-LABEL: build_tree ; CHECK: load ; CHECK: load ; Check that the load is not hoisted because the call can potentially @@ -23,3 +24,47 @@ do.end: ; preds = %do.body } declare i1 @pqdownheap(i32) + +@i = external hidden unnamed_addr global i32, align 4 +@j = external hidden unnamed_addr global [573 x i32], align 4 +@v = external global i1 + +; CHECK-LABEL: test +; CHECK-LABEL: do.end +; CHECK: load +; Check that the load is not hoisted because the call can potentially +; modify the global + +define i32 @test() { +entry: + br label %for.cond + +for.cond: + %a3 = load volatile i1, i1* @v + br i1 %a3, label %for.body, label %while.end + +for.body: + br label %if.then + +if.then: + %tmp4 = load i32, i32* @i, align 4 + br label %for.cond + +while.end: + br label %do.body + +do.body: + %tmp9 = load i32, i32* getelementptr inbounds ([573 x i32], [573 x i32]* @j, +i32 0, i32 1), align 4 + %tmp10 = load i32, i32* @i, align 4 + call void @fn() + %a1 = load volatile i1, i1* @v + br i1 %a1, label %do.body, label %do.end + +do.end: + %tmp20 = load i32, i32* getelementptr inbounds ([573 x i32], [573 x i32]* @j, +i32 0, i32 1), align 4 + ret i32 %tmp20 +} + +declare void @fn() diff --git a/test/Transforms/JumpThreading/ddt-crash3.ll b/test/Transforms/JumpThreading/ddt-crash3.ll new file mode 100644 index 000000000000..50ac86a3fb5b --- /dev/null +++ b/test/Transforms/JumpThreading/ddt-crash3.ll @@ -0,0 +1,43 @@ +; RUN: opt < %s -jump-threading -disable-output -verify-dom-info + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +@global = external local_unnamed_addr global i64, align 8 +@global.1 = external local_unnamed_addr global i64, align 8 +@global.2 = external local_unnamed_addr global i64, align 8 + +; Function Attrs: norecurse noreturn nounwind uwtable +define void @hoge() local_unnamed_addr #0 { +bb: + br label %bb1 + +bb1: ; preds = %bb26, %bb + %tmp = load i64, i64* @global, align 8, !tbaa !1 + %tmp2 = icmp eq i64 %tmp, 0 + br i1 %tmp2, label %bb27, label %bb3 + +bb3: ; preds = %bb1 + %tmp4 = load i64, i64* @global.1, align 8, !tbaa !1 + %tmp5 = icmp eq i64 %tmp4, 0 + br i1 %tmp5, label %bb23, label %bb23 + +bb23: ; preds = %bb3, %bb3 + br label %bb26 + +bb26: ; preds = %bb27, %bb23 + br label %bb1 + +bb27: ; preds = %bb1 + br label %bb26 +} + +attributes #0 = { norecurse noreturn nounwind uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } + +!llvm.ident = !{!0} + +!0 = !{!"clang version 7.0.0 "} +!1 = !{!2, !2, i64 0} +!2 = !{!"long", !3, i64 0} +!3 = !{!"omnipotent char", !4, i64 0} +!4 = !{!"Simple C/C++ TBAA"} diff --git a/test/Transforms/JumpThreading/ddt-crash4.ll b/test/Transforms/JumpThreading/ddt-crash4.ll new file mode 100644 index 000000000000..9bf08395d660 --- /dev/null +++ b/test/Transforms/JumpThreading/ddt-crash4.ll @@ -0,0 +1,75 @@ +; RUN: opt < %s -jump-threading -disable-output -verify-dom-info +@global = external global i64, align 8 + +define void @f() { +bb: + br label %bb1 + +bb1: + %tmp = load i64, i64* @global, align 8 + %tmp2 = icmp eq i64 %tmp, 0 + br i1 %tmp2, label %bb27, label %bb3 + +bb3: + %tmp4 = load i64, i64* @global, align 8 + %tmp5 = icmp eq i64 %tmp4, 0 + br i1 %tmp5, label %bb6, label %bb7 + +bb6: + br label %bb7 + +bb7: + %tmp8 = phi i1 [ true, %bb3 ], [ undef, %bb6 ] + %tmp9 = select i1 %tmp8, i64 %tmp4, i64 0 + br i1 false, label %bb10, label %bb23 + +bb10: + %tmp11 = load i64, i64* @global, align 8 + %tmp12 = icmp slt i64 %tmp11, 5 + br i1 %tmp12, label %bb13, label %bb17 + +bb13: + br label %bb14 + +bb14: + br i1 undef, label %bb15, label %bb16 + +bb15: + unreachable + +bb16: + br label %bb10 + +bb17: + br label %bb18 + +bb18: + br i1 undef, label %bb22, label %bb13 + +bb19: + br i1 undef, label %bb20, label %bb21 + +bb20: + unreachable + +bb21: + br label %bb18 + +bb22: + br label %bb23 + +bb23: + br i1 undef, label %bb24, label %bb13 + +bb24: + br i1 undef, label %bb26, label %bb25 + +bb25: + br label %bb19 + +bb26: + br label %bb1 + +bb27: + br label %bb24 +} diff --git a/test/Transforms/LoopVectorize/pr35773.ll b/test/Transforms/LoopVectorize/pr35773.ll new file mode 100644 index 000000000000..362ece70b898 --- /dev/null +++ b/test/Transforms/LoopVectorize/pr35773.ll @@ -0,0 +1,53 @@ +; RUN: opt -S -loop-vectorize -force-vector-width=4 -force-vector-interleave=1 < %s 2>&1 | FileCheck %s +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +@a = common local_unnamed_addr global i32 0, align 4 +@b = common local_unnamed_addr global i8 0, align 1 + +; Function Attrs: norecurse nounwind uwtable +define void @doit1() local_unnamed_addr{ +entry: + br label %for.body + +for.body: + %main.iv = phi i32 [ 0, %entry ], [ %inc, %for.body ] + + %i8.iv = phi i8 [ 0, %entry ], [ %i8.add, %for.body ] + %i32.iv = phi i32 [ 0, %entry ], [ %i32.add, %for.body ] + + %trunc.to.be.converted.to.new.iv = trunc i32 %i32.iv to i8 + %i8.add = add i8 %i8.iv, %trunc.to.be.converted.to.new.iv + + %noop.conv.under.pse = and i32 %i32.iv, 255 + %i32.add = add nuw nsw i32 %noop.conv.under.pse, 9 + + %inc = add i32 %main.iv, 1 + %tobool = icmp eq i32 %inc, 16 + br i1 %tobool, label %for.cond.for.end_crit_edge, label %for.body + +; CHECK-LABEL: @doit1( +; CHECK: vector.body: +; CHECK-NEXT: [[MAIN_IV:%.*]] = phi i32 [ 0, [[VECTOR_PH:%.*]] ], [ [[MAIN_IV_NEXT:%.*]], [[VECTOR_BODY:%.*]] ] +; CHECK-NEXT: [[I8_IV:%.*]] = phi <4 x i8> [ zeroinitializer, [[VECTOR_PH]] ], [ [[I8_IV_NEXT:%.*]], [[VECTOR_BODY]] ] +; CHECK-NEXT: [[I32_IV:%.*]] = phi <4 x i32> [ <i32 0, i32 9, i32 18, i32 27>, [[VECTOR_PH]] ], [ [[I32_IV_NEXT:%.*]], [[VECTOR_BODY]] ] +; CHECK-NEXT: [[IV_FROM_TRUNC:%.*]] = phi <4 x i8> [ <i8 0, i8 9, i8 18, i8 27>, [[VECTOR_PH]] ], [ [[IV_FROM_TRUNC_NEXT:%.*]], [[VECTOR_BODY]] ] + +; CHECK-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement <4 x i32> undef, i32 [[MAIN_IV]], i32 0 +; CHECK-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector <4 x i32> [[BROADCAST_SPLATINSERT]], <4 x i32> undef, <4 x i32> zeroinitializer +; CHECK-NEXT: [[INDUCTION:%.*]] = add <4 x i32> [[BROADCAST_SPLAT]], <i32 0, i32 1, i32 2, i32 3> +; CHECK-NEXT: [[TMP7:%.*]] = add i32 [[MAIN_IV]], 0 + +; CHECK-NEXT: [[I8_IV_NEXT]] = add <4 x i8> [[I8_IV]], [[IV_FROM_TRUNC]] + +; CHECK-NEXT: [[MAIN_IV_NEXT]] = add i32 [[MAIN_IV]], 4 +; CHECK-NEXT: [[I32_IV_NEXT]] = add <4 x i32> [[I32_IV]], <i32 36, i32 36, i32 36, i32 36> +; CHECK-NEXT: [[IV_FROM_TRUNC_NEXT]] = add <4 x i8> [[IV_FROM_TRUNC]], <i8 36, i8 36, i8 36, i8 36> +; CHECK-NEXT: [[TMP9:%.*]] = icmp eq i32 [[MAIN_IV_NEXT]], 16 +; CHECK-NEXT: br i1 [[TMP9]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop !0 + +for.cond.for.end_crit_edge: + store i8 %i8.add, i8* @b, align 1 + br label %for.end + +for.end: + ret void +} diff --git a/test/Transforms/SLPVectorizer/X86/PR35628_1.ll b/test/Transforms/SLPVectorizer/X86/PR35628_1.ll new file mode 100644 index 000000000000..a573fc911eef --- /dev/null +++ b/test/Transforms/SLPVectorizer/X86/PR35628_1.ll @@ -0,0 +1,74 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -slp-vectorizer -slp-vectorize-hor -slp-vectorize-hor-store -S < %s -mtriple=x86_64-unknown-linux-gnu | FileCheck %s +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128-ni:1" + +define void @mainTest(i32* %ptr) #0 { +; CHECK-LABEL: @mainTest( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32* [[PTR:%.*]], null +; CHECK-NEXT: br i1 [[CMP]], label [[LOOP:%.*]], label [[BAIL_OUT:%.*]] +; CHECK: loop: +; CHECK-NEXT: [[DUMMY_PHI:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ [[OP_EXTRA5:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i32, i32* [[PTR]], i64 1 +; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i32, i32* [[PTR]], i64 2 +; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i32, i32* [[PTR]], i64 3 +; CHECK-NEXT: [[TMP3:%.*]] = bitcast i32* [[PTR]] to <4 x i32>* +; CHECK-NEXT: [[TMP4:%.*]] = load <4 x i32>, <4 x i32>* [[TMP3]], align 4 +; CHECK-NEXT: [[TMP5:%.*]] = extractelement <4 x i32> [[TMP4]], i32 3 +; CHECK-NEXT: [[TMP6:%.*]] = extractelement <4 x i32> [[TMP4]], i32 2 +; CHECK-NEXT: [[TMP7:%.*]] = extractelement <4 x i32> [[TMP4]], i32 1 +; CHECK-NEXT: [[TMP8:%.*]] = mul <4 x i32> [[TMP4]], [[TMP4]] +; CHECK-NEXT: [[TMP9:%.*]] = add i32 1, undef +; CHECK-NEXT: [[TMP10:%.*]] = add i32 [[TMP9]], undef +; CHECK-NEXT: [[TMP11:%.*]] = add i32 [[TMP10]], undef +; CHECK-NEXT: [[TMP12:%.*]] = add i32 [[TMP11]], undef +; CHECK-NEXT: [[TMP13:%.*]] = add i32 [[TMP12]], undef +; CHECK-NEXT: [[TMP14:%.*]] = sext i32 [[TMP6]] to i64 +; CHECK-NEXT: [[TMP15:%.*]] = add i32 [[TMP13]], undef +; CHECK-NEXT: [[RDX_SHUF:%.*]] = shufflevector <4 x i32> [[TMP8]], <4 x i32> undef, <4 x i32> <i32 2, i32 3, i32 undef, i32 undef> +; CHECK-NEXT: [[BIN_RDX:%.*]] = add <4 x i32> [[TMP8]], [[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: [[TMP16:%.*]] = extractelement <4 x i32> [[BIN_RDX2]], i32 0 +; CHECK-NEXT: [[OP_EXTRA:%.*]] = add i32 [[TMP16]], 1 +; CHECK-NEXT: [[OP_EXTRA3:%.*]] = add i32 [[OP_EXTRA]], [[TMP7]] +; CHECK-NEXT: [[OP_EXTRA4:%.*]] = add i32 [[OP_EXTRA3]], [[TMP6]] +; CHECK-NEXT: [[OP_EXTRA5]] = add i32 [[OP_EXTRA4]], [[TMP5]] +; CHECK-NEXT: [[TMP17:%.*]] = add i32 [[TMP15]], undef +; CHECK-NEXT: br label [[LOOP]] +; CHECK: bail_out: +; CHECK-NEXT: ret void +; +entry: + %cmp = icmp eq i32* %ptr, null + br i1 %cmp, label %loop, label %bail_out + +loop: + %dummy_phi = phi i32 [ 1, %entry ], [ %18, %loop ] + %0 = load i32, i32 * %ptr , align 4 + %1 = mul i32 %0, %0 + %2 = add i32 1, %1 + %3 = getelementptr inbounds i32, i32 * %ptr, i64 1 + %4 = load i32, i32 * %3 , align 4 + %5 = mul i32 %4, %4 + %6 = add i32 %2, %4 + %7 = add i32 %6, %5 + %8 = getelementptr inbounds i32, i32 *%ptr, i64 2 + %9 = load i32, i32 * %8 , align 4 + %10 = mul i32 %9, %9 + %11 = add i32 %7, %9 + %12 = add i32 %11, %10 + %13 = sext i32 %9 to i64 + %14 = getelementptr inbounds i32, i32 *%ptr, i64 3 + %15 = load i32, i32 * %14 , align 4 + %16 = mul i32 %15, %15 + %17 = add i32 %12, %15 + %18 = add i32 %17, %16 + br label %loop + +bail_out: + ret void +} + +attributes #0 = { "target-cpu"="westmere" } + diff --git a/test/Transforms/SLPVectorizer/X86/PR35628_2.ll b/test/Transforms/SLPVectorizer/X86/PR35628_2.ll new file mode 100644 index 000000000000..52a6d73db981 --- /dev/null +++ b/test/Transforms/SLPVectorizer/X86/PR35628_2.ll @@ -0,0 +1,64 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -slp-vectorizer -slp-vectorize-hor -slp-vectorize-hor-store -S < %s -mtriple=x86_64-unknown-linux-gnu -mcpu=haswell | FileCheck %s +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128-ni:1" + +define void @test() #0 { +; CHECK-LABEL: @test( +; CHECK-NEXT: entry: +; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: loop: +; CHECK-NEXT: [[DUMMY_PHI:%.*]] = phi i64 [ 1, [[ENTRY:%.*]] ], [ [[OP_EXTRA3:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[TMP0:%.*]] = phi i64 [ 2, [[ENTRY]] ], [ [[TMP6:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[DUMMY_ADD:%.*]] = add i16 0, 0 +; CHECK-NEXT: [[TMP1:%.*]] = insertelement <4 x i64> undef, i64 [[TMP0]], i32 0 +; CHECK-NEXT: [[TMP2:%.*]] = insertelement <4 x i64> [[TMP1]], i64 [[TMP0]], i32 1 +; CHECK-NEXT: [[TMP3:%.*]] = insertelement <4 x i64> [[TMP2]], i64 [[TMP0]], i32 2 +; CHECK-NEXT: [[TMP4:%.*]] = insertelement <4 x i64> [[TMP3]], i64 [[TMP0]], i32 3 +; CHECK-NEXT: [[TMP5:%.*]] = add <4 x i64> <i64 3, i64 2, i64 1, i64 0>, [[TMP4]] +; CHECK-NEXT: [[TMP6]] = extractelement <4 x i64> [[TMP5]], i32 3 +; CHECK-NEXT: [[TMP7:%.*]] = extractelement <4 x i64> [[TMP5]], i32 0 +; CHECK-NEXT: [[DUMMY_SHL:%.*]] = shl i64 [[TMP7]], 32 +; CHECK-NEXT: [[TMP8:%.*]] = add <4 x i64> <i64 1, i64 1, i64 1, i64 1>, [[TMP5]] +; CHECK-NEXT: [[TMP9:%.*]] = ashr exact <4 x i64> [[TMP8]], <i64 32, i64 32, i64 32, i64 32> +; CHECK-NEXT: [[SUM1:%.*]] = add i64 undef, undef +; CHECK-NEXT: [[SUM2:%.*]] = add i64 [[SUM1]], undef +; CHECK-NEXT: [[ZSUM:%.*]] = add i64 [[SUM2]], 0 +; CHECK-NEXT: [[JOIN:%.*]] = add i64 undef, [[ZSUM]] +; CHECK-NEXT: [[RDX_SHUF:%.*]] = shufflevector <4 x i64> [[TMP9]], <4 x i64> undef, <4 x i32> <i32 2, i32 3, i32 undef, i32 undef> +; CHECK-NEXT: [[BIN_RDX:%.*]] = add <4 x i64> [[TMP9]], [[RDX_SHUF]] +; CHECK-NEXT: [[RDX_SHUF1:%.*]] = shufflevector <4 x i64> [[BIN_RDX]], <4 x i64> undef, <4 x i32> <i32 1, i32 undef, i32 undef, i32 undef> +; CHECK-NEXT: [[BIN_RDX2:%.*]] = add <4 x i64> [[BIN_RDX]], [[RDX_SHUF1]] +; CHECK-NEXT: [[TMP10:%.*]] = extractelement <4 x i64> [[BIN_RDX2]], i32 0 +; CHECK-NEXT: [[OP_EXTRA:%.*]] = add i64 [[TMP10]], 0 +; CHECK-NEXT: [[OP_EXTRA3]] = add i64 [[OP_EXTRA]], [[TMP6]] +; CHECK-NEXT: [[LAST:%.*]] = add i64 [[JOIN]], undef +; CHECK-NEXT: br label [[LOOP]] +; +entry: + br label %loop + +loop: + %dummy_phi = phi i64 [ 1, %entry ], [ %last, %loop ] + %0 = phi i64 [ 2, %entry ], [ %fork, %loop ] + %inc1 = add i64 %0, 1 + %inc2 = add i64 %0, 2 + %inc11 = add i64 1, %inc1 + %exact1 = ashr exact i64 %inc11, 32 + %inc3 = add i64 %0, 3 + %dummy_add = add i16 0, 0 + %inc12 = add i64 1, %inc2 + %exact2 = ashr exact i64 %inc12, 32 + %dummy_shl = shl i64 %inc3, 32 + %inc13 = add i64 1, %inc3 + %exact3 = ashr exact i64 %inc13, 32 + %fork = add i64 %0, 0 + %sum1 = add i64 %exact3, %exact2 + %sum2 = add i64 %sum1, %exact1 + %zsum = add i64 %sum2, 0 + %sext22 = add i64 1, %fork + %exact4 = ashr exact i64 %sext22, 32 + %join = add i64 %fork, %zsum + %last = add i64 %join, %exact4 + br label %loop +} + diff --git a/test/Transforms/SLPVectorizer/X86/PR35777.ll b/test/Transforms/SLPVectorizer/X86/PR35777.ll new file mode 100644 index 000000000000..f3983d716d08 --- /dev/null +++ b/test/Transforms/SLPVectorizer/X86/PR35777.ll @@ -0,0 +1,48 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt < %s -verify -slp-vectorizer -o - -S -mtriple=x86_64-apple-macosx10.13.0 | FileCheck %s + +@global = local_unnamed_addr global [6 x double] zeroinitializer, align 16 + +define { i64, i64 } @patatino(double %arg) { +; CHECK-LABEL: @patatino( +; CHECK-NEXT: bb: +; CHECK-NEXT: [[TMP0:%.*]] = load <2 x double>, <2 x double>* bitcast ([6 x double]* @global to <2 x double>*), align 16 +; CHECK-NEXT: [[TMP1:%.*]] = load <2 x double>, <2 x double>* bitcast (double* getelementptr inbounds ([6 x double], [6 x double]* @global, i64 0, i64 2) to <2 x double>*), align 16 +; CHECK-NEXT: [[TMP2:%.*]] = insertelement <2 x double> undef, double [[ARG:%.*]], i32 0 +; CHECK-NEXT: [[TMP3:%.*]] = insertelement <2 x double> [[TMP2]], double [[ARG]], i32 1 +; CHECK-NEXT: [[TMP4:%.*]] = fmul <2 x double> [[TMP3]], [[TMP1]] +; CHECK-NEXT: [[TMP5:%.*]] = fadd <2 x double> [[TMP0]], [[TMP4]] +; CHECK-NEXT: [[TMP6:%.*]] = load <2 x double>, <2 x double>* bitcast (double* getelementptr inbounds ([6 x double], [6 x double]* @global, i64 0, i64 4) to <2 x double>*), align 16 +; CHECK-NEXT: [[TMP7:%.*]] = fadd <2 x double> [[TMP6]], [[TMP5]] +; CHECK-NEXT: [[TMP8:%.*]] = fptosi <2 x double> [[TMP7]] to <2 x i32> +; CHECK-NEXT: [[TMP9:%.*]] = sext <2 x i32> [[TMP8]] to <2 x i64> +; CHECK-NEXT: [[TMP10:%.*]] = trunc <2 x i64> [[TMP9]] to <2 x i32> +; CHECK-NEXT: [[TMP11:%.*]] = extractelement <2 x i32> [[TMP10]], i32 0 +; CHECK-NEXT: [[TMP12:%.*]] = sext i32 [[TMP11]] to i64 +; CHECK-NEXT: [[TMP16:%.*]] = insertvalue { i64, i64 } undef, i64 [[TMP12]], 0 +; CHECK-NEXT: [[TMP13:%.*]] = extractelement <2 x i32> [[TMP10]], i32 1 +; CHECK-NEXT: [[TMP14:%.*]] = sext i32 [[TMP13]] to i64 +; CHECK-NEXT: [[TMP17:%.*]] = insertvalue { i64, i64 } [[TMP16]], i64 [[TMP14]], 1 +; CHECK-NEXT: ret { i64, i64 } [[TMP17]] +; +bb: + %tmp = load double, double* getelementptr inbounds ([6 x double], [6 x double]* @global, i64 0, i64 0), align 16 + %tmp1 = load double, double* getelementptr inbounds ([6 x double], [6 x double]* @global, i64 0, i64 2), align 16 + %tmp2 = fmul double %tmp1, %arg + %tmp3 = fadd double %tmp, %tmp2 + %tmp4 = load double, double* getelementptr inbounds ([6 x double], [6 x double]* @global, i64 0, i64 4), align 16 + %tmp5 = fadd double %tmp4, %tmp3 + %tmp6 = fptosi double %tmp5 to i32 + %tmp7 = sext i32 %tmp6 to i64 + %tmp8 = load double, double* getelementptr inbounds ([6 x double], [6 x double]* @global, i64 0, i64 1), align 8 + %tmp9 = load double, double* getelementptr inbounds ([6 x double], [6 x double]* @global, i64 0, i64 3), align 8 + %tmp10 = fmul double %tmp9, %arg + %tmp11 = fadd double %tmp8, %tmp10 + %tmp12 = load double, double* getelementptr inbounds ([6 x double], [6 x double]* @global, i64 0, i64 5), align 8 + %tmp13 = fadd double %tmp12, %tmp11 + %tmp14 = fptosi double %tmp13 to i32 + %tmp15 = sext i32 %tmp14 to i64 + %tmp16 = insertvalue { i64, i64 } undef, i64 %tmp7, 0 + %tmp17 = insertvalue { i64, i64 } %tmp16, i64 %tmp15, 1 + ret { i64, i64 } %tmp17 +} diff --git a/test/Transforms/SLPVectorizer/X86/PR35865.ll b/test/Transforms/SLPVectorizer/X86/PR35865.ll new file mode 100644 index 000000000000..b022dd7d9155 --- /dev/null +++ b/test/Transforms/SLPVectorizer/X86/PR35865.ll @@ -0,0 +1,27 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -slp-vectorizer < %s -S -o - -mtriple=x86_64-apple-macosx10.10.0 -mcpu=core2 | FileCheck %s + +define void @_Z10fooConvertPDv4_xS0_S0_PKS_() { +; CHECK-LABEL: @_Z10fooConvertPDv4_xS0_S0_PKS_( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = extractelement <16 x half> undef, i32 4 +; CHECK-NEXT: [[CONV_I_4_I:%.*]] = fpext half [[TMP0]] to float +; CHECK-NEXT: [[TMP1:%.*]] = bitcast float [[CONV_I_4_I]] to i32 +; CHECK-NEXT: [[VECINS_I_4_I:%.*]] = insertelement <8 x i32> undef, i32 [[TMP1]], i32 4 +; CHECK-NEXT: [[TMP2:%.*]] = extractelement <16 x half> undef, i32 5 +; CHECK-NEXT: [[CONV_I_5_I:%.*]] = fpext half [[TMP2]] to float +; CHECK-NEXT: [[TMP3:%.*]] = bitcast float [[CONV_I_5_I]] to i32 +; CHECK-NEXT: [[VECINS_I_5_I:%.*]] = insertelement <8 x i32> [[VECINS_I_4_I]], i32 [[TMP3]], i32 5 +; CHECK-NEXT: ret void +; +entry: + %0 = extractelement <16 x half> undef, i32 4 + %conv.i.4.i = fpext half %0 to float + %1 = bitcast float %conv.i.4.i to i32 + %vecins.i.4.i = insertelement <8 x i32> undef, i32 %1, i32 4 + %2 = extractelement <16 x half> undef, i32 5 + %conv.i.5.i = fpext half %2 to float + %3 = bitcast float %conv.i.5.i to i32 + %vecins.i.5.i = insertelement <8 x i32> %vecins.i.4.i, i32 %3, i32 5 + ret void +} diff --git a/test/Transforms/SLPVectorizer/X86/insert-element-build-vector.ll b/test/Transforms/SLPVectorizer/X86/insert-element-build-vector.ll index 46386e8b63e0..750a44736c97 100644 --- a/test/Transforms/SLPVectorizer/X86/insert-element-build-vector.ll +++ b/test/Transforms/SLPVectorizer/X86/insert-element-build-vector.ll @@ -7,8 +7,8 @@ target triple = "x86_64-apple-macosx10.8.0" define <4 x float> @simple_select(<4 x float> %a, <4 x float> %b, <4 x i32> %c) #0 { ; CHECK-LABEL: @simple_select( -; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <4 x i32> %c, zeroinitializer -; CHECK-NEXT: [[TMP2:%.*]] = select <4 x i1> [[TMP1]], <4 x float> %a, <4 x float> %b +; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <4 x i32> [[C:%.*]], zeroinitializer +; CHECK-NEXT: [[TMP2:%.*]] = select <4 x i1> [[TMP1]], <4 x float> [[A:%.*]], <4 x float> [[B:%.*]] ; CHECK-NEXT: [[TMP3:%.*]] = extractelement <4 x float> [[TMP2]], i32 0 ; CHECK-NEXT: [[RA:%.*]] = insertelement <4 x float> undef, float [[TMP3]], i32 0 ; CHECK-NEXT: [[TMP4:%.*]] = extractelement <4 x float> [[TMP2]], i32 1 @@ -20,8 +20,8 @@ define <4 x float> @simple_select(<4 x float> %a, <4 x float> %b, <4 x i32> %c) ; CHECK-NEXT: ret <4 x float> [[RD]] ; ; ZEROTHRESH-LABEL: @simple_select( -; ZEROTHRESH-NEXT: [[TMP1:%.*]] = icmp ne <4 x i32> %c, zeroinitializer -; ZEROTHRESH-NEXT: [[TMP2:%.*]] = select <4 x i1> [[TMP1]], <4 x float> %a, <4 x float> %b +; ZEROTHRESH-NEXT: [[TMP1:%.*]] = icmp ne <4 x i32> [[C:%.*]], zeroinitializer +; ZEROTHRESH-NEXT: [[TMP2:%.*]] = select <4 x i1> [[TMP1]], <4 x float> [[A:%.*]], <4 x float> [[B:%.*]] ; ZEROTHRESH-NEXT: [[TMP3:%.*]] = extractelement <4 x float> [[TMP2]], i32 0 ; ZEROTHRESH-NEXT: [[RA:%.*]] = insertelement <4 x float> undef, float [[TMP3]], i32 0 ; ZEROTHRESH-NEXT: [[TMP4:%.*]] = extractelement <4 x float> [[TMP2]], i32 1 @@ -64,18 +64,18 @@ declare void @llvm.assume(i1) nounwind ; This entire tree is ephemeral, don't vectorize any of it. define <4 x float> @simple_select_eph(<4 x float> %a, <4 x float> %b, <4 x i32> %c) #0 { ; CHECK-LABEL: @simple_select_eph( -; CHECK-NEXT: [[C0:%.*]] = extractelement <4 x i32> %c, i32 0 -; CHECK-NEXT: [[C1:%.*]] = extractelement <4 x i32> %c, i32 1 -; CHECK-NEXT: [[C2:%.*]] = extractelement <4 x i32> %c, i32 2 -; CHECK-NEXT: [[C3:%.*]] = extractelement <4 x i32> %c, i32 3 -; CHECK-NEXT: [[A0:%.*]] = extractelement <4 x float> %a, i32 0 -; CHECK-NEXT: [[A1:%.*]] = extractelement <4 x float> %a, i32 1 -; CHECK-NEXT: [[A2:%.*]] = extractelement <4 x float> %a, i32 2 -; CHECK-NEXT: [[A3:%.*]] = extractelement <4 x float> %a, i32 3 -; CHECK-NEXT: [[B0:%.*]] = extractelement <4 x float> %b, i32 0 -; CHECK-NEXT: [[B1:%.*]] = extractelement <4 x float> %b, i32 1 -; CHECK-NEXT: [[B2:%.*]] = extractelement <4 x float> %b, i32 2 -; CHECK-NEXT: [[B3:%.*]] = extractelement <4 x float> %b, i32 3 +; CHECK-NEXT: [[C0:%.*]] = extractelement <4 x i32> [[C:%.*]], i32 0 +; CHECK-NEXT: [[C1:%.*]] = extractelement <4 x i32> [[C]], i32 1 +; CHECK-NEXT: [[C2:%.*]] = extractelement <4 x i32> [[C]], i32 2 +; CHECK-NEXT: [[C3:%.*]] = extractelement <4 x i32> [[C]], i32 3 +; CHECK-NEXT: [[A0:%.*]] = extractelement <4 x float> [[A:%.*]], i32 0 +; CHECK-NEXT: [[A1:%.*]] = extractelement <4 x float> [[A]], i32 1 +; CHECK-NEXT: [[A2:%.*]] = extractelement <4 x float> [[A]], i32 2 +; CHECK-NEXT: [[A3:%.*]] = extractelement <4 x float> [[A]], i32 3 +; CHECK-NEXT: [[B0:%.*]] = extractelement <4 x float> [[B:%.*]], i32 0 +; CHECK-NEXT: [[B1:%.*]] = extractelement <4 x float> [[B]], i32 1 +; CHECK-NEXT: [[B2:%.*]] = extractelement <4 x float> [[B]], i32 2 +; CHECK-NEXT: [[B3:%.*]] = extractelement <4 x float> [[B]], i32 3 ; CHECK-NEXT: [[CMP0:%.*]] = icmp ne i32 [[C0]], 0 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i32 [[C1]], 0 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i32 [[C2]], 0 @@ -100,18 +100,18 @@ define <4 x float> @simple_select_eph(<4 x float> %a, <4 x float> %b, <4 x i32> ; CHECK-NEXT: ret <4 x float> undef ; ; ZEROTHRESH-LABEL: @simple_select_eph( -; ZEROTHRESH-NEXT: [[C0:%.*]] = extractelement <4 x i32> %c, i32 0 -; ZEROTHRESH-NEXT: [[C1:%.*]] = extractelement <4 x i32> %c, i32 1 -; ZEROTHRESH-NEXT: [[C2:%.*]] = extractelement <4 x i32> %c, i32 2 -; ZEROTHRESH-NEXT: [[C3:%.*]] = extractelement <4 x i32> %c, i32 3 -; ZEROTHRESH-NEXT: [[A0:%.*]] = extractelement <4 x float> %a, i32 0 -; ZEROTHRESH-NEXT: [[A1:%.*]] = extractelement <4 x float> %a, i32 1 -; ZEROTHRESH-NEXT: [[A2:%.*]] = extractelement <4 x float> %a, i32 2 -; ZEROTHRESH-NEXT: [[A3:%.*]] = extractelement <4 x float> %a, i32 3 -; ZEROTHRESH-NEXT: [[B0:%.*]] = extractelement <4 x float> %b, i32 0 -; ZEROTHRESH-NEXT: [[B1:%.*]] = extractelement <4 x float> %b, i32 1 -; ZEROTHRESH-NEXT: [[B2:%.*]] = extractelement <4 x float> %b, i32 2 -; ZEROTHRESH-NEXT: [[B3:%.*]] = extractelement <4 x float> %b, i32 3 +; ZEROTHRESH-NEXT: [[C0:%.*]] = extractelement <4 x i32> [[C:%.*]], i32 0 +; ZEROTHRESH-NEXT: [[C1:%.*]] = extractelement <4 x i32> [[C]], i32 1 +; ZEROTHRESH-NEXT: [[C2:%.*]] = extractelement <4 x i32> [[C]], i32 2 +; ZEROTHRESH-NEXT: [[C3:%.*]] = extractelement <4 x i32> [[C]], i32 3 +; ZEROTHRESH-NEXT: [[A0:%.*]] = extractelement <4 x float> [[A:%.*]], i32 0 +; ZEROTHRESH-NEXT: [[A1:%.*]] = extractelement <4 x float> [[A]], i32 1 +; ZEROTHRESH-NEXT: [[A2:%.*]] = extractelement <4 x float> [[A]], i32 2 +; ZEROTHRESH-NEXT: [[A3:%.*]] = extractelement <4 x float> [[A]], i32 3 +; ZEROTHRESH-NEXT: [[B0:%.*]] = extractelement <4 x float> [[B:%.*]], i32 0 +; ZEROTHRESH-NEXT: [[B1:%.*]] = extractelement <4 x float> [[B]], i32 1 +; ZEROTHRESH-NEXT: [[B2:%.*]] = extractelement <4 x float> [[B]], i32 2 +; ZEROTHRESH-NEXT: [[B3:%.*]] = extractelement <4 x float> [[B]], i32 3 ; ZEROTHRESH-NEXT: [[CMP0:%.*]] = icmp ne i32 [[C0]], 0 ; ZEROTHRESH-NEXT: [[CMP1:%.*]] = icmp ne i32 [[C1]], 0 ; ZEROTHRESH-NEXT: [[CMP2:%.*]] = icmp ne i32 [[C2]], 0 @@ -175,8 +175,8 @@ define <4 x float> @simple_select_eph(<4 x float> %a, <4 x float> %b, <4 x i32> ; doesn't matter define <4 x float> @simple_select_insert_out_of_order(<4 x float> %a, <4 x float> %b, <4 x i32> %c) #0 { ; CHECK-LABEL: @simple_select_insert_out_of_order( -; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <4 x i32> %c, zeroinitializer -; CHECK-NEXT: [[TMP2:%.*]] = select <4 x i1> [[TMP1]], <4 x float> %a, <4 x float> %b +; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <4 x i32> [[C:%.*]], zeroinitializer +; CHECK-NEXT: [[TMP2:%.*]] = select <4 x i1> [[TMP1]], <4 x float> [[A:%.*]], <4 x float> [[B:%.*]] ; CHECK-NEXT: [[TMP3:%.*]] = extractelement <4 x float> [[TMP2]], i32 0 ; CHECK-NEXT: [[RA:%.*]] = insertelement <4 x float> undef, float [[TMP3]], i32 2 ; CHECK-NEXT: [[TMP4:%.*]] = extractelement <4 x float> [[TMP2]], i32 1 @@ -188,8 +188,8 @@ define <4 x float> @simple_select_insert_out_of_order(<4 x float> %a, <4 x float ; CHECK-NEXT: ret <4 x float> [[RD]] ; ; ZEROTHRESH-LABEL: @simple_select_insert_out_of_order( -; ZEROTHRESH-NEXT: [[TMP1:%.*]] = icmp ne <4 x i32> %c, zeroinitializer -; ZEROTHRESH-NEXT: [[TMP2:%.*]] = select <4 x i1> [[TMP1]], <4 x float> %a, <4 x float> %b +; ZEROTHRESH-NEXT: [[TMP1:%.*]] = icmp ne <4 x i32> [[C:%.*]], zeroinitializer +; ZEROTHRESH-NEXT: [[TMP2:%.*]] = select <4 x i1> [[TMP1]], <4 x float> [[A:%.*]], <4 x float> [[B:%.*]] ; ZEROTHRESH-NEXT: [[TMP3:%.*]] = extractelement <4 x float> [[TMP2]], i32 0 ; ZEROTHRESH-NEXT: [[RA:%.*]] = insertelement <4 x float> undef, float [[TMP3]], i32 2 ; ZEROTHRESH-NEXT: [[TMP4:%.*]] = extractelement <4 x float> [[TMP2]], i32 1 @@ -233,8 +233,8 @@ declare void @f32_user(float) #0 ; Multiple users of the final constructed vector define <4 x float> @simple_select_users(<4 x float> %a, <4 x float> %b, <4 x i32> %c) #0 { ; CHECK-LABEL: @simple_select_users( -; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <4 x i32> %c, zeroinitializer -; CHECK-NEXT: [[TMP2:%.*]] = select <4 x i1> [[TMP1]], <4 x float> %a, <4 x float> %b +; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <4 x i32> [[C:%.*]], zeroinitializer +; CHECK-NEXT: [[TMP2:%.*]] = select <4 x i1> [[TMP1]], <4 x float> [[A:%.*]], <4 x float> [[B:%.*]] ; CHECK-NEXT: [[TMP3:%.*]] = extractelement <4 x float> [[TMP2]], i32 0 ; CHECK-NEXT: [[RA:%.*]] = insertelement <4 x float> undef, float [[TMP3]], i32 0 ; CHECK-NEXT: [[TMP4:%.*]] = extractelement <4 x float> [[TMP2]], i32 1 @@ -247,8 +247,8 @@ define <4 x float> @simple_select_users(<4 x float> %a, <4 x float> %b, <4 x i32 ; CHECK-NEXT: ret <4 x float> [[RD]] ; ; ZEROTHRESH-LABEL: @simple_select_users( -; ZEROTHRESH-NEXT: [[TMP1:%.*]] = icmp ne <4 x i32> %c, zeroinitializer -; ZEROTHRESH-NEXT: [[TMP2:%.*]] = select <4 x i1> [[TMP1]], <4 x float> %a, <4 x float> %b +; ZEROTHRESH-NEXT: [[TMP1:%.*]] = icmp ne <4 x i32> [[C:%.*]], zeroinitializer +; ZEROTHRESH-NEXT: [[TMP2:%.*]] = select <4 x i1> [[TMP1]], <4 x float> [[A:%.*]], <4 x float> [[B:%.*]] ; ZEROTHRESH-NEXT: [[TMP3:%.*]] = extractelement <4 x float> [[TMP2]], i32 0 ; ZEROTHRESH-NEXT: [[RA:%.*]] = insertelement <4 x float> undef, float [[TMP3]], i32 0 ; ZEROTHRESH-NEXT: [[TMP4:%.*]] = extractelement <4 x float> [[TMP2]], i32 1 @@ -291,18 +291,18 @@ define <4 x float> @simple_select_users(<4 x float> %a, <4 x float> %b, <4 x i32 ; Unused insertelement define <4 x float> @simple_select_no_users(<4 x float> %a, <4 x float> %b, <4 x i32> %c) #0 { ; CHECK-LABEL: @simple_select_no_users( -; CHECK-NEXT: [[C0:%.*]] = extractelement <4 x i32> %c, i32 0 -; CHECK-NEXT: [[C1:%.*]] = extractelement <4 x i32> %c, i32 1 -; CHECK-NEXT: [[C2:%.*]] = extractelement <4 x i32> %c, i32 2 -; CHECK-NEXT: [[C3:%.*]] = extractelement <4 x i32> %c, i32 3 -; CHECK-NEXT: [[A0:%.*]] = extractelement <4 x float> %a, i32 0 -; CHECK-NEXT: [[A1:%.*]] = extractelement <4 x float> %a, i32 1 -; CHECK-NEXT: [[A2:%.*]] = extractelement <4 x float> %a, i32 2 -; CHECK-NEXT: [[A3:%.*]] = extractelement <4 x float> %a, i32 3 -; CHECK-NEXT: [[B0:%.*]] = extractelement <4 x float> %b, i32 0 -; CHECK-NEXT: [[B1:%.*]] = extractelement <4 x float> %b, i32 1 -; CHECK-NEXT: [[B2:%.*]] = extractelement <4 x float> %b, i32 2 -; CHECK-NEXT: [[B3:%.*]] = extractelement <4 x float> %b, i32 3 +; CHECK-NEXT: [[C0:%.*]] = extractelement <4 x i32> [[C:%.*]], i32 0 +; CHECK-NEXT: [[C1:%.*]] = extractelement <4 x i32> [[C]], i32 1 +; CHECK-NEXT: [[C2:%.*]] = extractelement <4 x i32> [[C]], i32 2 +; CHECK-NEXT: [[C3:%.*]] = extractelement <4 x i32> [[C]], i32 3 +; CHECK-NEXT: [[A0:%.*]] = extractelement <4 x float> [[A:%.*]], i32 0 +; CHECK-NEXT: [[A1:%.*]] = extractelement <4 x float> [[A]], i32 1 +; CHECK-NEXT: [[A2:%.*]] = extractelement <4 x float> [[A]], i32 2 +; CHECK-NEXT: [[A3:%.*]] = extractelement <4 x float> [[A]], i32 3 +; CHECK-NEXT: [[B0:%.*]] = extractelement <4 x float> [[B:%.*]], i32 0 +; CHECK-NEXT: [[B1:%.*]] = extractelement <4 x float> [[B]], i32 1 +; CHECK-NEXT: [[B2:%.*]] = extractelement <4 x float> [[B]], i32 2 +; CHECK-NEXT: [[B3:%.*]] = extractelement <4 x float> [[B]], i32 3 ; CHECK-NEXT: [[TMP1:%.*]] = insertelement <2 x i32> undef, i32 [[C0]], i32 0 ; CHECK-NEXT: [[TMP2:%.*]] = insertelement <2 x i32> [[TMP1]], i32 [[C1]], i32 1 ; CHECK-NEXT: [[TMP3:%.*]] = icmp ne <2 x i32> [[TMP2]], zeroinitializer @@ -330,18 +330,18 @@ define <4 x float> @simple_select_no_users(<4 x float> %a, <4 x float> %b, <4 x ; CHECK-NEXT: ret <4 x float> [[RD]] ; ; ZEROTHRESH-LABEL: @simple_select_no_users( -; ZEROTHRESH-NEXT: [[C0:%.*]] = extractelement <4 x i32> %c, i32 0 -; ZEROTHRESH-NEXT: [[C1:%.*]] = extractelement <4 x i32> %c, i32 1 -; ZEROTHRESH-NEXT: [[C2:%.*]] = extractelement <4 x i32> %c, i32 2 -; ZEROTHRESH-NEXT: [[C3:%.*]] = extractelement <4 x i32> %c, i32 3 -; ZEROTHRESH-NEXT: [[A0:%.*]] = extractelement <4 x float> %a, i32 0 -; ZEROTHRESH-NEXT: [[A1:%.*]] = extractelement <4 x float> %a, i32 1 -; ZEROTHRESH-NEXT: [[A2:%.*]] = extractelement <4 x float> %a, i32 2 -; ZEROTHRESH-NEXT: [[A3:%.*]] = extractelement <4 x float> %a, i32 3 -; ZEROTHRESH-NEXT: [[B0:%.*]] = extractelement <4 x float> %b, i32 0 -; ZEROTHRESH-NEXT: [[B1:%.*]] = extractelement <4 x float> %b, i32 1 -; ZEROTHRESH-NEXT: [[B2:%.*]] = extractelement <4 x float> %b, i32 2 -; ZEROTHRESH-NEXT: [[B3:%.*]] = extractelement <4 x float> %b, i32 3 +; ZEROTHRESH-NEXT: [[C0:%.*]] = extractelement <4 x i32> [[C:%.*]], i32 0 +; ZEROTHRESH-NEXT: [[C1:%.*]] = extractelement <4 x i32> [[C]], i32 1 +; ZEROTHRESH-NEXT: [[C2:%.*]] = extractelement <4 x i32> [[C]], i32 2 +; ZEROTHRESH-NEXT: [[C3:%.*]] = extractelement <4 x i32> [[C]], i32 3 +; ZEROTHRESH-NEXT: [[A0:%.*]] = extractelement <4 x float> [[A:%.*]], i32 0 +; ZEROTHRESH-NEXT: [[A1:%.*]] = extractelement <4 x float> [[A]], i32 1 +; ZEROTHRESH-NEXT: [[A2:%.*]] = extractelement <4 x float> [[A]], i32 2 +; ZEROTHRESH-NEXT: [[A3:%.*]] = extractelement <4 x float> [[A]], i32 3 +; ZEROTHRESH-NEXT: [[B0:%.*]] = extractelement <4 x float> [[B:%.*]], i32 0 +; ZEROTHRESH-NEXT: [[B1:%.*]] = extractelement <4 x float> [[B]], i32 1 +; ZEROTHRESH-NEXT: [[B2:%.*]] = extractelement <4 x float> [[B]], i32 2 +; ZEROTHRESH-NEXT: [[B3:%.*]] = extractelement <4 x float> [[B]], i32 3 ; ZEROTHRESH-NEXT: [[CMP0:%.*]] = icmp ne i32 [[C0]], 0 ; ZEROTHRESH-NEXT: [[CMP1:%.*]] = icmp ne i32 [[C1]], 0 ; ZEROTHRESH-NEXT: [[CMP2:%.*]] = icmp ne i32 [[C2]], 0 @@ -387,25 +387,25 @@ define <4 x float> @simple_select_no_users(<4 x float> %a, <4 x float> %b, <4 x ; to do this backwards this backwards define <4 x i32> @reconstruct(<4 x i32> %c) #0 { ; CHECK-LABEL: @reconstruct( -; CHECK-NEXT: [[TMP1:%.*]] = extractelement <4 x i32> %c, i32 0 -; CHECK-NEXT: [[RA:%.*]] = insertelement <4 x i32> undef, i32 [[TMP1]], i32 0 -; CHECK-NEXT: [[TMP2:%.*]] = extractelement <4 x i32> %c, i32 1 -; CHECK-NEXT: [[RB:%.*]] = insertelement <4 x i32> [[RA]], i32 [[TMP2]], i32 1 -; CHECK-NEXT: [[TMP3:%.*]] = extractelement <4 x i32> %c, i32 2 -; CHECK-NEXT: [[RC:%.*]] = insertelement <4 x i32> [[RB]], i32 [[TMP3]], i32 2 -; CHECK-NEXT: [[TMP4:%.*]] = extractelement <4 x i32> %c, i32 3 -; CHECK-NEXT: [[RD:%.*]] = insertelement <4 x i32> [[RC]], i32 [[TMP4]], i32 3 +; CHECK-NEXT: [[TMP1:%.*]] = extractelement <4 x i32> [[C:%.*]], i32 3 +; CHECK-NEXT: [[TMP2:%.*]] = extractelement <4 x i32> [[C]], i32 2 +; CHECK-NEXT: [[TMP3:%.*]] = extractelement <4 x i32> [[C]], i32 1 +; CHECK-NEXT: [[TMP4:%.*]] = extractelement <4 x i32> [[C]], i32 0 +; CHECK-NEXT: [[RA:%.*]] = insertelement <4 x i32> undef, i32 [[TMP4]], i32 0 +; CHECK-NEXT: [[RB:%.*]] = insertelement <4 x i32> [[RA]], i32 [[TMP3]], i32 1 +; CHECK-NEXT: [[RC:%.*]] = insertelement <4 x i32> [[RB]], i32 [[TMP2]], i32 2 +; CHECK-NEXT: [[RD:%.*]] = insertelement <4 x i32> [[RC]], i32 [[TMP1]], i32 3 ; CHECK-NEXT: ret <4 x i32> [[RD]] ; ; ZEROTHRESH-LABEL: @reconstruct( -; ZEROTHRESH-NEXT: [[TMP1:%.*]] = extractelement <4 x i32> %c, i32 0 -; ZEROTHRESH-NEXT: [[RA:%.*]] = insertelement <4 x i32> undef, i32 [[TMP1]], i32 0 -; ZEROTHRESH-NEXT: [[TMP2:%.*]] = extractelement <4 x i32> %c, i32 1 -; ZEROTHRESH-NEXT: [[RB:%.*]] = insertelement <4 x i32> [[RA]], i32 [[TMP2]], i32 1 -; ZEROTHRESH-NEXT: [[TMP3:%.*]] = extractelement <4 x i32> %c, i32 2 -; ZEROTHRESH-NEXT: [[RC:%.*]] = insertelement <4 x i32> [[RB]], i32 [[TMP3]], i32 2 -; ZEROTHRESH-NEXT: [[TMP4:%.*]] = extractelement <4 x i32> %c, i32 3 -; ZEROTHRESH-NEXT: [[RD:%.*]] = insertelement <4 x i32> [[RC]], i32 [[TMP4]], i32 3 +; ZEROTHRESH-NEXT: [[C0:%.*]] = extractelement <4 x i32> [[C:%.*]], i32 0 +; ZEROTHRESH-NEXT: [[C1:%.*]] = extractelement <4 x i32> [[C]], i32 1 +; ZEROTHRESH-NEXT: [[C2:%.*]] = extractelement <4 x i32> [[C]], i32 2 +; ZEROTHRESH-NEXT: [[C3:%.*]] = extractelement <4 x i32> [[C]], i32 3 +; ZEROTHRESH-NEXT: [[RA:%.*]] = insertelement <4 x i32> undef, i32 [[C0]], i32 0 +; ZEROTHRESH-NEXT: [[RB:%.*]] = insertelement <4 x i32> [[RA]], i32 [[C1]], i32 1 +; ZEROTHRESH-NEXT: [[RC:%.*]] = insertelement <4 x i32> [[RB]], i32 [[C2]], i32 2 +; ZEROTHRESH-NEXT: [[RD:%.*]] = insertelement <4 x i32> [[RC]], i32 [[C3]], i32 3 ; ZEROTHRESH-NEXT: ret <4 x i32> [[RD]] ; %c0 = extractelement <4 x i32> %c, i32 0 @@ -421,8 +421,8 @@ define <4 x i32> @reconstruct(<4 x i32> %c) #0 { define <2 x float> @simple_select_v2(<2 x float> %a, <2 x float> %b, <2 x i32> %c) #0 { ; CHECK-LABEL: @simple_select_v2( -; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <2 x i32> %c, zeroinitializer -; CHECK-NEXT: [[TMP2:%.*]] = select <2 x i1> [[TMP1]], <2 x float> %a, <2 x float> %b +; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <2 x i32> [[C:%.*]], zeroinitializer +; CHECK-NEXT: [[TMP2:%.*]] = select <2 x i1> [[TMP1]], <2 x float> [[A:%.*]], <2 x float> [[B:%.*]] ; CHECK-NEXT: [[TMP3:%.*]] = extractelement <2 x float> [[TMP2]], i32 0 ; CHECK-NEXT: [[RA:%.*]] = insertelement <2 x float> undef, float [[TMP3]], i32 0 ; CHECK-NEXT: [[TMP4:%.*]] = extractelement <2 x float> [[TMP2]], i32 1 @@ -430,12 +430,12 @@ define <2 x float> @simple_select_v2(<2 x float> %a, <2 x float> %b, <2 x i32> % ; CHECK-NEXT: ret <2 x float> [[RB]] ; ; ZEROTHRESH-LABEL: @simple_select_v2( -; ZEROTHRESH-NEXT: [[C0:%.*]] = extractelement <2 x i32> %c, i32 0 -; ZEROTHRESH-NEXT: [[C1:%.*]] = extractelement <2 x i32> %c, i32 1 -; ZEROTHRESH-NEXT: [[A0:%.*]] = extractelement <2 x float> %a, i32 0 -; ZEROTHRESH-NEXT: [[A1:%.*]] = extractelement <2 x float> %a, i32 1 -; ZEROTHRESH-NEXT: [[B0:%.*]] = extractelement <2 x float> %b, i32 0 -; ZEROTHRESH-NEXT: [[B1:%.*]] = extractelement <2 x float> %b, i32 1 +; ZEROTHRESH-NEXT: [[C0:%.*]] = extractelement <2 x i32> [[C:%.*]], i32 0 +; ZEROTHRESH-NEXT: [[C1:%.*]] = extractelement <2 x i32> [[C]], i32 1 +; ZEROTHRESH-NEXT: [[A0:%.*]] = extractelement <2 x float> [[A:%.*]], i32 0 +; ZEROTHRESH-NEXT: [[A1:%.*]] = extractelement <2 x float> [[A]], i32 1 +; ZEROTHRESH-NEXT: [[B0:%.*]] = extractelement <2 x float> [[B:%.*]], i32 0 +; ZEROTHRESH-NEXT: [[B1:%.*]] = extractelement <2 x float> [[B]], i32 1 ; ZEROTHRESH-NEXT: [[CMP0:%.*]] = icmp ne i32 [[C0]], 0 ; ZEROTHRESH-NEXT: [[CMP1:%.*]] = icmp ne i32 [[C1]], 0 ; ZEROTHRESH-NEXT: [[S0:%.*]] = select i1 [[CMP0]], float [[A0]], float [[B0]] @@ -464,12 +464,12 @@ define <2 x float> @simple_select_v2(<2 x float> %a, <2 x float> %b, <2 x i32> % ; (low cost threshold needed to force this to happen) define <4 x float> @simple_select_partial_vector(<4 x float> %a, <4 x float> %b, <4 x i32> %c) #0 { ; CHECK-LABEL: @simple_select_partial_vector( -; CHECK-NEXT: [[C0:%.*]] = extractelement <4 x i32> %c, i32 0 -; CHECK-NEXT: [[C1:%.*]] = extractelement <4 x i32> %c, i32 1 -; CHECK-NEXT: [[A0:%.*]] = extractelement <4 x float> %a, i32 0 -; CHECK-NEXT: [[A1:%.*]] = extractelement <4 x float> %a, i32 1 -; CHECK-NEXT: [[B0:%.*]] = extractelement <4 x float> %b, i32 0 -; CHECK-NEXT: [[B1:%.*]] = extractelement <4 x float> %b, i32 1 +; CHECK-NEXT: [[C0:%.*]] = extractelement <4 x i32> [[C:%.*]], i32 0 +; CHECK-NEXT: [[C1:%.*]] = extractelement <4 x i32> [[C]], i32 1 +; CHECK-NEXT: [[A0:%.*]] = extractelement <4 x float> [[A:%.*]], i32 0 +; CHECK-NEXT: [[A1:%.*]] = extractelement <4 x float> [[A]], i32 1 +; CHECK-NEXT: [[B0:%.*]] = extractelement <4 x float> [[B:%.*]], i32 0 +; CHECK-NEXT: [[B1:%.*]] = extractelement <4 x float> [[B]], i32 1 ; CHECK-NEXT: [[TMP1:%.*]] = insertelement <2 x i32> undef, i32 [[C0]], i32 0 ; CHECK-NEXT: [[TMP2:%.*]] = insertelement <2 x i32> [[TMP1]], i32 [[C1]], i32 1 ; CHECK-NEXT: [[TMP3:%.*]] = icmp ne <2 x i32> [[TMP2]], zeroinitializer @@ -485,12 +485,12 @@ define <4 x float> @simple_select_partial_vector(<4 x float> %a, <4 x float> %b, ; CHECK-NEXT: ret <4 x float> [[RB]] ; ; ZEROTHRESH-LABEL: @simple_select_partial_vector( -; ZEROTHRESH-NEXT: [[C0:%.*]] = extractelement <4 x i32> %c, i32 0 -; ZEROTHRESH-NEXT: [[C1:%.*]] = extractelement <4 x i32> %c, i32 1 -; ZEROTHRESH-NEXT: [[A0:%.*]] = extractelement <4 x float> %a, i32 0 -; ZEROTHRESH-NEXT: [[A1:%.*]] = extractelement <4 x float> %a, i32 1 -; ZEROTHRESH-NEXT: [[B0:%.*]] = extractelement <4 x float> %b, i32 0 -; ZEROTHRESH-NEXT: [[B1:%.*]] = extractelement <4 x float> %b, i32 1 +; ZEROTHRESH-NEXT: [[C0:%.*]] = extractelement <4 x i32> [[C:%.*]], i32 0 +; ZEROTHRESH-NEXT: [[C1:%.*]] = extractelement <4 x i32> [[C]], i32 1 +; ZEROTHRESH-NEXT: [[A0:%.*]] = extractelement <4 x float> [[A:%.*]], i32 0 +; ZEROTHRESH-NEXT: [[A1:%.*]] = extractelement <4 x float> [[A]], i32 1 +; ZEROTHRESH-NEXT: [[B0:%.*]] = extractelement <4 x float> [[B:%.*]], i32 0 +; ZEROTHRESH-NEXT: [[B1:%.*]] = extractelement <4 x float> [[B]], i32 1 ; ZEROTHRESH-NEXT: [[TMP1:%.*]] = insertelement <2 x i32> undef, i32 [[C0]], i32 0 ; ZEROTHRESH-NEXT: [[TMP2:%.*]] = insertelement <2 x i32> [[TMP1]], i32 [[C1]], i32 1 ; ZEROTHRESH-NEXT: [[TMP3:%.*]] = icmp ne <2 x i32> [[TMP2]], zeroinitializer @@ -530,7 +530,7 @@ define <4 x float> @simple_select_partial_vector(<4 x float> %a, <4 x float> %b, ; must be rescheduled. The case here is from compiling Julia. define <4 x float> @reschedule_extract(<4 x float> %a, <4 x float> %b) { ; CHECK-LABEL: @reschedule_extract( -; CHECK-NEXT: [[TMP1:%.*]] = fadd <4 x float> %a, %b +; CHECK-NEXT: [[TMP1:%.*]] = fadd <4 x float> [[A:%.*]], [[B:%.*]] ; CHECK-NEXT: [[TMP2:%.*]] = extractelement <4 x float> [[TMP1]], i32 0 ; CHECK-NEXT: [[V0:%.*]] = insertelement <4 x float> undef, float [[TMP2]], i32 0 ; CHECK-NEXT: [[TMP3:%.*]] = extractelement <4 x float> [[TMP1]], i32 1 @@ -542,7 +542,7 @@ define <4 x float> @reschedule_extract(<4 x float> %a, <4 x float> %b) { ; CHECK-NEXT: ret <4 x float> [[V3]] ; ; ZEROTHRESH-LABEL: @reschedule_extract( -; ZEROTHRESH-NEXT: [[TMP1:%.*]] = fadd <4 x float> %a, %b +; ZEROTHRESH-NEXT: [[TMP1:%.*]] = fadd <4 x float> [[A:%.*]], [[B:%.*]] ; ZEROTHRESH-NEXT: [[TMP2:%.*]] = extractelement <4 x float> [[TMP1]], i32 0 ; ZEROTHRESH-NEXT: [[V0:%.*]] = insertelement <4 x float> undef, float [[TMP2]], i32 0 ; ZEROTHRESH-NEXT: [[TMP3:%.*]] = extractelement <4 x float> [[TMP1]], i32 1 @@ -576,7 +576,7 @@ define <4 x float> @reschedule_extract(<4 x float> %a, <4 x float> %b) { ; instructions that are erased. define <4 x float> @take_credit(<4 x float> %a, <4 x float> %b) { ; CHECK-LABEL: @take_credit( -; CHECK-NEXT: [[TMP1:%.*]] = fadd <4 x float> %a, %b +; CHECK-NEXT: [[TMP1:%.*]] = fadd <4 x float> [[A:%.*]], [[B:%.*]] ; CHECK-NEXT: [[TMP2:%.*]] = extractelement <4 x float> [[TMP1]], i32 0 ; CHECK-NEXT: [[V0:%.*]] = insertelement <4 x float> undef, float [[TMP2]], i32 0 ; CHECK-NEXT: [[TMP3:%.*]] = extractelement <4 x float> [[TMP1]], i32 1 @@ -588,7 +588,7 @@ define <4 x float> @take_credit(<4 x float> %a, <4 x float> %b) { ; CHECK-NEXT: ret <4 x float> [[V3]] ; ; ZEROTHRESH-LABEL: @take_credit( -; ZEROTHRESH-NEXT: [[TMP1:%.*]] = fadd <4 x float> %a, %b +; ZEROTHRESH-NEXT: [[TMP1:%.*]] = fadd <4 x float> [[A:%.*]], [[B:%.*]] ; ZEROTHRESH-NEXT: [[TMP2:%.*]] = extractelement <4 x float> [[TMP1]], i32 0 ; ZEROTHRESH-NEXT: [[V0:%.*]] = insertelement <4 x float> undef, float [[TMP2]], i32 0 ; ZEROTHRESH-NEXT: [[TMP3:%.*]] = extractelement <4 x float> [[TMP1]], i32 1 @@ -622,10 +622,10 @@ define <4 x float> @take_credit(<4 x float> %a, <4 x float> %b) { define <4 x double> @multi_tree(double %w, double %x, double %y, double %z) { ; CHECK-LABEL: @multi_tree( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[TMP0:%.*]] = insertelement <4 x double> undef, double %w, i32 0 -; CHECK-NEXT: [[TMP1:%.*]] = insertelement <4 x double> [[TMP0]], double %x, i32 1 -; CHECK-NEXT: [[TMP2:%.*]] = insertelement <4 x double> [[TMP1]], double %y, i32 2 -; CHECK-NEXT: [[TMP3:%.*]] = insertelement <4 x double> [[TMP2]], double %z, i32 3 +; CHECK-NEXT: [[TMP0:%.*]] = insertelement <4 x double> undef, double [[W:%.*]], i32 0 +; CHECK-NEXT: [[TMP1:%.*]] = insertelement <4 x double> [[TMP0]], double [[X:%.*]], i32 1 +; CHECK-NEXT: [[TMP2:%.*]] = insertelement <4 x double> [[TMP1]], double [[Y:%.*]], i32 2 +; CHECK-NEXT: [[TMP3:%.*]] = insertelement <4 x double> [[TMP2]], double [[Z:%.*]], i32 3 ; CHECK-NEXT: [[TMP4:%.*]] = fadd <4 x double> [[TMP3]], <double 0.000000e+00, double 1.000000e+00, double 2.000000e+00, double 3.000000e+00> ; CHECK-NEXT: [[TMP5:%.*]] = fmul <4 x double> <double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00>, [[TMP4]] ; CHECK-NEXT: [[TMP6:%.*]] = extractelement <4 x double> [[TMP5]], i32 0 @@ -640,10 +640,10 @@ define <4 x double> @multi_tree(double %w, double %x, double %y, double %z) { ; ; ZEROTHRESH-LABEL: @multi_tree( ; ZEROTHRESH-NEXT: entry: -; ZEROTHRESH-NEXT: [[TMP0:%.*]] = insertelement <4 x double> undef, double %w, i32 0 -; ZEROTHRESH-NEXT: [[TMP1:%.*]] = insertelement <4 x double> [[TMP0]], double %x, i32 1 -; ZEROTHRESH-NEXT: [[TMP2:%.*]] = insertelement <4 x double> [[TMP1]], double %y, i32 2 -; ZEROTHRESH-NEXT: [[TMP3:%.*]] = insertelement <4 x double> [[TMP2]], double %z, i32 3 +; ZEROTHRESH-NEXT: [[TMP0:%.*]] = insertelement <4 x double> undef, double [[W:%.*]], i32 0 +; ZEROTHRESH-NEXT: [[TMP1:%.*]] = insertelement <4 x double> [[TMP0]], double [[X:%.*]], i32 1 +; ZEROTHRESH-NEXT: [[TMP2:%.*]] = insertelement <4 x double> [[TMP1]], double [[Y:%.*]], i32 2 +; ZEROTHRESH-NEXT: [[TMP3:%.*]] = insertelement <4 x double> [[TMP2]], double [[Z:%.*]], i32 3 ; ZEROTHRESH-NEXT: [[TMP4:%.*]] = fadd <4 x double> [[TMP3]], <double 0.000000e+00, double 1.000000e+00, double 2.000000e+00, double 3.000000e+00> ; ZEROTHRESH-NEXT: [[TMP5:%.*]] = fmul <4 x double> <double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00>, [[TMP4]] ; ZEROTHRESH-NEXT: [[TMP6:%.*]] = extractelement <4 x double> [[TMP5]], i32 0 @@ -675,7 +675,7 @@ entry: define <8 x float> @_vadd256(<8 x float> %a, <8 x float> %b) local_unnamed_addr #0 { ; CHECK-LABEL: @_vadd256( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[TMP0:%.*]] = fadd <8 x float> %a, %b +; CHECK-NEXT: [[TMP0:%.*]] = fadd <8 x float> [[A:%.*]], [[B:%.*]] ; CHECK-NEXT: [[TMP1:%.*]] = extractelement <8 x float> [[TMP0]], i32 0 ; CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <8 x float> undef, float [[TMP1]], i32 0 ; CHECK-NEXT: [[TMP2:%.*]] = extractelement <8 x float> [[TMP0]], i32 1 @@ -696,7 +696,7 @@ define <8 x float> @_vadd256(<8 x float> %a, <8 x float> %b) local_unnamed_addr ; ; ZEROTHRESH-LABEL: @_vadd256( ; ZEROTHRESH-NEXT: entry: -; ZEROTHRESH-NEXT: [[TMP0:%.*]] = fadd <8 x float> %a, %b +; ZEROTHRESH-NEXT: [[TMP0:%.*]] = fadd <8 x float> [[A:%.*]], [[B:%.*]] ; ZEROTHRESH-NEXT: [[TMP1:%.*]] = extractelement <8 x float> [[TMP0]], i32 0 ; ZEROTHRESH-NEXT: [[VECINIT_I:%.*]] = insertelement <8 x float> undef, float [[TMP1]], i32 0 ; ZEROTHRESH-NEXT: [[TMP2:%.*]] = extractelement <8 x float> [[TMP0]], i32 1 diff --git a/test/Transforms/SLPVectorizer/X86/insertvalue.ll b/test/Transforms/SLPVectorizer/X86/insertvalue.ll index 5884ee7a2675..1af11609fe6f 100644 --- a/test/Transforms/SLPVectorizer/X86/insertvalue.ll +++ b/test/Transforms/SLPVectorizer/X86/insertvalue.ll @@ -1,11 +1,30 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt < %s -basicaa -slp-vectorizer -S -mtriple=x86_64-unknown-linux-gnu -mcpu=corei7-avx | FileCheck %s -; CHECK-LABEL: julia_2xdouble -; CHECK: load <2 x double> -; CHECK: load <2 x double> -; CHECK: fmul <2 x double> -; CHECK: fadd <2 x double> define void @julia_2xdouble([2 x double]* sret, [2 x double]*, [2 x double]*, [2 x double]*) { +; CHECK-LABEL: @julia_2xdouble( +; CHECK-NEXT: top: +; CHECK-NEXT: [[PX0:%.*]] = getelementptr inbounds [2 x double], [2 x double]* [[TMP2:%.*]], i64 0, i64 0 +; CHECK-NEXT: [[PY0:%.*]] = getelementptr inbounds [2 x double], [2 x double]* [[TMP3:%.*]], i64 0, i64 0 +; CHECK-NEXT: [[PX1:%.*]] = getelementptr inbounds [2 x double], [2 x double]* [[TMP2]], i64 0, i64 1 +; CHECK-NEXT: [[TMP4:%.*]] = bitcast double* [[PX0]] to <2 x double>* +; CHECK-NEXT: [[TMP5:%.*]] = load <2 x double>, <2 x double>* [[TMP4]], align 4 +; CHECK-NEXT: [[PY1:%.*]] = getelementptr inbounds [2 x double], [2 x double]* [[TMP3]], i64 0, i64 1 +; CHECK-NEXT: [[TMP6:%.*]] = bitcast double* [[PY0]] to <2 x double>* +; CHECK-NEXT: [[TMP7:%.*]] = load <2 x double>, <2 x double>* [[TMP6]], align 4 +; CHECK-NEXT: [[TMP8:%.*]] = fmul <2 x double> [[TMP5]], [[TMP7]] +; CHECK-NEXT: [[PZ0:%.*]] = getelementptr inbounds [2 x double], [2 x double]* [[TMP1:%.*]], i64 0, i64 0 +; CHECK-NEXT: [[PZ1:%.*]] = getelementptr inbounds [2 x double], [2 x double]* [[TMP1]], i64 0, i64 1 +; CHECK-NEXT: [[TMP9:%.*]] = bitcast double* [[PZ0]] to <2 x double>* +; CHECK-NEXT: [[TMP10:%.*]] = load <2 x double>, <2 x double>* [[TMP9]], align 4 +; CHECK-NEXT: [[TMP11:%.*]] = fadd <2 x double> [[TMP8]], [[TMP10]] +; CHECK-NEXT: [[TMP12:%.*]] = extractelement <2 x double> [[TMP11]], i32 0 +; CHECK-NEXT: [[I0:%.*]] = insertvalue [2 x double] undef, double [[TMP12]], 0 +; CHECK-NEXT: [[TMP13:%.*]] = extractelement <2 x double> [[TMP11]], i32 1 +; CHECK-NEXT: [[I1:%.*]] = insertvalue [2 x double] [[I0]], double [[TMP13]], 1 +; CHECK-NEXT: store [2 x double] [[I1]], [2 x double]* [[TMP0:%.*]], align 4 +; CHECK-NEXT: ret void +; top: %px0 = getelementptr inbounds [2 x double], [2 x double]* %2, i64 0, i64 0 %x0 = load double, double* %px0, align 4 @@ -29,12 +48,40 @@ top: ret void } -; CHECK-LABEL: julia_4xfloat -; CHECK: load <4 x float> -; CHECK: load <4 x float> -; CHECK: fmul <4 x float> -; CHECK: fadd <4 x float> define void @julia_4xfloat([4 x float]* sret, [4 x float]*, [4 x float]*, [4 x float]*) { +; CHECK-LABEL: @julia_4xfloat( +; CHECK-NEXT: top: +; CHECK-NEXT: [[PX0:%.*]] = getelementptr inbounds [4 x float], [4 x float]* [[TMP2:%.*]], i64 0, i64 0 +; CHECK-NEXT: [[PY0:%.*]] = getelementptr inbounds [4 x float], [4 x float]* [[TMP3:%.*]], i64 0, i64 0 +; CHECK-NEXT: [[PX1:%.*]] = getelementptr inbounds [4 x float], [4 x float]* [[TMP2]], i64 0, i64 1 +; CHECK-NEXT: [[PY1:%.*]] = getelementptr inbounds [4 x float], [4 x float]* [[TMP3]], i64 0, i64 1 +; CHECK-NEXT: [[PX2:%.*]] = getelementptr inbounds [4 x float], [4 x float]* [[TMP2]], i64 0, i64 2 +; CHECK-NEXT: [[PY2:%.*]] = getelementptr inbounds [4 x float], [4 x float]* [[TMP3]], i64 0, i64 2 +; CHECK-NEXT: [[PX3:%.*]] = getelementptr inbounds [4 x float], [4 x float]* [[TMP2]], i64 0, i64 3 +; CHECK-NEXT: [[TMP4:%.*]] = bitcast float* [[PX0]] to <4 x float>* +; CHECK-NEXT: [[TMP5:%.*]] = load <4 x float>, <4 x float>* [[TMP4]], align 4 +; CHECK-NEXT: [[PY3:%.*]] = getelementptr inbounds [4 x float], [4 x float]* [[TMP3]], i64 0, i64 3 +; CHECK-NEXT: [[TMP6:%.*]] = bitcast float* [[PY0]] to <4 x float>* +; CHECK-NEXT: [[TMP7:%.*]] = load <4 x float>, <4 x float>* [[TMP6]], align 4 +; CHECK-NEXT: [[TMP8:%.*]] = fmul <4 x float> [[TMP5]], [[TMP7]] +; CHECK-NEXT: [[PZ0:%.*]] = getelementptr inbounds [4 x float], [4 x float]* [[TMP1:%.*]], i64 0, i64 0 +; CHECK-NEXT: [[PZ1:%.*]] = getelementptr inbounds [4 x float], [4 x float]* [[TMP1]], i64 0, i64 1 +; CHECK-NEXT: [[PZ2:%.*]] = getelementptr inbounds [4 x float], [4 x float]* [[TMP1]], i64 0, i64 2 +; CHECK-NEXT: [[PZ3:%.*]] = getelementptr inbounds [4 x float], [4 x float]* [[TMP1]], i64 0, i64 3 +; CHECK-NEXT: [[TMP9:%.*]] = bitcast float* [[PZ0]] to <4 x float>* +; CHECK-NEXT: [[TMP10:%.*]] = load <4 x float>, <4 x float>* [[TMP9]], align 4 +; CHECK-NEXT: [[TMP11:%.*]] = fadd <4 x float> [[TMP8]], [[TMP10]] +; CHECK-NEXT: [[TMP12:%.*]] = extractelement <4 x float> [[TMP11]], i32 0 +; CHECK-NEXT: [[I0:%.*]] = insertvalue [4 x float] undef, float [[TMP12]], 0 +; CHECK-NEXT: [[TMP13:%.*]] = extractelement <4 x float> [[TMP11]], i32 1 +; CHECK-NEXT: [[I1:%.*]] = insertvalue [4 x float] [[I0]], float [[TMP13]], 1 +; CHECK-NEXT: [[TMP14:%.*]] = extractelement <4 x float> [[TMP11]], i32 2 +; CHECK-NEXT: [[I2:%.*]] = insertvalue [4 x float] [[I1]], float [[TMP14]], 2 +; CHECK-NEXT: [[TMP15:%.*]] = extractelement <4 x float> [[TMP11]], i32 3 +; CHECK-NEXT: [[I3:%.*]] = insertvalue [4 x float] [[I2]], float [[TMP15]], 3 +; CHECK-NEXT: store [4 x float] [[I3]], [4 x float]* [[TMP0:%.*]], align 4 +; CHECK-NEXT: ret void +; top: %px0 = getelementptr inbounds [4 x float], [4 x float]* %2, i64 0, i64 0 %x0 = load float, float* %px0, align 4 @@ -76,9 +123,27 @@ top: ret void } -; CHECK-LABEL: julia_load_array_of_float -; CHECK: fsub <4 x float> define void @julia_load_array_of_float([4 x float]* %a, [4 x float]* %b, [4 x float]* %c) { +; CHECK-LABEL: @julia_load_array_of_float( +; CHECK-NEXT: top: +; CHECK-NEXT: [[TMP0:%.*]] = bitcast [4 x float]* [[A:%.*]] to <4 x float>* +; CHECK-NEXT: [[TMP1:%.*]] = load <4 x float>, <4 x float>* [[TMP0]], align 4 +; CHECK-NEXT: [[A_ARR:%.*]] = load [4 x float], [4 x float]* [[A]], align 4 +; CHECK-NEXT: [[TMP2:%.*]] = bitcast [4 x float]* [[B:%.*]] to <4 x float>* +; CHECK-NEXT: [[TMP3:%.*]] = load <4 x float>, <4 x float>* [[TMP2]], align 4 +; CHECK-NEXT: [[B_ARR:%.*]] = load [4 x float], [4 x float]* [[B]], align 4 +; CHECK-NEXT: [[TMP4:%.*]] = fsub <4 x float> [[TMP1]], [[TMP3]] +; CHECK-NEXT: [[TMP5:%.*]] = extractelement <4 x float> [[TMP4]], i32 0 +; CHECK-NEXT: [[C_ARR0:%.*]] = insertvalue [4 x float] undef, float [[TMP5]], 0 +; CHECK-NEXT: [[TMP6:%.*]] = extractelement <4 x float> [[TMP4]], i32 1 +; CHECK-NEXT: [[C_ARR1:%.*]] = insertvalue [4 x float] [[C_ARR0]], float [[TMP6]], 1 +; CHECK-NEXT: [[TMP7:%.*]] = extractelement <4 x float> [[TMP4]], i32 2 +; CHECK-NEXT: [[C_ARR2:%.*]] = insertvalue [4 x float] [[C_ARR1]], float [[TMP7]], 2 +; CHECK-NEXT: [[TMP8:%.*]] = extractelement <4 x float> [[TMP4]], i32 3 +; CHECK-NEXT: [[C_ARR3:%.*]] = insertvalue [4 x float] [[C_ARR2]], float [[TMP8]], 3 +; CHECK-NEXT: store [4 x float] [[C_ARR3]], [4 x float]* [[C:%.*]], align 4 +; CHECK-NEXT: ret void +; top: %a_arr = load [4 x float], [4 x float]* %a, align 4 %a0 = extractvalue [4 x float] %a_arr, 0 @@ -102,11 +167,27 @@ top: ret void } -; CHECK-LABEL: julia_load_array_of_i32 -; CHECK: load <4 x i32> -; CHECK: load <4 x i32> -; CHECK: sub <4 x i32> define void @julia_load_array_of_i32([4 x i32]* %a, [4 x i32]* %b, [4 x i32]* %c) { +; CHECK-LABEL: @julia_load_array_of_i32( +; CHECK-NEXT: top: +; CHECK-NEXT: [[TMP0:%.*]] = bitcast [4 x i32]* [[A:%.*]] to <4 x i32>* +; CHECK-NEXT: [[TMP1:%.*]] = load <4 x i32>, <4 x i32>* [[TMP0]], align 4 +; CHECK-NEXT: [[A_ARR:%.*]] = load [4 x i32], [4 x i32]* [[A]], align 4 +; CHECK-NEXT: [[TMP2:%.*]] = bitcast [4 x i32]* [[B:%.*]] to <4 x i32>* +; CHECK-NEXT: [[TMP3:%.*]] = load <4 x i32>, <4 x i32>* [[TMP2]], align 4 +; CHECK-NEXT: [[B_ARR:%.*]] = load [4 x i32], [4 x i32]* [[B]], align 4 +; CHECK-NEXT: [[TMP4:%.*]] = sub <4 x i32> [[TMP1]], [[TMP3]] +; CHECK-NEXT: [[TMP5:%.*]] = extractelement <4 x i32> [[TMP4]], i32 0 +; CHECK-NEXT: [[C_ARR0:%.*]] = insertvalue [4 x i32] undef, i32 [[TMP5]], 0 +; CHECK-NEXT: [[TMP6:%.*]] = extractelement <4 x i32> [[TMP4]], i32 1 +; CHECK-NEXT: [[C_ARR1:%.*]] = insertvalue [4 x i32] [[C_ARR0]], i32 [[TMP6]], 1 +; CHECK-NEXT: [[TMP7:%.*]] = extractelement <4 x i32> [[TMP4]], i32 2 +; CHECK-NEXT: [[C_ARR2:%.*]] = insertvalue [4 x i32] [[C_ARR1]], i32 [[TMP7]], 2 +; CHECK-NEXT: [[TMP8:%.*]] = extractelement <4 x i32> [[TMP4]], i32 3 +; CHECK-NEXT: [[C_ARR3:%.*]] = insertvalue [4 x i32] [[C_ARR2]], i32 [[TMP8]], 3 +; CHECK-NEXT: store [4 x i32] [[C_ARR3]], [4 x i32]* [[C:%.*]], align 4 +; CHECK-NEXT: ret void +; top: %a_arr = load [4 x i32], [4 x i32]* %a, align 4 %a0 = extractvalue [4 x i32] %a_arr, 0 @@ -132,9 +213,30 @@ top: ; Almost identical to previous test, but for type that should NOT be vectorized. ; -; CHECK-LABEL: julia_load_array_of_i16 -; CHECK-NOT: i2> define void @julia_load_array_of_i16([4 x i16]* %a, [4 x i16]* %b, [4 x i16]* %c) { +; CHECK-LABEL: @julia_load_array_of_i16( +; CHECK-NEXT: top: +; CHECK-NEXT: [[A_ARR:%.*]] = load [4 x i16], [4 x i16]* [[A:%.*]], align 4 +; CHECK-NEXT: [[A0:%.*]] = extractvalue [4 x i16] [[A_ARR]], 0 +; CHECK-NEXT: [[A2:%.*]] = extractvalue [4 x i16] [[A_ARR]], 2 +; CHECK-NEXT: [[A1:%.*]] = extractvalue [4 x i16] [[A_ARR]], 1 +; CHECK-NEXT: [[B_ARR:%.*]] = load [4 x i16], [4 x i16]* [[B:%.*]], align 4 +; CHECK-NEXT: [[B0:%.*]] = extractvalue [4 x i16] [[B_ARR]], 0 +; CHECK-NEXT: [[B2:%.*]] = extractvalue [4 x i16] [[B_ARR]], 2 +; CHECK-NEXT: [[B1:%.*]] = extractvalue [4 x i16] [[B_ARR]], 1 +; CHECK-NEXT: [[A3:%.*]] = extractvalue [4 x i16] [[A_ARR]], 3 +; CHECK-NEXT: [[C1:%.*]] = sub i16 [[A1]], [[B1]] +; CHECK-NEXT: [[B3:%.*]] = extractvalue [4 x i16] [[B_ARR]], 3 +; CHECK-NEXT: [[C0:%.*]] = sub i16 [[A0]], [[B0]] +; CHECK-NEXT: [[C2:%.*]] = sub i16 [[A2]], [[B2]] +; CHECK-NEXT: [[C_ARR0:%.*]] = insertvalue [4 x i16] undef, i16 [[C0]], 0 +; CHECK-NEXT: [[C_ARR1:%.*]] = insertvalue [4 x i16] [[C_ARR0]], i16 [[C1]], 1 +; CHECK-NEXT: [[C3:%.*]] = sub i16 [[A3]], [[B3]] +; CHECK-NEXT: [[C_ARR2:%.*]] = insertvalue [4 x i16] [[C_ARR1]], i16 [[C2]], 2 +; CHECK-NEXT: [[C_ARR3:%.*]] = insertvalue [4 x i16] [[C_ARR2]], i16 [[C3]], 3 +; CHECK-NEXT: store [4 x i16] [[C_ARR3]], [4 x i16]* [[C:%.*]], align 4 +; CHECK-NEXT: ret void +; top: %a_arr = load [4 x i16], [4 x i16]* %a, align 4 %a0 = extractvalue [4 x i16] %a_arr, 0 @@ -160,11 +262,27 @@ top: %pseudovec = type { float, float, float, float } -; CHECK-LABEL: julia_load_struct_of_float -; CHECK: load <4 x float> -; CHECK: load <4 x float> -; CHECK: fsub <4 x float> define void @julia_load_struct_of_float(%pseudovec* %a, %pseudovec* %b, %pseudovec* %c) { +; CHECK-LABEL: @julia_load_struct_of_float( +; CHECK-NEXT: top: +; CHECK-NEXT: [[TMP0:%.*]] = bitcast %pseudovec* [[A:%.*]] to <4 x float>* +; CHECK-NEXT: [[TMP1:%.*]] = load <4 x float>, <4 x float>* [[TMP0]], align 4 +; CHECK-NEXT: [[A_STRUCT:%.*]] = load [[PSEUDOVEC:%.*]], %pseudovec* [[A]], align 4 +; CHECK-NEXT: [[TMP2:%.*]] = bitcast %pseudovec* [[B:%.*]] to <4 x float>* +; CHECK-NEXT: [[TMP3:%.*]] = load <4 x float>, <4 x float>* [[TMP2]], align 4 +; CHECK-NEXT: [[B_STRUCT:%.*]] = load [[PSEUDOVEC]], %pseudovec* [[B]], align 4 +; CHECK-NEXT: [[TMP4:%.*]] = fsub <4 x float> [[TMP1]], [[TMP3]] +; CHECK-NEXT: [[TMP5:%.*]] = extractelement <4 x float> [[TMP4]], i32 0 +; CHECK-NEXT: [[C_STRUCT0:%.*]] = insertvalue [[PSEUDOVEC]] undef, float [[TMP5]], 0 +; CHECK-NEXT: [[TMP6:%.*]] = extractelement <4 x float> [[TMP4]], i32 1 +; CHECK-NEXT: [[C_STRUCT1:%.*]] = insertvalue [[PSEUDOVEC]] %c_struct0, float [[TMP6]], 1 +; CHECK-NEXT: [[TMP7:%.*]] = extractelement <4 x float> [[TMP4]], i32 2 +; CHECK-NEXT: [[C_STRUCT2:%.*]] = insertvalue [[PSEUDOVEC]] %c_struct1, float [[TMP7]], 2 +; CHECK-NEXT: [[TMP8:%.*]] = extractelement <4 x float> [[TMP4]], i32 3 +; CHECK-NEXT: [[C_STRUCT3:%.*]] = insertvalue [[PSEUDOVEC]] %c_struct2, float [[TMP8]], 3 +; CHECK-NEXT: store [[PSEUDOVEC]] %c_struct3, %pseudovec* [[C:%.*]], align 4 +; CHECK-NEXT: ret void +; top: %a_struct = load %pseudovec, %pseudovec* %a, align 4 %a0 = extractvalue %pseudovec %a_struct, 0 diff --git a/test/Transforms/SLPVectorizer/X86/value-bug.ll b/test/Transforms/SLPVectorizer/X86/value-bug.ll index 64d2ae1c7d79..7558c724a15d 100644 --- a/test/Transforms/SLPVectorizer/X86/value-bug.ll +++ b/test/Transforms/SLPVectorizer/X86/value-bug.ll @@ -1,15 +1,46 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt -slp-vectorizer < %s -S -mtriple="x86_64-grtev3-linux-gnu" -mcpu=corei7-avx | FileCheck %s target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" -target triple = "x86_64-grtev3-linux-gnu" ; We used to crash on this example because we were building a constant ; expression during vectorization and the vectorizer expects instructions ; as elements of the vectorized tree. -; CHECK-LABEL: @test ; PR19621 define void @test() { +; CHECK-LABEL: @test( +; CHECK-NEXT: bb279: +; CHECK-NEXT: br label [[BB283:%.*]] +; CHECK: bb283: +; CHECK-NEXT: [[TMP0:%.*]] = phi <2 x float> [ undef, [[BB279:%.*]] ], [ [[TMP11:%.*]], [[EXIT:%.*]] ] +; CHECK-NEXT: [[TMP1:%.*]] = phi <2 x float> [ undef, [[BB279]] ], [ [[TMP13:%.*]], [[EXIT]] ] +; CHECK-NEXT: br label [[BB284:%.*]] +; CHECK: bb284: +; CHECK-NEXT: [[TMP2:%.*]] = fpext <2 x float> [[TMP0]] to <2 x double> +; CHECK-NEXT: [[TMP3:%.*]] = fsub <2 x double> [[TMP2]], undef +; CHECK-NEXT: [[TMP4:%.*]] = fsub <2 x double> [[TMP3]], undef +; CHECK-NEXT: br label [[BB21_I:%.*]] +; CHECK: bb21.i: +; CHECK-NEXT: br i1 undef, label [[BB22_I:%.*]], label [[EXIT]] +; CHECK: bb22.i: +; CHECK-NEXT: [[TMP5:%.*]] = fadd <2 x double> undef, [[TMP4]] +; CHECK-NEXT: br label [[BB32_I:%.*]] +; CHECK: bb32.i: +; CHECK-NEXT: [[TMP6:%.*]] = phi <2 x double> [ [[TMP5]], [[BB22_I]] ], [ zeroinitializer, [[BB32_I]] ] +; CHECK-NEXT: br i1 undef, label [[BB32_I]], label [[BB21_I]] +; CHECK: exit: +; CHECK-NEXT: [[TMP7:%.*]] = fpext <2 x float> [[TMP1]] to <2 x double> +; CHECK-NEXT: [[TMP8:%.*]] = fmul <2 x double> <double undef, double 0.000000e+00>, [[TMP7]] +; CHECK-NEXT: [[TMP9:%.*]] = fadd <2 x double> undef, [[TMP8]] +; CHECK-NEXT: [[TMP10:%.*]] = fadd <2 x double> undef, [[TMP9]] +; CHECK-NEXT: [[TMP11]] = fptrunc <2 x double> [[TMP10]] to <2 x float> +; CHECK-NEXT: [[TMP317:%.*]] = fptrunc double undef to float +; CHECK-NEXT: [[TMP319:%.*]] = fptrunc double undef to float +; CHECK-NEXT: [[TMP12:%.*]] = insertelement <2 x float> undef, float [[TMP317]], i32 0 +; CHECK-NEXT: [[TMP13]] = insertelement <2 x float> [[TMP12]], float [[TMP319]], i32 1 +; CHECK-NEXT: br label [[BB283]] +; bb279: br label %bb283 @@ -62,6 +93,12 @@ exit: ; vectorizer starts at the type (%t2, %t3) and wil constant fold the tree. ; The code that handles insertelement instructions must handle this. define <4 x double> @constant_folding() { +; CHECK-LABEL: @constant_folding( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[I1:%.*]] = insertelement <4 x double> undef, double 1.000000e+00, i32 1 +; CHECK-NEXT: [[I2:%.*]] = insertelement <4 x double> [[I1]], double 2.000000e+00, i32 0 +; CHECK-NEXT: ret <4 x double> [[I2]] +; entry: %t0 = fadd double 1.000000e+00 , 0.000000e+00 %t1 = fadd double 1.000000e+00 , 1.000000e+00 @@ -71,10 +108,3 @@ entry: %i2 = insertelement <4 x double> %i1, double %t3, i32 0 ret <4 x double> %i2 } - -; CHECK-LABEL: @constant_folding -; CHECK: %[[V0:.+]] = extractelement <2 x double> <double 1.000000e+00, double 2.000000e+00>, i32 0 -; CHECK: %[[V1:.+]] = insertelement <4 x double> undef, double %[[V0]], i32 1 -; CHECK: %[[V2:.+]] = extractelement <2 x double> <double 1.000000e+00, double 2.000000e+00>, i32 1 -; CHECK: %[[V3:.+]] = insertelement <4 x double> %[[V1]], double %[[V2]], i32 0 -; CHECK: ret <4 x double> %[[V3]] diff --git a/test/Transforms/StructurizeCFG/AMDGPU/backedge-id-bug-xfail.ll b/test/Transforms/StructurizeCFG/AMDGPU/backedge-id-bug-xfail.ll new file mode 100644 index 000000000000..e9c54151cf29 --- /dev/null +++ b/test/Transforms/StructurizeCFG/AMDGPU/backedge-id-bug-xfail.ll @@ -0,0 +1,77 @@ +; XFAIL: * +; RUN: opt -mtriple=amdgcn-amd-amdhsa -S -structurizecfg -verify-region-info %s + +; FIXME: Merge into backedge-id-bug +; Variant which has an issue with region construction + +define amdgpu_kernel void @loop_backedge_misidentified_alt(i32 addrspace(1)* %arg0) #0 { +entry: + %tmp = load volatile <2 x i32>, <2 x i32> addrspace(1)* undef, align 16 + %load1 = load volatile <2 x float>, <2 x float> addrspace(1)* undef + %tid = call i32 @llvm.amdgcn.workitem.id.x() + %gep = getelementptr inbounds i32, i32 addrspace(1)* %arg0, i32 %tid + %i.initial = load volatile i32, i32 addrspace(1)* %gep, align 4 + br label %LOOP.HEADER + +LOOP.HEADER: + %i = phi i32 [ %i.final, %END_ELSE_BLOCK ], [ %i.initial, %entry ] + call void asm sideeffect "s_nop 0x100b ; loop $0 ", "r,~{memory}"(i32 %i) #0 + %tmp12 = zext i32 %i to i64 + %tmp13 = getelementptr inbounds <4 x i32>, <4 x i32> addrspace(1)* null, i64 %tmp12 + %tmp14 = load <4 x i32>, <4 x i32> addrspace(1)* %tmp13, align 16 + %tmp15 = extractelement <4 x i32> %tmp14, i64 0 + %tmp16 = and i32 %tmp15, 65535 + %tmp17 = icmp eq i32 %tmp16, 1 + br i1 %tmp17, label %bb18, label %bb62 + +bb18: + %tmp19 = extractelement <2 x i32> %tmp, i64 0 + %tmp22 = lshr i32 %tmp19, 16 + %tmp24 = urem i32 %tmp22, 52 + %tmp25 = mul nuw nsw i32 %tmp24, 52 + br label %INNER_LOOP + +INNER_LOOP: + %inner.loop.j = phi i32 [ %tmp25, %bb18 ], [ %inner.loop.j.inc, %INNER_LOOP ] + call void asm sideeffect "; inner loop body", ""() #0 + %inner.loop.j.inc = add nsw i32 %inner.loop.j, 1 + %inner.loop.cmp = icmp eq i32 %inner.loop.j, 0 + br i1 %inner.loop.cmp, label %INNER_LOOP_BREAK, label %INNER_LOOP + +INNER_LOOP_BREAK: + %tmp59 = extractelement <4 x i32> %tmp14, i64 2 + call void asm sideeffect "s_nop 23 ", "~{memory}"() #0 + br label %END_ELSE_BLOCK + +bb62: + %load13 = icmp ult i32 %tmp16, 271 + ;br i1 %load13, label %bb64, label %INCREMENT_I + ; branching directly to the return avoids the bug + br i1 %load13, label %RETURN, label %INCREMENT_I + + +bb64: + call void asm sideeffect "s_nop 42", "~{memory}"() #0 + br label %RETURN + +INCREMENT_I: + %inc.i = add i32 %i, 1 + call void asm sideeffect "s_nop 0x1336 ; increment $0", "v,~{memory}"(i32 %inc.i) #0 + br label %END_ELSE_BLOCK + +END_ELSE_BLOCK: + %i.final = phi i32 [ %tmp59, %INNER_LOOP_BREAK ], [ %inc.i, %INCREMENT_I ] + call void asm sideeffect "s_nop 0x1337 ; end else block $0", "v,~{memory}"(i32 %i.final) #0 + %cmp.end.else.block = icmp eq i32 %i.final, -1 + br i1 %cmp.end.else.block, label %RETURN, label %LOOP.HEADER + +RETURN: + call void asm sideeffect "s_nop 0x99 ; ClosureEval return", "~{memory}"() #0 + store volatile <2 x float> %load1, <2 x float> addrspace(1)* undef, align 8 + ret void +} + +declare i32 @llvm.amdgcn.workitem.id.x() #1 + +attributes #0 = { convergent nounwind } +attributes #1 = { convergent nounwind readnone } diff --git a/test/Transforms/StructurizeCFG/AMDGPU/backedge-id-bug.ll b/test/Transforms/StructurizeCFG/AMDGPU/backedge-id-bug.ll new file mode 100644 index 000000000000..9cddffdd1795 --- /dev/null +++ b/test/Transforms/StructurizeCFG/AMDGPU/backedge-id-bug.ll @@ -0,0 +1,163 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -mtriple=amdgcn-amd-amdhsa -S -structurizecfg %s | FileCheck %s + +; StructurizeCFG::orderNodes used an arbitrary and nonsensical sorting +; function which broke the basic backedge identification algorithm. It +; would use RPO order, but then do a weird partial sort by the loop +; depth assuming blocks are sorted by loop. However a block can appear +; in between blocks of a loop that is not part of a loop, breaking the +; assumption of the sort. +; +; The collectInfos must be done in RPO order. The actual +; structurization order I think is less important, but unless the loop +; headers are identified in RPO order, it finds the wrong set of back +; edges. + +define amdgpu_kernel void @loop_backedge_misidentified(i32 addrspace(1)* %arg0) #0 { +; CHECK-LABEL: @loop_backedge_misidentified( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP:%.*]] = load volatile <2 x i32>, <2 x i32> addrspace(1)* undef, align 16 +; CHECK-NEXT: [[LOAD1:%.*]] = load volatile <2 x float>, <2 x float> addrspace(1)* undef +; CHECK-NEXT: [[TID:%.*]] = call i32 @llvm.amdgcn.workitem.id.x() +; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i32, i32 addrspace(1)* [[ARG0:%.*]], i32 [[TID]] +; CHECK-NEXT: [[I_INITIAL:%.*]] = load volatile i32, i32 addrspace(1)* [[GEP]], align 4 +; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] +; CHECK: LOOP.HEADER: +; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_INITIAL]], [[ENTRY:%.*]] ], [ [[TMP10:%.*]], [[FLOW4:%.*]] ] +; CHECK-NEXT: call void asm sideeffect "s_nop 0x100b +; CHECK-NEXT: [[TMP12:%.*]] = zext i32 [[I]] to i64 +; CHECK-NEXT: [[TMP13:%.*]] = getelementptr inbounds <4 x i32>, <4 x i32> addrspace(1)* null, i64 [[TMP12]] +; CHECK-NEXT: [[TMP14:%.*]] = load <4 x i32>, <4 x i32> addrspace(1)* [[TMP13]], align 16 +; CHECK-NEXT: [[TMP15:%.*]] = extractelement <4 x i32> [[TMP14]], i64 0 +; CHECK-NEXT: [[TMP16:%.*]] = and i32 [[TMP15]], 65535 +; CHECK-NEXT: [[TMP17:%.*]] = icmp eq i32 [[TMP16]], 1 +; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[TMP17]], true +; CHECK-NEXT: br i1 [[TMP0]], label [[BB62:%.*]], label [[FLOW:%.*]] +; CHECK: Flow2: +; CHECK-NEXT: br label [[FLOW]] +; CHECK: bb18: +; CHECK-NEXT: [[TMP19:%.*]] = extractelement <2 x i32> [[TMP]], i64 0 +; CHECK-NEXT: [[TMP22:%.*]] = lshr i32 [[TMP19]], 16 +; CHECK-NEXT: [[TMP24:%.*]] = urem i32 [[TMP22]], 52 +; CHECK-NEXT: [[TMP25:%.*]] = mul nuw nsw i32 [[TMP24]], 52 +; CHECK-NEXT: br label [[INNER_LOOP:%.*]] +; CHECK: Flow3: +; CHECK-NEXT: [[TMP1:%.*]] = phi i32 [ [[TMP59:%.*]], [[INNER_LOOP_BREAK:%.*]] ], [ [[TMP7:%.*]], [[FLOW]] ] +; CHECK-NEXT: [[TMP2:%.*]] = phi i1 [ true, [[INNER_LOOP_BREAK]] ], [ [[TMP8:%.*]], [[FLOW]] ] +; CHECK-NEXT: br i1 [[TMP2]], label [[END_ELSE_BLOCK:%.*]], label [[FLOW4]] +; CHECK: INNER_LOOP: +; CHECK-NEXT: [[INNER_LOOP_J:%.*]] = phi i32 [ [[INNER_LOOP_J_INC:%.*]], [[INNER_LOOP]] ], [ [[TMP25]], [[BB18:%.*]] ] +; CHECK-NEXT: call void asm sideeffect " +; CHECK-NEXT: [[INNER_LOOP_J_INC]] = add nsw i32 [[INNER_LOOP_J]], 1 +; CHECK-NEXT: [[INNER_LOOP_CMP:%.*]] = icmp eq i32 [[INNER_LOOP_J]], 0 +; CHECK-NEXT: br i1 [[INNER_LOOP_CMP]], label [[INNER_LOOP_BREAK]], label [[INNER_LOOP]] +; CHECK: INNER_LOOP_BREAK: +; CHECK-NEXT: [[TMP59]] = extractelement <4 x i32> [[TMP14]], i64 2 +; CHECK-NEXT: call void asm sideeffect "s_nop 23 ", "~{memory}"() #0 +; CHECK-NEXT: br label [[FLOW3:%.*]] +; CHECK: bb62: +; CHECK-NEXT: [[LOAD13:%.*]] = icmp ult i32 [[TMP16]], 271 +; CHECK-NEXT: [[TMP3:%.*]] = xor i1 [[LOAD13]], true +; CHECK-NEXT: br i1 [[TMP3]], label [[INCREMENT_I:%.*]], label [[FLOW1:%.*]] +; CHECK: Flow1: +; CHECK-NEXT: [[TMP4:%.*]] = phi i32 [ [[INC_I:%.*]], [[INCREMENT_I]] ], [ undef, [[BB62]] ] +; CHECK-NEXT: [[TMP5:%.*]] = phi i1 [ true, [[INCREMENT_I]] ], [ false, [[BB62]] ] +; CHECK-NEXT: [[TMP6:%.*]] = phi i1 [ false, [[INCREMENT_I]] ], [ true, [[BB62]] ] +; CHECK-NEXT: br i1 [[TMP6]], label [[BB64:%.*]], label [[FLOW2:%.*]] +; CHECK: bb64: +; CHECK-NEXT: call void asm sideeffect "s_nop 42", "~{memory}"() #0 +; CHECK-NEXT: br label [[FLOW2]] +; CHECK: Flow: +; CHECK-NEXT: [[TMP7]] = phi i32 [ [[TMP4]], [[FLOW2]] ], [ undef, [[LOOP_HEADER]] ] +; CHECK-NEXT: [[TMP8]] = phi i1 [ [[TMP5]], [[FLOW2]] ], [ false, [[LOOP_HEADER]] ] +; CHECK-NEXT: [[TMP9:%.*]] = phi i1 [ false, [[FLOW2]] ], [ true, [[LOOP_HEADER]] ] +; CHECK-NEXT: br i1 [[TMP9]], label [[BB18]], label [[FLOW3]] +; CHECK: INCREMENT_I: +; CHECK-NEXT: [[INC_I]] = add i32 [[I]], 1 +; CHECK-NEXT: call void asm sideeffect "s_nop 0x1336 +; CHECK-NEXT: br label [[FLOW1]] +; CHECK: END_ELSE_BLOCK: +; CHECK-NEXT: [[I_FINAL:%.*]] = phi i32 [ [[TMP1]], [[FLOW3]] ] +; CHECK-NEXT: call void asm sideeffect "s_nop 0x1337 +; CHECK-NEXT: [[CMP_END_ELSE_BLOCK:%.*]] = icmp eq i32 [[I_FINAL]], -1 +; CHECK-NEXT: br label [[FLOW4]] +; CHECK: Flow4: +; CHECK-NEXT: [[TMP10]] = phi i32 [ [[I_FINAL]], [[END_ELSE_BLOCK]] ], [ undef, [[FLOW3]] ] +; CHECK-NEXT: [[TMP11:%.*]] = phi i1 [ [[CMP_END_ELSE_BLOCK]], [[END_ELSE_BLOCK]] ], [ true, [[FLOW3]] ] +; CHECK-NEXT: br i1 [[TMP11]], label [[RETURN:%.*]], label [[LOOP_HEADER]] +; CHECK: RETURN: +; CHECK-NEXT: call void asm sideeffect "s_nop 0x99 +; CHECK-NEXT: store volatile <2 x float> [[LOAD1]], <2 x float> addrspace(1)* undef, align 8 +; CHECK-NEXT: ret void +; +entry: + %tmp = load volatile <2 x i32>, <2 x i32> addrspace(1)* undef, align 16 + %load1 = load volatile <2 x float>, <2 x float> addrspace(1)* undef + %tid = call i32 @llvm.amdgcn.workitem.id.x() + %gep = getelementptr inbounds i32, i32 addrspace(1)* %arg0, i32 %tid + %i.initial = load volatile i32, i32 addrspace(1)* %gep, align 4 + br label %LOOP.HEADER + +LOOP.HEADER: + %i = phi i32 [ %i.final, %END_ELSE_BLOCK ], [ %i.initial, %entry ] + call void asm sideeffect "s_nop 0x100b ; loop $0 ", "r,~{memory}"(i32 %i) #0 + %tmp12 = zext i32 %i to i64 + %tmp13 = getelementptr inbounds <4 x i32>, <4 x i32> addrspace(1)* null, i64 %tmp12 + %tmp14 = load <4 x i32>, <4 x i32> addrspace(1)* %tmp13, align 16 + %tmp15 = extractelement <4 x i32> %tmp14, i64 0 + %tmp16 = and i32 %tmp15, 65535 + %tmp17 = icmp eq i32 %tmp16, 1 + br i1 %tmp17, label %bb18, label %bb62 + +bb18: + %tmp19 = extractelement <2 x i32> %tmp, i64 0 + %tmp22 = lshr i32 %tmp19, 16 + %tmp24 = urem i32 %tmp22, 52 + %tmp25 = mul nuw nsw i32 %tmp24, 52 + br label %INNER_LOOP + +INNER_LOOP: + %inner.loop.j = phi i32 [ %tmp25, %bb18 ], [ %inner.loop.j.inc, %INNER_LOOP ] + call void asm sideeffect "; inner loop body", ""() #0 + %inner.loop.j.inc = add nsw i32 %inner.loop.j, 1 + %inner.loop.cmp = icmp eq i32 %inner.loop.j, 0 + br i1 %inner.loop.cmp, label %INNER_LOOP_BREAK, label %INNER_LOOP + +INNER_LOOP_BREAK: + %tmp59 = extractelement <4 x i32> %tmp14, i64 2 + call void asm sideeffect "s_nop 23 ", "~{memory}"() #0 + br label %END_ELSE_BLOCK + +bb62: + %load13 = icmp ult i32 %tmp16, 271 + br i1 %load13, label %bb64, label %INCREMENT_I + +bb64: + call void asm sideeffect "s_nop 42", "~{memory}"() #0 + br label %RETURN + +INCREMENT_I: + %inc.i = add i32 %i, 1 + call void asm sideeffect "s_nop 0x1336 ; increment $0", "v,~{memory}"(i32 %inc.i) #0 + br label %END_ELSE_BLOCK + +END_ELSE_BLOCK: + %i.final = phi i32 [ %tmp59, %INNER_LOOP_BREAK ], [ %inc.i, %INCREMENT_I ] + call void asm sideeffect "s_nop 0x1337 ; end else block $0", "v,~{memory}"(i32 %i.final) #0 + %cmp.end.else.block = icmp eq i32 %i.final, -1 + br i1 %cmp.end.else.block, label %RETURN, label %LOOP.HEADER + +RETURN: + call void asm sideeffect "s_nop 0x99 ; ClosureEval return", "~{memory}"() #0 + store volatile <2 x float> %load1, <2 x float> addrspace(1)* undef, align 8 + ret void +} + +; The same function, except break to return block goes directly to the +; return, which managed to hide the bug. +; FIXME: Merge variant from backedge-id-bug-xfail + +declare i32 @llvm.amdgcn.workitem.id.x() #1 + +attributes #0 = { convergent nounwind } +attributes #1 = { convergent nounwind readnone } diff --git a/test/Transforms/StructurizeCFG/AMDGPU/lit.local.cfg b/test/Transforms/StructurizeCFG/AMDGPU/lit.local.cfg new file mode 100644 index 000000000000..2a665f06be72 --- /dev/null +++ b/test/Transforms/StructurizeCFG/AMDGPU/lit.local.cfg @@ -0,0 +1,2 @@ +if not 'AMDGPU' in config.root.targets: + config.unsupported = True diff --git a/test/Transforms/StructurizeCFG/nested-loop-order.ll b/test/Transforms/StructurizeCFG/nested-loop-order.ll index 58634d0d37db..7b5bd5acb629 100644 --- a/test/Transforms/StructurizeCFG/nested-loop-order.ll +++ b/test/Transforms/StructurizeCFG/nested-loop-order.ll @@ -1,32 +1,76 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt -S -structurizecfg %s -o - | FileCheck %s define void @main(float addrspace(1)* %out) { - -; CHECK: main_body: -; CHECK: br label %LOOP.outer +; CHECK-LABEL: @main( +; CHECK-NEXT: main_body: +; CHECK-NEXT: br label [[LOOP_OUTER:%.*]] +; CHECK: LOOP.outer: +; CHECK-NEXT: [[TEMP8_0_PH:%.*]] = phi float [ 0.000000e+00, [[MAIN_BODY:%.*]] ], [ [[TMP13:%.*]], [[FLOW3:%.*]] ] +; CHECK-NEXT: [[TEMP4_0_PH:%.*]] = phi i32 [ 0, [[MAIN_BODY]] ], [ [[TMP12:%.*]], [[FLOW3]] ] +; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: LOOP: +; CHECK-NEXT: [[TMP0:%.*]] = phi i32 [ undef, [[LOOP_OUTER]] ], [ [[TMP12]], [[FLOW:%.*]] ] +; CHECK-NEXT: [[TMP1:%.*]] = phi float [ undef, [[LOOP_OUTER]] ], [ [[TMP13]], [[FLOW]] ] +; CHECK-NEXT: [[TEMP4_0:%.*]] = phi i32 [ [[TEMP4_0_PH]], [[LOOP_OUTER]] ], [ [[TMP15:%.*]], [[FLOW]] ] +; CHECK-NEXT: [[TMP20:%.*]] = add i32 [[TEMP4_0]], 1 +; CHECK-NEXT: [[TMP22:%.*]] = icmp sgt i32 [[TMP20]], 3 +; CHECK-NEXT: [[TMP2:%.*]] = xor i1 [[TMP22]], true +; CHECK-NEXT: br i1 [[TMP2]], label [[ENDIF:%.*]], label [[FLOW]] +; CHECK: Flow2: +; CHECK-NEXT: [[TMP3:%.*]] = phi float [ [[TEMP8_0_PH]], [[IF29:%.*]] ], [ [[TMP9:%.*]], [[FLOW1:%.*]] ] +; CHECK-NEXT: [[TMP4:%.*]] = phi i32 [ [[TMP20]], [[IF29]] ], [ undef, [[FLOW1]] ] +; CHECK-NEXT: [[TMP5:%.*]] = phi i1 [ [[TMP32:%.*]], [[IF29]] ], [ true, [[FLOW1]] ] +; CHECK-NEXT: br label [[FLOW]] +; CHECK: Flow3: +; CHECK-NEXT: br i1 [[TMP16:%.*]], label [[ENDLOOP:%.*]], label [[LOOP_OUTER]] +; CHECK: ENDLOOP: +; CHECK-NEXT: [[TEMP8_1:%.*]] = phi float [ [[TMP14:%.*]], [[FLOW3]] ] +; CHECK-NEXT: [[TMP23:%.*]] = icmp eq i32 [[TMP20]], 3 +; CHECK-NEXT: [[DOT45:%.*]] = select i1 [[TMP23]], float 0.000000e+00, float 1.000000e+00 +; CHECK-NEXT: store float [[DOT45]], float addrspace(1)* [[OUT:%.*]] +; CHECK-NEXT: ret void +; CHECK: ENDIF: +; CHECK-NEXT: [[TMP31:%.*]] = icmp sgt i32 [[TMP20]], 1 +; CHECK-NEXT: [[TMP6:%.*]] = xor i1 [[TMP31]], true +; CHECK-NEXT: br i1 [[TMP6]], label [[ENDIF28:%.*]], label [[FLOW1]] +; CHECK: Flow1: +; CHECK-NEXT: [[TMP7:%.*]] = phi i32 [ [[TMP20]], [[ENDIF28]] ], [ [[TMP0]], [[ENDIF]] ] +; CHECK-NEXT: [[TMP8:%.*]] = phi float [ [[TMP35:%.*]], [[ENDIF28]] ], [ [[TMP1]], [[ENDIF]] ] +; CHECK-NEXT: [[TMP9]] = phi float [ [[TMP35]], [[ENDIF28]] ], [ [[TEMP8_0_PH]], [[ENDIF]] ] +; CHECK-NEXT: [[TMP10:%.*]] = phi i1 [ [[TMP36:%.*]], [[ENDIF28]] ], [ true, [[ENDIF]] ] +; CHECK-NEXT: [[TMP11:%.*]] = phi i1 [ false, [[ENDIF28]] ], [ true, [[ENDIF]] ] +; CHECK-NEXT: br i1 [[TMP11]], label [[IF29]], label [[FLOW2:%.*]] +; CHECK: IF29: +; CHECK-NEXT: [[TMP32]] = icmp sgt i32 [[TMP20]], 2 +; CHECK-NEXT: br label [[FLOW2]] +; CHECK: Flow: +; CHECK-NEXT: [[TMP12]] = phi i32 [ [[TMP7]], [[FLOW2]] ], [ [[TMP0]], [[LOOP]] ] +; CHECK-NEXT: [[TMP13]] = phi float [ [[TMP8]], [[FLOW2]] ], [ [[TMP1]], [[LOOP]] ] +; CHECK-NEXT: [[TMP14]] = phi float [ [[TMP3]], [[FLOW2]] ], [ [[TEMP8_0_PH]], [[LOOP]] ] +; CHECK-NEXT: [[TMP15]] = phi i32 [ [[TMP4]], [[FLOW2]] ], [ undef, [[LOOP]] ] +; CHECK-NEXT: [[TMP16]] = phi i1 [ [[TMP10]], [[FLOW2]] ], [ true, [[LOOP]] ] +; CHECK-NEXT: [[TMP17:%.*]] = phi i1 [ [[TMP5]], [[FLOW2]] ], [ true, [[LOOP]] ] +; CHECK-NEXT: br i1 [[TMP17]], label [[FLOW3]], label [[LOOP]] +; CHECK: ENDIF28: +; CHECK-NEXT: [[TMP35]] = fadd float [[TEMP8_0_PH]], 1.000000e+00 +; CHECK-NEXT: [[TMP36]] = icmp sgt i32 [[TMP20]], 2 +; CHECK-NEXT: br label [[FLOW1]] +; main_body: br label %LOOP.outer -; CHECK: LOOP.outer: -; CHECK: br label %LOOP LOOP.outer: ; preds = %ENDIF28, %main_body %temp8.0.ph = phi float [ 0.000000e+00, %main_body ], [ %tmp35, %ENDIF28 ] %temp4.0.ph = phi i32 [ 0, %main_body ], [ %tmp20, %ENDIF28 ] br label %LOOP -; CHECK: LOOP: -; br i1 %{{[0-9]+}}, label %ENDIF, label %Flow LOOP: ; preds = %IF29, %LOOP.outer %temp4.0 = phi i32 [ %temp4.0.ph, %LOOP.outer ], [ %tmp20, %IF29 ] %tmp20 = add i32 %temp4.0, 1 %tmp22 = icmp sgt i32 %tmp20, 3 br i1 %tmp22, label %ENDLOOP, label %ENDIF -; CHECK: Flow3 -; CHECK: br i1 %{{[0-9]+}}, label %ENDLOOP, label %LOOP.outer - -; CHECK: ENDLOOP: -; CHECK: ret void ENDLOOP: ; preds = %ENDIF28, %IF29, %LOOP %temp8.1 = phi float [ %temp8.0.ph, %LOOP ], [ %temp8.0.ph, %IF29 ], [ %tmp35, %ENDIF28 ] %tmp23 = icmp eq i32 %tmp20, 3 @@ -34,29 +78,14 @@ ENDLOOP: ; preds = %ENDIF28, %IF29, %LO store float %.45, float addrspace(1)* %out ret void -; CHECK: ENDIF: -; CHECK: br i1 %tmp31, label %IF29, label %Flow1 ENDIF: ; preds = %LOOP %tmp31 = icmp sgt i32 %tmp20, 1 br i1 %tmp31, label %IF29, label %ENDIF28 -; CHECK: Flow: -; CHECK: br i1 %{{[0-9]+}}, label %Flow2, label %LOOP - -; CHECK: IF29: -; CHECK: br label %Flow1 IF29: ; preds = %ENDIF %tmp32 = icmp sgt i32 %tmp20, 2 br i1 %tmp32, label %ENDLOOP, label %LOOP -; CHECK: Flow1: -; CHECK: br label %Flow - -; CHECK: Flow2: -; CHECK: br i1 %{{[0-9]+}}, label %ENDIF28, label %Flow3 - -; CHECK: ENDIF28: -; CHECK: br label %Flow3 ENDIF28: ; preds = %ENDIF %tmp35 = fadd float %temp8.0.ph, 1.0 %tmp36 = icmp sgt i32 %tmp20, 2 |
