diff --git a/llvm/test/Transforms/NewGVN/load_coercion_replace_load_with_phi.ll b/llvm/test/Transforms/NewGVN/load_coercion_replace_load_with_phi.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/NewGVN/load_coercion_replace_load_with_phi.ll @@ -0,0 +1,4034 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -S -gvn < %s | FileCheck %s -check-prefixes=GVN,OLDGVN +; RUN: opt -S -newgvn < %s | FileCheck %s -check-prefixes=GVN,NEWGVN + +define i32 @test1(i32* %P, i32 %V1, i1 %Cond) { +; Entry +; / \ +; T F +; \ / +; vv +; Exit +; +; OLDGVN-LABEL: @test1( +; OLDGVN-NEXT: Entry: +; OLDGVN-NEXT: br i1 [[COND:%.*]], label [[T:%.*]], label [[F:%.*]] +; OLDGVN: T: +; OLDGVN-NEXT: store i32 [[V1:%.*]], i32* [[P:%.*]], align 4 +; OLDGVN-NEXT: br label [[EXIT:%.*]] +; OLDGVN: F: +; OLDGVN-NEXT: store i32 13, i32* [[P]], align 4 +; OLDGVN-NEXT: br label [[EXIT]] +; OLDGVN: Exit: +; OLDGVN-NEXT: [[V2:%.*]] = phi i32 [ 13, [[F]] ], [ [[V1]], [[T]] ] +; OLDGVN-NEXT: ret i32 [[V2]] +; +; NEWGVN-LABEL: @test1( +; NEWGVN-NEXT: Entry: +; NEWGVN-NEXT: br i1 [[COND:%.*]], label [[T:%.*]], label [[F:%.*]] +; NEWGVN: T: +; NEWGVN-NEXT: store i32 [[V1:%.*]], i32* [[P:%.*]], align 4 +; NEWGVN-NEXT: br label [[EXIT:%.*]] +; NEWGVN: F: +; NEWGVN-NEXT: store i32 13, i32* [[P]], align 4 +; NEWGVN-NEXT: br label [[EXIT]] +; NEWGVN: Exit: +; NEWGVN-NEXT: [[V2:%.*]] = load i32, i32* [[P]], align 4 +; NEWGVN-NEXT: ret i32 [[V2]] +; +Entry: + br i1 %Cond, label %T, label %F + +T: + store i32 %V1, i32* %P + br label %Exit + +F: + store i32 13, i32* %P + br label %Exit + +Exit: + %V2 = load i32, i32* %P + ret i32 %V2 +} + +define i8 @test2(i32* %P, i1 %Cond) { +; Entry +; / \ +; T F +; \ / +; vv +; Exit +; +; OLDGVN-LABEL: @test2( +; OLDGVN-NEXT: Entry: +; OLDGVN-NEXT: [[P1:%.*]] = bitcast i32* [[P:%.*]] to float* +; OLDGVN-NEXT: br i1 [[COND:%.*]], label [[T:%.*]], label [[F:%.*]] +; OLDGVN: T: +; OLDGVN-NEXT: store i32 42, i32* [[P]], align 4 +; OLDGVN-NEXT: br label [[EXIT:%.*]] +; OLDGVN: F: +; OLDGVN-NEXT: store float 1.000000e+00, float* [[P1]], align 4 +; OLDGVN-NEXT: br label [[EXIT]] +; OLDGVN: Exit: +; OLDGVN-NEXT: [[V2:%.*]] = phi i8 [ 0, [[F]] ], [ 42, [[T]] ] +; OLDGVN-NEXT: [[P2:%.*]] = bitcast i32* [[P]] to i8* +; OLDGVN-NEXT: [[V3:%.*]] = add i8 [[V2]], [[V2]] +; OLDGVN-NEXT: ret i8 [[V3]] +; +; NEWGVN-LABEL: @test2( +; NEWGVN-NEXT: Entry: +; NEWGVN-NEXT: [[P1:%.*]] = bitcast i32* [[P:%.*]] to float* +; NEWGVN-NEXT: br i1 [[COND:%.*]], label [[T:%.*]], label [[F:%.*]] +; NEWGVN: T: +; NEWGVN-NEXT: store i32 42, i32* [[P]], align 4 +; NEWGVN-NEXT: br label [[EXIT:%.*]] +; NEWGVN: F: +; NEWGVN-NEXT: store float 1.000000e+00, float* [[P1]], align 4 +; NEWGVN-NEXT: br label [[EXIT]] +; NEWGVN: Exit: +; NEWGVN-NEXT: [[PHI:%.*]] = phi i8 [ 0, [[F]] ], [ 42, [[T]] ] +; NEWGVN-NEXT: [[P2:%.*]] = bitcast i32* [[P]] to i8* +; NEWGVN-NEXT: [[V2:%.*]] = load i8, i8* [[P2]], align 1 +; NEWGVN-NEXT: [[V3:%.*]] = add i8 [[V2]], [[PHI]] +; NEWGVN-NEXT: ret i8 [[V3]] +; +Entry: + %P1 = bitcast i32* %P to float* + br i1 %Cond, label %T, label %F + +T: + store i32 42, i32* %P + br label %Exit + +F: + store float 1.0, float* %P1 + br label %Exit + +Exit: + %Phi = phi i8 [ 0, %F ], [ 42, %T ] + %P2 = bitcast i32* %P to i8* + %V2 = load i8, i8* %P2 + %V3 = add i8 %V2, %Phi + ret i8 %V3 +} + +define i8 @test3(i32* %P, i1 %Cond) { +; Entry +; / \ +; T F +; \ / +; vv +; Exit +; +; OLDGVN-LABEL: @test3( +; OLDGVN-NEXT: Entry: +; OLDGVN-NEXT: [[P3:%.*]] = bitcast i32* [[P:%.*]] to i8* +; OLDGVN-NEXT: [[P4:%.*]] = getelementptr i8, i8* [[P3]], i32 2 +; OLDGVN-NEXT: br i1 [[COND:%.*]], label [[T:%.*]], label [[F:%.*]] +; OLDGVN: T: +; OLDGVN-NEXT: store i32 42, i32* [[P]], align 4 +; OLDGVN-NEXT: br label [[EXIT:%.*]] +; OLDGVN: F: +; OLDGVN-NEXT: [[V4_PRE:%.*]] = load i8, i8* [[P4]], align 1 +; OLDGVN-NEXT: br label [[EXIT]] +; OLDGVN: Exit: +; OLDGVN-NEXT: [[V4:%.*]] = phi i8 [ [[V4_PRE]], [[F]] ], [ 0, [[T]] ] +; OLDGVN-NEXT: ret i8 [[V4]] +; +; NEWGVN-LABEL: @test3( +; NEWGVN-NEXT: Entry: +; NEWGVN-NEXT: [[P3:%.*]] = bitcast i32* [[P:%.*]] to i8* +; NEWGVN-NEXT: [[P4:%.*]] = getelementptr i8, i8* [[P3]], i32 2 +; NEWGVN-NEXT: br i1 [[COND:%.*]], label [[T:%.*]], label [[F:%.*]] +; NEWGVN: T: +; NEWGVN-NEXT: store i32 42, i32* [[P]], align 4 +; NEWGVN-NEXT: br label [[EXIT:%.*]] +; NEWGVN: F: +; NEWGVN-NEXT: br label [[EXIT]] +; NEWGVN: Exit: +; NEWGVN-NEXT: [[V4:%.*]] = load i8, i8* [[P4]], align 1 +; NEWGVN-NEXT: ret i8 [[V4]] +; +Entry: + %P3 = bitcast i32* %P to i8* + %P4 = getelementptr i8, i8* %P3, i32 2 + br i1 %Cond, label %T, label %F + +T: + store i32 42, i32* %P + br label %Exit + +F: + br label %Exit + +Exit: + %V4 = load i8, i8* %P4 + ret i8 %V4 +} + +define i32 @test4(i32* %P, i1 %Cond1, i1 %Cond2) { +; Entry +; / \ +; T F +; | / \ +; | F1 F2 +; \ | | +; v v v +; Exit +; +; GVN-LABEL: @test4( +; GVN-NEXT: Entry: +; GVN-NEXT: br i1 [[COND1:%.*]], label [[T:%.*]], label [[F:%.*]] +; GVN: T: +; GVN-NEXT: store i32 42, i32* [[P:%.*]], align 4 +; GVN-NEXT: br label [[EXIT:%.*]] +; GVN: F: +; GVN-NEXT: br i1 [[COND2:%.*]], label [[F1:%.*]], label [[F2:%.*]] +; GVN: F1: +; GVN-NEXT: br label [[EXIT]] +; GVN: F2: +; GVN-NEXT: br label [[EXIT]] +; GVN: Exit: +; GVN-NEXT: [[PHI:%.*]] = phi i32 [ 1, [[T]] ], [ 2, [[F1]] ], [ 3, [[F2]] ] +; GVN-NEXT: [[V1:%.*]] = load i32, i32* [[P]], align 4 +; GVN-NEXT: [[V2:%.*]] = add i32 [[PHI]], [[V1]] +; GVN-NEXT: ret i32 [[V2]] +; +Entry: + br i1 %Cond1, label %T, label %F + +T: + store i32 42, i32* %P + br label %Exit + +F: + br i1 %Cond2, label %F1, label %F2 + +F1: + br label %Exit + +F2: + br label %Exit + +Exit: + %Phi = phi i32 [1, %T], [2, %F1], [3, %F2] + %V1 = load i32, i32* %P + %V2 = add i32 %Phi, %V1 + ret i32 %V2 +} + +define i32 @test5(i32* %P, i1 %Cond1, i1 %Cond2) { +; Entry +; / \ +; T F +; | / \ +; | F1 F2 +; \ | | +; v v v +; Exit +; +; OLDGVN-LABEL: @test5( +; OLDGVN-NEXT: Entry: +; OLDGVN-NEXT: br i1 [[COND1:%.*]], label [[T:%.*]], label [[F:%.*]] +; OLDGVN: T: +; OLDGVN-NEXT: store i32 42, i32* [[P:%.*]], align 4 +; OLDGVN-NEXT: br label [[EXIT:%.*]] +; OLDGVN: F: +; OLDGVN-NEXT: br i1 [[COND2:%.*]], label [[F1:%.*]], label [[F2:%.*]] +; OLDGVN: F1: +; OLDGVN-NEXT: store i32 13, i32* [[P]], align 4 +; OLDGVN-NEXT: br label [[EXIT]] +; OLDGVN: F2: +; OLDGVN-NEXT: [[V1_PRE:%.*]] = load i32, i32* [[P]], align 4 +; OLDGVN-NEXT: br label [[EXIT]] +; OLDGVN: Exit: +; OLDGVN-NEXT: [[V1:%.*]] = phi i32 [ 42, [[T]] ], [ 13, [[F1]] ], [ [[V1_PRE]], [[F2]] ] +; OLDGVN-NEXT: [[PHI:%.*]] = phi i32 [ 1, [[T]] ], [ 2, [[F1]] ], [ 3, [[F2]] ] +; OLDGVN-NEXT: [[V2:%.*]] = add i32 [[PHI]], [[V1]] +; OLDGVN-NEXT: ret i32 [[V2]] +; +; NEWGVN-LABEL: @test5( +; NEWGVN-NEXT: Entry: +; NEWGVN-NEXT: br i1 [[COND1:%.*]], label [[T:%.*]], label [[F:%.*]] +; NEWGVN: T: +; NEWGVN-NEXT: store i32 42, i32* [[P:%.*]], align 4 +; NEWGVN-NEXT: br label [[EXIT:%.*]] +; NEWGVN: F: +; NEWGVN-NEXT: br i1 [[COND2:%.*]], label [[F1:%.*]], label [[F2:%.*]] +; NEWGVN: F1: +; NEWGVN-NEXT: store i32 13, i32* [[P]], align 4 +; NEWGVN-NEXT: br label [[EXIT]] +; NEWGVN: F2: +; NEWGVN-NEXT: br label [[EXIT]] +; NEWGVN: Exit: +; NEWGVN-NEXT: [[PHI:%.*]] = phi i32 [ 1, [[T]] ], [ 2, [[F1]] ], [ 3, [[F2]] ] +; NEWGVN-NEXT: [[V1:%.*]] = load i32, i32* [[P]], align 4 +; NEWGVN-NEXT: [[V2:%.*]] = add i32 [[PHI]], [[V1]] +; NEWGVN-NEXT: ret i32 [[V2]] +; +Entry: + br i1 %Cond1, label %T, label %F + +T: + store i32 42, i32* %P + br label %Exit + +F: + br i1 %Cond2, label %F1, label %F2 + +F1: + store i32 13, i32* %P + br label %Exit + +F2: + br label %Exit + +Exit: + %Phi = phi i32 [1, %T], [2, %F1], [3, %F2] + %V1 = load i32, i32* %P + %V2 = add i32 %Phi, %V1 + ret i32 %V2 +} + +define i32 @test6(i32* %P, i1 %Cond1, i1 %Cond2) { +; Entry __ +; | \ / | +; | v v | +; | Loop | +; | / \__| +; v v +; Exit +; +; OLDGVN-LABEL: @test6( +; OLDGVN-NEXT: Entry: +; OLDGVN-NEXT: store i32 42, i32* [[P:%.*]], align 4 +; OLDGVN-NEXT: br i1 [[COND1:%.*]], label [[LOOP:%.*]], label [[EXIT:%.*]] +; OLDGVN: Loop: +; OLDGVN-NEXT: store i32 13, i32* [[P]], align 4 +; OLDGVN-NEXT: br i1 [[COND2:%.*]], label [[LOOP]], label [[EXIT]] +; OLDGVN: Exit: +; OLDGVN-NEXT: [[V:%.*]] = phi i32 [ 13, [[LOOP]] ], [ 42, [[ENTRY:%.*]] ] +; OLDGVN-NEXT: ret i32 [[V]] +; +; NEWGVN-LABEL: @test6( +; NEWGVN-NEXT: Entry: +; NEWGVN-NEXT: store i32 42, i32* [[P:%.*]], align 4 +; NEWGVN-NEXT: br i1 [[COND1:%.*]], label [[LOOP:%.*]], label [[EXIT:%.*]] +; NEWGVN: Loop: +; NEWGVN-NEXT: store i32 13, i32* [[P]], align 4 +; NEWGVN-NEXT: br i1 [[COND2:%.*]], label [[LOOP]], label [[EXIT]] +; NEWGVN: Exit: +; NEWGVN-NEXT: [[V:%.*]] = load i32, i32* [[P]], align 4 +; NEWGVN-NEXT: ret i32 [[V]] +; +Entry: + store i32 42, i32* %P + br i1 %Cond1, label %Loop, label %Exit + +Loop: + store i32 13, i32* %P + br i1 %Cond2, label %Loop, label %Exit + +Exit: + %V = load i32, i32* %P + ret i32 %V +} + +define i32 @test7(i32* %P, i1 %Cond1, i1 %Cond2, i1 %Cond3) { +; Entry +; | +; +--Outer.Loop<-------+ +; | | _ | +; | | / | | +; | | v | | +; | Inner.Loop | | +; | | \_| | +; | | | +; +->Outer.Loop.Latch--+ +; | +; Exit +; +; OLDGVN-LABEL: @test7( +; OLDGVN-NEXT: Entry: +; OLDGVN-NEXT: br label [[OUTER_LOOP:%.*]] +; OLDGVN: Outer.Loop: +; OLDGVN-NEXT: store i32 42, i32* [[P:%.*]], align 4 +; OLDGVN-NEXT: br i1 [[COND1:%.*]], label [[INNER_LOOP:%.*]], label [[OUTER_LOOP_LATCH:%.*]] +; OLDGVN: Inner.Loop: +; OLDGVN-NEXT: store i32 13, i32* [[P]], align 4 +; OLDGVN-NEXT: br i1 [[COND2:%.*]], label [[INNER_LOOP]], label [[OUTER_LOOP_LATCH]] +; OLDGVN: Outer.Loop.Latch: +; OLDGVN-NEXT: [[V2:%.*]] = phi i32 [ 13, [[INNER_LOOP]] ], [ 42, [[OUTER_LOOP]] ] +; OLDGVN-NEXT: [[PHI:%.*]] = phi i32 [ 100, [[INNER_LOOP]] ], [ 200, [[OUTER_LOOP]] ] +; OLDGVN-NEXT: [[V3:%.*]] = add i32 [[V2]], [[PHI]] +; OLDGVN-NEXT: br i1 [[COND3:%.*]], label [[OUTER_LOOP]], label [[EXIT:%.*]] +; OLDGVN: Exit: +; OLDGVN-NEXT: ret i32 [[V3]] +; +; NEWGVN-LABEL: @test7( +; NEWGVN-NEXT: Entry: +; NEWGVN-NEXT: br label [[OUTER_LOOP:%.*]] +; NEWGVN: Outer.Loop: +; NEWGVN-NEXT: store i32 42, i32* [[P:%.*]], align 4 +; NEWGVN-NEXT: br i1 [[COND1:%.*]], label [[INNER_LOOP:%.*]], label [[OUTER_LOOP_LATCH:%.*]] +; NEWGVN: Inner.Loop: +; NEWGVN-NEXT: store i32 13, i32* [[P]], align 4 +; NEWGVN-NEXT: br i1 [[COND2:%.*]], label [[INNER_LOOP]], label [[OUTER_LOOP_LATCH]] +; NEWGVN: Outer.Loop.Latch: +; NEWGVN-NEXT: [[PHI:%.*]] = phi i32 [ 100, [[INNER_LOOP]] ], [ 200, [[OUTER_LOOP]] ] +; NEWGVN-NEXT: [[V2:%.*]] = load i32, i32* [[P]], align 4 +; NEWGVN-NEXT: [[V3:%.*]] = add i32 [[V2]], [[PHI]] +; NEWGVN-NEXT: br i1 [[COND3:%.*]], label [[OUTER_LOOP]], label [[EXIT:%.*]] +; NEWGVN: Exit: +; NEWGVN-NEXT: ret i32 [[V3]] +; +Entry: + br label %Outer.Loop + +Outer.Loop: + store i32 42, i32* %P + br i1 %Cond1, label %Inner.Loop, label %Outer.Loop.Latch + +Inner.Loop: + store i32 13, i32* %P + br i1 %Cond2, label %Inner.Loop, label %Outer.Loop.Latch + +Outer.Loop.Latch: + %Phi = phi i32 [ 100, %Inner.Loop ], [ 200, %Outer.Loop ] + %V2 = load i32, i32* %P + %V3 = add i32 %V2, %Phi + br i1 %Cond3, label %Outer.Loop, label %Exit + +Exit: + ret i32 %V3 +} + +define i32 @test8(i8* %P, i1 %Cond) { +; Entry +; / \ +; T F +; \ / +; vv +; Exit +; +; OLDGVN-LABEL: @test8( +; OLDGVN-NEXT: Entry: +; OLDGVN-NEXT: br i1 [[COND:%.*]], label [[T:%.*]], label [[F:%.*]] +; OLDGVN: T: +; OLDGVN-NEXT: [[P1:%.*]] = bitcast i8* [[P:%.*]] to <2 x i32>* +; OLDGVN-NEXT: [[V1:%.*]] = load <2 x i32>, <2 x i32>* [[P1]], align 8 +; OLDGVN-NEXT: [[V3:%.*]] = extractelement <2 x i32> [[V1]], i64 1 +; OLDGVN-NEXT: [[TMP0:%.*]] = bitcast <2 x i32> [[V1]] to i64 +; OLDGVN-NEXT: [[TMP1:%.*]] = trunc i64 [[TMP0]] to i32 +; OLDGVN-NEXT: [[DOTPRE:%.*]] = bitcast i8* [[P]] to i32* +; OLDGVN-NEXT: br label [[EXIT:%.*]] +; OLDGVN: F: +; OLDGVN-NEXT: [[P2_PHI_TRANS_INSERT:%.*]] = bitcast i8* [[P]] to i32* +; OLDGVN-NEXT: [[V2_PRE:%.*]] = load i32, i32* [[P2_PHI_TRANS_INSERT]], align 4 +; OLDGVN-NEXT: br label [[EXIT]] +; OLDGVN: Exit: +; OLDGVN-NEXT: [[P2_PRE_PHI:%.*]] = phi i32* [ [[P2_PHI_TRANS_INSERT]], [[F]] ], [ [[DOTPRE]], [[T]] ] +; OLDGVN-NEXT: [[V2:%.*]] = phi i32 [ [[V2_PRE]], [[F]] ], [ [[TMP1]], [[T]] ] +; OLDGVN-NEXT: [[PHI:%.*]] = phi i32 [ 100, [[F]] ], [ [[V3]], [[T]] ] +; OLDGVN-NEXT: [[V4:%.*]] = add i32 [[V2]], [[PHI]] +; OLDGVN-NEXT: ret i32 [[V4]] +; +; NEWGVN-LABEL: @test8( +; NEWGVN-NEXT: Entry: +; NEWGVN-NEXT: br i1 [[COND:%.*]], label [[T:%.*]], label [[F:%.*]] +; NEWGVN: T: +; NEWGVN-NEXT: [[P1:%.*]] = bitcast i8* [[P:%.*]] to <2 x i32>* +; NEWGVN-NEXT: [[V1:%.*]] = load <2 x i32>, <2 x i32>* [[P1]], align 8 +; NEWGVN-NEXT: [[V3:%.*]] = extractelement <2 x i32> [[V1]], i64 1 +; NEWGVN-NEXT: br label [[EXIT:%.*]] +; NEWGVN: F: +; NEWGVN-NEXT: br label [[EXIT]] +; NEWGVN: Exit: +; NEWGVN-NEXT: [[PHI:%.*]] = phi i32 [ 100, [[F]] ], [ [[V3]], [[T]] ] +; NEWGVN-NEXT: [[P2:%.*]] = bitcast i8* [[P]] to i32* +; NEWGVN-NEXT: [[V2:%.*]] = load i32, i32* [[P2]], align 4 +; NEWGVN-NEXT: [[V4:%.*]] = add i32 [[V2]], [[PHI]] +; NEWGVN-NEXT: ret i32 [[V4]] +; +Entry: + br i1 %Cond, label %T, label %F + +T: + %P1 = bitcast i8* %P to <2 x i32>* + %V1 = load <2 x i32>, <2 x i32>* %P1 + %V3 = extractelement <2 x i32> %V1, i64 1 + br label %Exit + +F: + br label %Exit + +Exit: + %Phi = phi i32 [100, %F], [%V3, %T] + %P2 = bitcast i8* %P to i32* + %V2 = load i32, i32* %P2 + %V4 = add i32 %V2, %Phi + ret i32 %V4 +} + +define i32 @test9(i32* %P, i1 %Cond) { +; Entry +; / \ +; T F +; \ / +; vv +; Exit +; +; OLDGVN-LABEL: @test9( +; OLDGVN-NEXT: Entry: +; OLDGVN-NEXT: br i1 [[COND:%.*]], label [[T:%.*]], label [[F:%.*]] +; OLDGVN: T: +; OLDGVN-NEXT: [[P1:%.*]] = bitcast i32* [[P:%.*]] to <2 x i32>* +; OLDGVN-NEXT: [[V4_PRE:%.*]] = load i32, i32* [[P]], align 4 +; OLDGVN-NEXT: br label [[EXIT:%.*]] +; OLDGVN: F: +; OLDGVN-NEXT: [[P2:%.*]] = bitcast i32* [[P]] to <2 x i32>* +; OLDGVN-NEXT: [[V2:%.*]] = load <2 x i32>, <2 x i32>* [[P2]], align 8 +; OLDGVN-NEXT: [[V3:%.*]] = extractelement <2 x i32> [[V2]], i64 1 +; OLDGVN-NEXT: [[TMP0:%.*]] = bitcast <2 x i32> [[V2]] to i64 +; OLDGVN-NEXT: [[TMP1:%.*]] = trunc i64 [[TMP0]] to i32 +; OLDGVN-NEXT: br label [[EXIT]] +; OLDGVN: Exit: +; OLDGVN-NEXT: [[V4:%.*]] = phi i32 [ [[V4_PRE]], [[T]] ], [ [[TMP1]], [[F]] ] +; OLDGVN-NEXT: [[PHI:%.*]] = phi i32 [ 0, [[T]] ], [ [[V3]], [[F]] ] +; OLDGVN-NEXT: [[V5:%.*]] = add i32 [[V4]], [[PHI]] +; OLDGVN-NEXT: ret i32 [[V5]] +; +; NEWGVN-LABEL: @test9( +; NEWGVN-NEXT: Entry: +; NEWGVN-NEXT: br i1 [[COND:%.*]], label [[T:%.*]], label [[F:%.*]] +; NEWGVN: T: +; NEWGVN-NEXT: br label [[EXIT:%.*]] +; NEWGVN: F: +; NEWGVN-NEXT: [[P2:%.*]] = bitcast i32* [[P:%.*]] to <2 x i32>* +; NEWGVN-NEXT: [[V2:%.*]] = load <2 x i32>, <2 x i32>* [[P2]], align 8 +; NEWGVN-NEXT: [[V3:%.*]] = extractelement <2 x i32> [[V2]], i64 1 +; NEWGVN-NEXT: br label [[EXIT]] +; NEWGVN: Exit: +; NEWGVN-NEXT: [[PHI:%.*]] = phi i32 [ 0, [[T]] ], [ [[V3]], [[F]] ] +; NEWGVN-NEXT: [[V4:%.*]] = load i32, i32* [[P]], align 4 +; NEWGVN-NEXT: [[V5:%.*]] = add i32 [[V4]], [[PHI]] +; NEWGVN-NEXT: ret i32 [[V5]] +; +Entry: + br i1 %Cond, label %T, label %F + +T: + %P1 = bitcast i32* %P to <2 x i32>* + %V1 = load <2 x i32>, <2 x i32>* %P1 + br label %Exit + +F: + %P2 = bitcast i32* %P to <2 x i32>* + %V2 = load <2 x i32>, <2 x i32>* %P2 + %V3 = extractelement <2 x i32> %V2, i64 1 + br label %Exit + +Exit: + %Phi = phi i32 [0, %T], [%V3, %F] + %V4 = load i32, i32* %P + %V5 = add i32 %V4, %Phi + ret i32 %V5 +} + +define i32 @test10(i32* %P, i1 %Cond) { +; Entry +; / \ +; T F +; \ / +; vv +; Exit +; +; OLDGVN-LABEL: @test10( +; OLDGVN-NEXT: Entry: +; OLDGVN-NEXT: br i1 [[COND:%.*]], label [[T:%.*]], label [[F:%.*]] +; OLDGVN: T: +; OLDGVN-NEXT: [[V1:%.*]] = load i32, i32* [[P:%.*]], align 4 +; OLDGVN-NEXT: br label [[EXIT:%.*]] +; OLDGVN: F: +; OLDGVN-NEXT: [[P2:%.*]] = bitcast i32* [[P]] to <2 x i32>* +; OLDGVN-NEXT: [[V2:%.*]] = load <2 x i32>, <2 x i32>* [[P2]], align 8 +; OLDGVN-NEXT: [[V3:%.*]] = extractelement <2 x i32> [[V2]], i64 1 +; OLDGVN-NEXT: [[TMP0:%.*]] = bitcast <2 x i32> [[V2]] to i64 +; OLDGVN-NEXT: [[TMP1:%.*]] = trunc i64 [[TMP0]] to i32 +; OLDGVN-NEXT: br label [[EXIT]] +; OLDGVN: Exit: +; OLDGVN-NEXT: [[V4:%.*]] = phi i32 [ [[V1]], [[T]] ], [ [[TMP1]], [[F]] ] +; OLDGVN-NEXT: [[PHI:%.*]] = phi i32 [ [[V1]], [[T]] ], [ [[V3]], [[F]] ] +; OLDGVN-NEXT: [[V5:%.*]] = add i32 [[PHI]], [[PHI]] +; OLDGVN-NEXT: [[V6:%.*]] = add i32 [[V5]], [[V4]] +; OLDGVN-NEXT: ret i32 [[V6]] +; +; NEWGVN-LABEL: @test10( +; NEWGVN-NEXT: Entry: +; NEWGVN-NEXT: br i1 [[COND:%.*]], label [[T:%.*]], label [[F:%.*]] +; NEWGVN: T: +; NEWGVN-NEXT: [[V1:%.*]] = load i32, i32* [[P:%.*]], align 4 +; NEWGVN-NEXT: br label [[EXIT:%.*]] +; NEWGVN: F: +; NEWGVN-NEXT: [[P2:%.*]] = bitcast i32* [[P]] to <2 x i32>* +; NEWGVN-NEXT: [[V2:%.*]] = load <2 x i32>, <2 x i32>* [[P2]], align 8 +; NEWGVN-NEXT: [[V3:%.*]] = extractelement <2 x i32> [[V2]], i64 1 +; NEWGVN-NEXT: br label [[EXIT]] +; NEWGVN: Exit: +; NEWGVN-NEXT: [[PHI:%.*]] = phi i32 [ [[V1]], [[T]] ], [ [[V3]], [[F]] ] +; NEWGVN-NEXT: [[V4:%.*]] = load i32, i32* [[P]], align 4 +; NEWGVN-NEXT: [[V5:%.*]] = add i32 [[PHI]], [[PHI]] +; NEWGVN-NEXT: [[V6:%.*]] = add i32 [[V5]], [[V4]] +; NEWGVN-NEXT: ret i32 [[V6]] +; +Entry: + br i1 %Cond, label %T, label %F + +T: + %V1 = load i32, i32* %P + br label %Exit + +F: + %P2 = bitcast i32* %P to <2 x i32>* + %V2 = load <2 x i32>, <2 x i32>* %P2 + %V3 = extractelement <2 x i32> %V2, i64 1 + br label %Exit + +Exit: + %Phi = phi i32 [%V1, %T], [%V3, %F] + %V4 = load i32, i32* %P + %V5 = add i32 %Phi, %Phi + %V6 = add i32 %V5, %V4 + ret i32 %V6 +} + +define i32 @test11(i32* %P, i1 %Cond) { +; Entry +; / \ +; T F +; \ / +; vv +; Exit +; +; GVN-LABEL: @test11( +; GVN-NEXT: Entry: +; GVN-NEXT: br i1 [[COND:%.*]], label [[T:%.*]], label [[F:%.*]] +; GVN: T: +; GVN-NEXT: [[V1:%.*]] = load i32, i32* [[P:%.*]], align 4 +; GVN-NEXT: br label [[EXIT:%.*]] +; GVN: F: +; GVN-NEXT: br label [[EXIT]] +; GVN: Exit: +; GVN-NEXT: [[PHI:%.*]] = phi i32 [ [[V1]], [[T]] ], [ 0, [[F]] ] +; GVN-NEXT: [[P2:%.*]] = bitcast i32* [[P]] to <2 x i32>* +; GVN-NEXT: [[V2:%.*]] = load <2 x i32>, <2 x i32>* [[P2]], align 8 +; GVN-NEXT: [[V3:%.*]] = extractelement <2 x i32> [[V2]], i64 1 +; GVN-NEXT: [[V5:%.*]] = add i32 [[PHI]], [[V3]] +; GVN-NEXT: ret i32 [[V5]] +; +Entry: + br i1 %Cond, label %T, label %F + +T: + %V1 = load i32, i32* %P + br label %Exit + +F: + br label %Exit + +Exit: + %Phi = phi i32 [%V1, %T], [0, %F] + %P2 = bitcast i32* %P to <2 x i32>* + %V2 = load <2 x i32>, <2 x i32>* %P2 + %V3 = extractelement <2 x i32> %V2, i64 1 + %V5 = add i32 %Phi, %V3 + ret i32 %V5 +} + +define i32 @test12(i32* %P, i1 %Cond1, i1 %Cond2) { +; Entry __ +; | \ / | +; | v v | +; | Loop | +; | / \__| +; v v +; Exit +; +; OLDGVN-LABEL: @test12( +; OLDGVN-NEXT: Entry: +; OLDGVN-NEXT: [[P1:%.*]] = bitcast i32* [[P:%.*]] to <2 x i32>* +; OLDGVN-NEXT: [[V1:%.*]] = load <2 x i32>, <2 x i32>* [[P1]], align 8 +; OLDGVN-NEXT: [[V2:%.*]] = extractelement <2 x i32> [[V1]], i64 1 +; OLDGVN-NEXT: [[TMP0:%.*]] = bitcast <2 x i32> [[V1]] to i64 +; OLDGVN-NEXT: [[TMP1:%.*]] = trunc i64 [[TMP0]] to i32 +; OLDGVN-NEXT: br i1 [[COND1:%.*]], label [[LOOP:%.*]], label [[EXIT:%.*]] +; OLDGVN: Loop: +; OLDGVN-NEXT: br i1 [[COND2:%.*]], label [[LOOP]], label [[EXIT]] +; OLDGVN: Exit: +; OLDGVN-NEXT: [[PHI:%.*]] = phi i32 [ [[V2]], [[ENTRY:%.*]] ], [ [[TMP1]], [[LOOP]] ] +; OLDGVN-NEXT: ret i32 [[PHI]] +; +; NEWGVN-LABEL: @test12( +; NEWGVN-NEXT: Entry: +; NEWGVN-NEXT: [[P1:%.*]] = bitcast i32* [[P:%.*]] to <2 x i32>* +; NEWGVN-NEXT: [[V1:%.*]] = load <2 x i32>, <2 x i32>* [[P1]], align 8 +; NEWGVN-NEXT: [[V2:%.*]] = extractelement <2 x i32> [[V1]], i64 1 +; NEWGVN-NEXT: br i1 [[COND1:%.*]], label [[LOOP:%.*]], label [[EXIT:%.*]] +; NEWGVN: Loop: +; NEWGVN-NEXT: [[V3:%.*]] = load i32, i32* [[P]], align 4 +; NEWGVN-NEXT: br i1 [[COND2:%.*]], label [[LOOP]], label [[EXIT]] +; NEWGVN: Exit: +; NEWGVN-NEXT: [[PHI:%.*]] = phi i32 [ [[V2]], [[ENTRY:%.*]] ], [ [[V3]], [[LOOP]] ] +; NEWGVN-NEXT: ret i32 [[PHI]] +; +Entry: + %P1 = bitcast i32* %P to <2 x i32>* + %V1 = load <2 x i32>, <2 x i32>* %P1 + %V2 = extractelement <2 x i32> %V1, i64 1 + br i1 %Cond1, label %Loop, label %Exit + +Loop: + %V3 = load i32, i32* %P + br i1 %Cond2, label %Loop, label %Exit + +Exit: + %Phi = phi i32 [ %V2, %Entry ], [ %V3, %Loop ] + ret i32 %Phi +} + +define i32 @test13(i32* %P, i1 %Cond) { +; Entry +; / \ +; T F +; \ / +; vv +; Exit +; +; OLDGVN-LABEL: @test13( +; OLDGVN-NEXT: Entry: +; OLDGVN-NEXT: br i1 [[COND:%.*]], label [[T:%.*]], label [[F:%.*]] +; OLDGVN: T: +; OLDGVN-NEXT: [[P1:%.*]] = bitcast i32* [[P:%.*]] to <4 x i32>* +; OLDGVN-NEXT: [[V1:%.*]] = load <4 x i32>, <4 x i32>* [[P1]], align 16 +; OLDGVN-NEXT: [[V2:%.*]] = extractelement <4 x i32> [[V1]], i64 2 +; OLDGVN-NEXT: [[TMP0:%.*]] = bitcast <4 x i32> [[V1]] to i128 +; OLDGVN-NEXT: [[TMP1:%.*]] = trunc i128 [[TMP0]] to i32 +; OLDGVN-NEXT: br label [[EXIT:%.*]] +; OLDGVN: F: +; OLDGVN-NEXT: store i32 13, i32* [[P]], align 4 +; OLDGVN-NEXT: br label [[EXIT]] +; OLDGVN: Exit: +; OLDGVN-NEXT: [[V3:%.*]] = phi i32 [ [[TMP1]], [[T]] ], [ 13, [[F]] ] +; OLDGVN-NEXT: [[PHI:%.*]] = phi i32 [ [[V2]], [[T]] ], [ 100, [[F]] ] +; OLDGVN-NEXT: [[V4:%.*]] = add i32 [[PHI]], [[V3]] +; OLDGVN-NEXT: ret i32 [[V4]] +; +; NEWGVN-LABEL: @test13( +; NEWGVN-NEXT: Entry: +; NEWGVN-NEXT: br i1 [[COND:%.*]], label [[T:%.*]], label [[F:%.*]] +; NEWGVN: T: +; NEWGVN-NEXT: [[P1:%.*]] = bitcast i32* [[P:%.*]] to <4 x i32>* +; NEWGVN-NEXT: [[V1:%.*]] = load <4 x i32>, <4 x i32>* [[P1]], align 16 +; NEWGVN-NEXT: [[V2:%.*]] = extractelement <4 x i32> [[V1]], i64 2 +; NEWGVN-NEXT: br label [[EXIT:%.*]] +; NEWGVN: F: +; NEWGVN-NEXT: store i32 13, i32* [[P]], align 4 +; NEWGVN-NEXT: br label [[EXIT]] +; NEWGVN: Exit: +; NEWGVN-NEXT: [[PHI:%.*]] = phi i32 [ [[V2]], [[T]] ], [ 100, [[F]] ] +; NEWGVN-NEXT: [[V3:%.*]] = load i32, i32* [[P]], align 4 +; NEWGVN-NEXT: [[V4:%.*]] = add i32 [[PHI]], [[V3]] +; NEWGVN-NEXT: ret i32 [[V4]] +; +Entry: + br i1 %Cond, label %T, label %F + +T: + %P1 = bitcast i32* %P to <4 x i32>* + %V1 = load <4 x i32>, <4 x i32>* %P1 + %V2 = extractelement <4 x i32> %V1, i64 2 + br label %Exit + +F: + store i32 13, i32* %P + br label %Exit + +Exit: + %Phi = phi i32 [ %V2, %T ], [ 100, %F ] + %V3 = load i32, i32* %P + %V4 = add i32 %Phi, %V3 + ret i32 %V4 +} + +define i32 @test14(i32* %P, i1 %Cond) { +; Entry +; / \ +; T F +; \ / +; vv +; Exit +; +; OLDGVN-LABEL: @test14( +; OLDGVN-NEXT: Entry: +; OLDGVN-NEXT: [[P1:%.*]] = bitcast i32* [[P:%.*]] to <4 x i32>* +; OLDGVN-NEXT: store <4 x i32> , <4 x i32>* [[P1]], align 16 +; OLDGVN-NEXT: br i1 [[COND:%.*]], label [[T:%.*]], label [[F:%.*]] +; OLDGVN: T: +; OLDGVN-NEXT: br label [[EXIT:%.*]] +; OLDGVN: F: +; OLDGVN-NEXT: store i32 100, i32* [[P]], align 4 +; OLDGVN-NEXT: br label [[EXIT]] +; OLDGVN: Exit: +; OLDGVN-NEXT: [[V3:%.*]] = phi i32 [ 13, [[T]] ], [ 100, [[F]] ] +; OLDGVN-NEXT: [[V4:%.*]] = add i32 [[V3]], [[V3]] +; OLDGVN-NEXT: ret i32 [[V4]] +; +; NEWGVN-LABEL: @test14( +; NEWGVN-NEXT: Entry: +; NEWGVN-NEXT: [[P1:%.*]] = bitcast i32* [[P:%.*]] to <4 x i32>* +; NEWGVN-NEXT: store <4 x i32> , <4 x i32>* [[P1]], align 16 +; NEWGVN-NEXT: br i1 [[COND:%.*]], label [[T:%.*]], label [[F:%.*]] +; NEWGVN: T: +; NEWGVN-NEXT: br label [[EXIT:%.*]] +; NEWGVN: F: +; NEWGVN-NEXT: store i32 100, i32* [[P]], align 4 +; NEWGVN-NEXT: br label [[EXIT]] +; NEWGVN: Exit: +; NEWGVN-NEXT: [[PHI:%.*]] = phi i32 [ 13, [[T]] ], [ 100, [[F]] ] +; NEWGVN-NEXT: [[V3:%.*]] = load i32, i32* [[P]], align 4 +; NEWGVN-NEXT: [[V4:%.*]] = add i32 [[PHI]], [[V3]] +; NEWGVN-NEXT: ret i32 [[V4]] +; +Entry: + %P1 = bitcast i32* %P to <4 x i32>* + store <4 x i32> , <4 x i32>* %P1 + br i1 %Cond, label %T, label %F + +T: + %V1 = load <4 x i32>, <4 x i32>* %P1 + %V2 = extractelement <4 x i32> %V1, i64 2 + br label %Exit + +F: + store i32 100, i32* %P + br label %Exit + +Exit: + %Phi = phi i32 [ %V2, %T ], [ 100, %F ] + %V3 = load i32, i32* %P + %V4 = add i32 %Phi, %V3 + ret i32 %V4 +} + +define i32 @test15(i32* %P, i1 %Cond) { +; Entry +; / | +; BB | +; | | +; v v +; Exit +; +; OLDGVN-LABEL: @test15( +; OLDGVN-NEXT: Entry: +; OLDGVN-NEXT: store i32 42, i32* [[P:%.*]], align 4 +; OLDGVN-NEXT: br i1 [[COND:%.*]], label [[BB:%.*]], label [[EXIT:%.*]] +; OLDGVN: BB: +; OLDGVN-NEXT: store i32 13, i32* [[P]], align 4 +; OLDGVN-NEXT: br label [[EXIT]] +; OLDGVN: Exit: +; OLDGVN-NEXT: [[V1:%.*]] = phi i32 [ 13, [[BB]] ], [ 42, [[ENTRY:%.*]] ] +; OLDGVN-NEXT: ret i32 [[V1]] +; +; NEWGVN-LABEL: @test15( +; NEWGVN-NEXT: Entry: +; NEWGVN-NEXT: store i32 42, i32* [[P:%.*]], align 4 +; NEWGVN-NEXT: br i1 [[COND:%.*]], label [[BB:%.*]], label [[EXIT:%.*]] +; NEWGVN: BB: +; NEWGVN-NEXT: store i32 13, i32* [[P]], align 4 +; NEWGVN-NEXT: br label [[EXIT]] +; NEWGVN: Exit: +; NEWGVN-NEXT: [[V1:%.*]] = load i32, i32* [[P]], align 4 +; NEWGVN-NEXT: ret i32 [[V1]] +; +Entry: + store i32 42, i32* %P + br i1 %Cond, label %BB, label %Exit + +BB: + store i32 13, i32* %P + br label %Exit + +Exit: + %V1 = load i32, i32* %P + ret i32 %V1 +} + +define i32 @test16(i32* %P, i1 %Cond) { +; Entry +; / | +; BB | +; | | +; v v +; Exit +; +; OLDGVN-LABEL: @test16( +; OLDGVN-NEXT: Entry: +; OLDGVN-NEXT: [[P1:%.*]] = bitcast i32* [[P:%.*]] to <4 x i32>* +; OLDGVN-NEXT: [[V1:%.*]] = load <4 x i32>, <4 x i32>* [[P1]], align 16 +; OLDGVN-NEXT: [[V2:%.*]] = extractelement <4 x i32> [[V1]], i64 2 +; OLDGVN-NEXT: [[TMP0:%.*]] = bitcast <4 x i32> [[V1]] to i128 +; OLDGVN-NEXT: [[TMP1:%.*]] = trunc i128 [[TMP0]] to i32 +; OLDGVN-NEXT: br i1 [[COND:%.*]], label [[BB:%.*]], label [[EXIT:%.*]] +; OLDGVN: BB: +; OLDGVN-NEXT: store i32 13, i32* [[P]], align 4 +; OLDGVN-NEXT: br label [[EXIT]] +; OLDGVN: Exit: +; OLDGVN-NEXT: [[V3:%.*]] = phi i32 [ [[TMP1]], [[ENTRY:%.*]] ], [ 13, [[BB]] ] +; OLDGVN-NEXT: [[PHI:%.*]] = phi i32 [ [[V2]], [[ENTRY]] ], [ 100, [[BB]] ] +; OLDGVN-NEXT: [[V4:%.*]] = add i32 [[PHI]], [[V3]] +; OLDGVN-NEXT: ret i32 [[V4]] +; +; NEWGVN-LABEL: @test16( +; NEWGVN-NEXT: Entry: +; NEWGVN-NEXT: [[P1:%.*]] = bitcast i32* [[P:%.*]] to <4 x i32>* +; NEWGVN-NEXT: [[V1:%.*]] = load <4 x i32>, <4 x i32>* [[P1]], align 16 +; NEWGVN-NEXT: [[V2:%.*]] = extractelement <4 x i32> [[V1]], i64 2 +; NEWGVN-NEXT: br i1 [[COND:%.*]], label [[BB:%.*]], label [[EXIT:%.*]] +; NEWGVN: BB: +; NEWGVN-NEXT: store i32 13, i32* [[P]], align 4 +; NEWGVN-NEXT: br label [[EXIT]] +; NEWGVN: Exit: +; NEWGVN-NEXT: [[PHI:%.*]] = phi i32 [ [[V2]], [[ENTRY:%.*]] ], [ 100, [[BB]] ] +; NEWGVN-NEXT: [[V3:%.*]] = load i32, i32* [[P]], align 4 +; NEWGVN-NEXT: [[V4:%.*]] = add i32 [[PHI]], [[V3]] +; NEWGVN-NEXT: ret i32 [[V4]] +; +Entry: + %P1 = bitcast i32* %P to <4 x i32>* + %V1 = load <4 x i32>, <4 x i32>* %P1 + %V2 = extractelement <4 x i32> %V1, i64 2 + br i1 %Cond, label %BB, label %Exit + +BB: + store i32 13, i32* %P + br label %Exit + +Exit: + %Phi = phi i32 [ %V2, %Entry ], [ 100, %BB ] + %V3 = load i32, i32* %P + %V4 = add i32 %Phi, %V3 + ret i32 %V4 +} + +define i32 @test17(i32* %P, i32 %V, i1 %cond1, i1 %cond2) { +; Entry __ +; / \ v | +; BB Loop | +; \ / \_| +; vv +; Exit +; +; OLDGVN-LABEL: @test17( +; OLDGVN-NEXT: Entry: +; OLDGVN-NEXT: br i1 [[COND1:%.*]], label [[BB:%.*]], label [[LOOP:%.*]] +; OLDGVN: BB: +; OLDGVN-NEXT: store i32 42, i32* [[P:%.*]], align 4 +; OLDGVN-NEXT: br label [[EXIT:%.*]] +; OLDGVN: Loop: +; OLDGVN-NEXT: [[PHI:%.*]] = phi i32 [ 100, [[ENTRY:%.*]] ], [ [[V1:%.*]], [[LOOP]] ] +; OLDGVN-NEXT: [[V1]] = add i32 [[V:%.*]], [[PHI]] +; OLDGVN-NEXT: br i1 [[COND2:%.*]], label [[LOOP]], label [[LOOP_EXIT_CRIT_EDGE:%.*]] +; OLDGVN: Loop.Exit_crit_edge: +; OLDGVN-NEXT: [[V2_PRE:%.*]] = load i32, i32* [[P]], align 4 +; OLDGVN-NEXT: br label [[EXIT]] +; OLDGVN: Exit: +; OLDGVN-NEXT: [[V2:%.*]] = phi i32 [ [[V2_PRE]], [[LOOP_EXIT_CRIT_EDGE]] ], [ 42, [[BB]] ] +; OLDGVN-NEXT: ret i32 [[V2]] +; +; NEWGVN-LABEL: @test17( +; NEWGVN-NEXT: Entry: +; NEWGVN-NEXT: br i1 [[COND1:%.*]], label [[BB:%.*]], label [[LOOP:%.*]] +; NEWGVN: BB: +; NEWGVN-NEXT: store i32 42, i32* [[P:%.*]], align 4 +; NEWGVN-NEXT: br label [[EXIT:%.*]] +; NEWGVN: Loop: +; NEWGVN-NEXT: [[PHI:%.*]] = phi i32 [ 100, [[ENTRY:%.*]] ], [ [[V1:%.*]], [[LOOP]] ] +; NEWGVN-NEXT: [[V1]] = add i32 [[V:%.*]], [[PHI]] +; NEWGVN-NEXT: br i1 [[COND2:%.*]], label [[LOOP]], label [[EXIT]] +; NEWGVN: Exit: +; NEWGVN-NEXT: [[V2:%.*]] = load i32, i32* [[P]], align 4 +; NEWGVN-NEXT: ret i32 [[V2]] +; +Entry: + br i1 %cond1, label %BB, label %Loop + +BB: + store i32 42, i32* %P + br label %Exit + +Loop: + %phi = phi i32 [ 100, %Entry ], [ %V1, %Loop ] + %V1 = add i32 %V, %phi + br i1 %cond2, label %Loop, label %Exit + +Exit: + %V2 = load i32, i32* %P + ret i32 %V2 +} + +define i32 @test18(i32* %P, i1 %Cond) { +; Entry +; / \ +; T F +; \ / +; vv +; Exit +; +; OLDGVN-LABEL: @test18( +; OLDGVN-NEXT: Entry: +; OLDGVN-NEXT: [[P1:%.*]] = bitcast i32* [[P:%.*]] to <4 x i32>* +; OLDGVN-NEXT: [[V1:%.*]] = load <4 x i32>, <4 x i32>* [[P1]], align 16 +; OLDGVN-NEXT: [[V2:%.*]] = extractelement <4 x i32> [[V1]], i64 2 +; OLDGVN-NEXT: [[TMP0:%.*]] = bitcast <4 x i32> [[V1]] to i128 +; OLDGVN-NEXT: [[TMP1:%.*]] = trunc i128 [[TMP0]] to i32 +; OLDGVN-NEXT: br i1 [[COND:%.*]], label [[T:%.*]], label [[F:%.*]] +; OLDGVN: T: +; OLDGVN-NEXT: br label [[EXIT:%.*]] +; OLDGVN: F: +; OLDGVN-NEXT: store <4 x i32> , <4 x i32>* [[P1]], align 16 +; OLDGVN-NEXT: store i32 100, i32* [[P]], align 4 +; OLDGVN-NEXT: br label [[EXIT]] +; OLDGVN: Exit: +; OLDGVN-NEXT: [[V4:%.*]] = phi i32 [ [[TMP1]], [[T]] ], [ 100, [[F]] ] +; OLDGVN-NEXT: [[PHI:%.*]] = phi i32 [ [[V2]], [[T]] ], [ 13, [[F]] ] +; OLDGVN-NEXT: [[V5:%.*]] = add i32 [[PHI]], [[V4]] +; OLDGVN-NEXT: ret i32 [[V5]] +; +; NEWGVN-LABEL: @test18( +; NEWGVN-NEXT: Entry: +; NEWGVN-NEXT: [[P1:%.*]] = bitcast i32* [[P:%.*]] to <4 x i32>* +; NEWGVN-NEXT: [[V1:%.*]] = load <4 x i32>, <4 x i32>* [[P1]], align 16 +; NEWGVN-NEXT: [[V2:%.*]] = extractelement <4 x i32> [[V1]], i64 2 +; NEWGVN-NEXT: br i1 [[COND:%.*]], label [[T:%.*]], label [[F:%.*]] +; NEWGVN: T: +; NEWGVN-NEXT: br label [[EXIT:%.*]] +; NEWGVN: F: +; NEWGVN-NEXT: store <4 x i32> , <4 x i32>* [[P1]], align 16 +; NEWGVN-NEXT: store i32 100, i32* [[P]], align 4 +; NEWGVN-NEXT: br label [[EXIT]] +; NEWGVN: Exit: +; NEWGVN-NEXT: [[PHI:%.*]] = phi i32 [ [[V2]], [[T]] ], [ 13, [[F]] ] +; NEWGVN-NEXT: [[V4:%.*]] = load i32, i32* [[P]], align 4 +; NEWGVN-NEXT: [[V5:%.*]] = add i32 [[PHI]], [[V4]] +; NEWGVN-NEXT: ret i32 [[V5]] +; +Entry: + %P1 = bitcast i32* %P to <4 x i32>* + %V1 = load <4 x i32>, <4 x i32>* %P1 + %V2 = extractelement <4 x i32> %V1, i64 2 + br i1 %Cond, label %T, label %F + +T: + br label %Exit + +F: + store <4 x i32> , <4 x i32>* %P1 + %V3 = load i32, i32* %P + store i32 100, i32* %P + br label %Exit + +Exit: + %Phi = phi i32 [ %V2, %T ], [ %V3, %F ] + %V4 = load i32, i32* %P + %V5 = add i32 %Phi, %V4 + ret i32 %V5 +} + +define i16 @test19(i32* %P, i32 %V, i1 %Cond) { +; Entry +; / \ +; T F +; \ / +; vv +; Exit +; +; OLDGVN-LABEL: @test19( +; OLDGVN-NEXT: Entry: +; OLDGVN-NEXT: store i32 42, i32* [[P:%.*]], align 4 +; OLDGVN-NEXT: br i1 [[COND:%.*]], label [[T:%.*]], label [[F:%.*]] +; OLDGVN: T: +; OLDGVN-NEXT: [[P1:%.*]] = bitcast i32* [[P]] to i16* +; OLDGVN-NEXT: store i16 13, i16* [[P1]], align 2 +; OLDGVN-NEXT: br label [[EXIT:%.*]] +; OLDGVN: F: +; OLDGVN-NEXT: store i32 [[V:%.*]], i32* [[P]], align 4 +; OLDGVN-NEXT: [[TMP0:%.*]] = trunc i32 [[V]] to i16 +; OLDGVN-NEXT: [[DOTPRE:%.*]] = bitcast i32* [[P]] to i16* +; OLDGVN-NEXT: br label [[EXIT]] +; OLDGVN: Exit: +; OLDGVN-NEXT: [[P2_PRE_PHI:%.*]] = phi i16* [ [[DOTPRE]], [[F]] ], [ [[P1]], [[T]] ] +; OLDGVN-NEXT: [[V2:%.*]] = phi i16 [ [[TMP0]], [[F]] ], [ 13, [[T]] ] +; OLDGVN-NEXT: ret i16 [[V2]] +; +; NEWGVN-LABEL: @test19( +; NEWGVN-NEXT: Entry: +; NEWGVN-NEXT: store i32 42, i32* [[P:%.*]], align 4 +; NEWGVN-NEXT: br i1 [[COND:%.*]], label [[T:%.*]], label [[F:%.*]] +; NEWGVN: T: +; NEWGVN-NEXT: [[P1:%.*]] = bitcast i32* [[P]] to i16* +; NEWGVN-NEXT: store i16 13, i16* [[P1]], align 2 +; NEWGVN-NEXT: br label [[EXIT:%.*]] +; NEWGVN: F: +; NEWGVN-NEXT: store i32 [[V:%.*]], i32* [[P]], align 4 +; NEWGVN-NEXT: br label [[EXIT]] +; NEWGVN: Exit: +; NEWGVN-NEXT: [[P2:%.*]] = bitcast i32* [[P]] to i16* +; NEWGVN-NEXT: [[V2:%.*]] = load i16, i16* [[P2]], align 2 +; NEWGVN-NEXT: ret i16 [[V2]] +; +Entry: + store i32 42, i32* %P + br i1 %Cond, label %T, label %F + +T: + %P1 = bitcast i32* %P to i16* + store i16 13, i16* %P1 + br label %Exit + +F: + store i32 %V, i32* %P + br label %Exit + +Exit: + %P2 = bitcast i32* %P to i16* + %V2 = load i16, i16* %P2 + ret i16 %V2 +} + +define i32 @test20(i32* %P, i1 %cond1, i1 %cond2) { +; Entry +; / \ +; BB1 BB2 +; | | +; BB3 BB4 +; \ / +; vv +; Exit +; +; OLDGVN-LABEL: @test20( +; OLDGVN-NEXT: Entry: +; OLDGVN-NEXT: [[P1:%.*]] = bitcast i32* [[P:%.*]] to <2 x i32>* +; OLDGVN-NEXT: br i1 [[COND1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] +; OLDGVN: BB1: +; OLDGVN-NEXT: store i32 42, i32* [[P]], align 4 +; OLDGVN-NEXT: br label [[EXIT:%.*]] +; OLDGVN: BB2: +; OLDGVN-NEXT: [[V2:%.*]] = load i32, i32* [[P]], align 4 +; OLDGVN-NEXT: [[V5:%.*]] = add i32 [[V2]], 100 +; OLDGVN-NEXT: br label [[EXIT]] +; OLDGVN: Exit: +; OLDGVN-NEXT: [[PHI:%.*]] = phi i32 [ 142, [[BB1]] ], [ [[V5]], [[BB2]] ] +; OLDGVN-NEXT: ret i32 [[PHI]] +; +; NEWGVN-LABEL: @test20( +; NEWGVN-NEXT: Entry: +; NEWGVN-NEXT: [[P1:%.*]] = bitcast i32* [[P:%.*]] to <2 x i32>* +; NEWGVN-NEXT: br i1 [[COND1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] +; NEWGVN: BB1: +; NEWGVN-NEXT: store i32 42, i32* [[P]], align 4 +; NEWGVN-NEXT: br label [[BB3:%.*]] +; NEWGVN: BB2: +; NEWGVN-NEXT: [[V2:%.*]] = load i32, i32* [[P]], align 4 +; NEWGVN-NEXT: br label [[BB4:%.*]] +; NEWGVN: BB3: +; NEWGVN-NEXT: br label [[EXIT:%.*]] +; NEWGVN: BB4: +; NEWGVN-NEXT: [[V5:%.*]] = add i32 [[V2]], 100 +; NEWGVN-NEXT: br label [[EXIT]] +; NEWGVN: Exit: +; NEWGVN-NEXT: [[PHI:%.*]] = phi i32 [ 142, [[BB3]] ], [ [[V5]], [[BB4]] ] +; NEWGVN-NEXT: ret i32 [[PHI]] +; +Entry: + %P1 = bitcast i32* %P to <2 x i32>* + %V1 = load <2 x i32>, <2 x i32>* %P1 + br i1 %cond1, label %BB1, label %BB2 + +BB1: + store i32 42, i32* %P + br label %BB3 + +BB2: + %V2 = load i32, i32* %P + br label %BB4 + +BB3: + %V3 = load i32, i32* %P + %V4 = add i32 %V3, 100 + br label %Exit + +BB4: + %V5 = add i32 %V2, 100 + br label %Exit + +Exit: + %phi = phi i32 [ %V4, %BB3 ], [ %V5, %BB4 ] + ret i32 %phi +} + +define i32 @test21(i32* %P1, i32* %P2, i1 %cond) { +; Entry +; / \ +; T F +; \ / +; vv +; Exit +; +; OLDGVN-LABEL: @test21( +; OLDGVN-NEXT: Entry: +; OLDGVN-NEXT: br i1 [[COND:%.*]], label [[T:%.*]], label [[F:%.*]] +; OLDGVN: T: +; OLDGVN-NEXT: store i32 42, i32* [[P1:%.*]], align 4 +; OLDGVN-NEXT: br label [[EXIT:%.*]] +; OLDGVN: F: +; OLDGVN-NEXT: [[V1_PRE:%.*]] = load i32, i32* [[P1]], align 4 +; OLDGVN-NEXT: br label [[EXIT]] +; OLDGVN: Exit: +; OLDGVN-NEXT: [[V1:%.*]] = phi i32 [ [[V1_PRE]], [[F]] ], [ 42, [[T]] ] +; OLDGVN-NEXT: [[V2:%.*]] = load i32, i32* [[P2:%.*]], align 4 +; OLDGVN-NEXT: [[V3:%.*]] = add i32 [[V1]], [[V2]] +; OLDGVN-NEXT: ret i32 [[V3]] +; +; NEWGVN-LABEL: @test21( +; NEWGVN-NEXT: Entry: +; NEWGVN-NEXT: br i1 [[COND:%.*]], label [[T:%.*]], label [[F:%.*]] +; NEWGVN: T: +; NEWGVN-NEXT: store i32 42, i32* [[P1:%.*]], align 4 +; NEWGVN-NEXT: br label [[EXIT:%.*]] +; NEWGVN: F: +; NEWGVN-NEXT: br label [[EXIT]] +; NEWGVN: Exit: +; NEWGVN-NEXT: [[V1:%.*]] = load i32, i32* [[P1]], align 4 +; NEWGVN-NEXT: [[V2:%.*]] = load i32, i32* [[P2:%.*]], align 4 +; NEWGVN-NEXT: [[V3:%.*]] = add i32 [[V1]], [[V2]] +; NEWGVN-NEXT: ret i32 [[V3]] +; +Entry: + br i1 %cond, label %T, label %F + +T: + store i32 42, i32* %P1 + br label %Exit + +F: + br label %Exit + +Exit: + %V1 = load i32, i32* %P1 + %V2 = load i32, i32* %P2 + %V3 = add i32 %V1, %V2 + ret i32 %V3 +} + +define i32 @test22(i32* %P1, i32* %P2, i1 %cond) { +; Entry +; / \ +; T F +; \ / +; vv +; Exit +; +; OLDGVN-LABEL: @test22( +; OLDGVN-NEXT: Entry: +; OLDGVN-NEXT: br i1 [[COND:%.*]], label [[T:%.*]], label [[F:%.*]] +; OLDGVN: T: +; OLDGVN-NEXT: store i32 42, i32* [[P1:%.*]], align 4 +; OLDGVN-NEXT: [[V2_PRE:%.*]] = load i32, i32* [[P2:%.*]], align 4 +; OLDGVN-NEXT: br label [[EXIT:%.*]] +; OLDGVN: F: +; OLDGVN-NEXT: store i32 13, i32* [[P2]], align 4 +; OLDGVN-NEXT: [[V1_PRE:%.*]] = load i32, i32* [[P1]], align 4 +; OLDGVN-NEXT: br label [[EXIT]] +; OLDGVN: Exit: +; OLDGVN-NEXT: [[V2:%.*]] = phi i32 [ 13, [[F]] ], [ [[V2_PRE]], [[T]] ] +; OLDGVN-NEXT: [[V1:%.*]] = phi i32 [ [[V1_PRE]], [[F]] ], [ 42, [[T]] ] +; OLDGVN-NEXT: [[V3:%.*]] = add i32 [[V1]], [[V2]] +; OLDGVN-NEXT: ret i32 [[V3]] +; +; NEWGVN-LABEL: @test22( +; NEWGVN-NEXT: Entry: +; NEWGVN-NEXT: br i1 [[COND:%.*]], label [[T:%.*]], label [[F:%.*]] +; NEWGVN: T: +; NEWGVN-NEXT: store i32 42, i32* [[P1:%.*]], align 4 +; NEWGVN-NEXT: br label [[EXIT:%.*]] +; NEWGVN: F: +; NEWGVN-NEXT: store i32 13, i32* [[P2:%.*]], align 4 +; NEWGVN-NEXT: br label [[EXIT]] +; NEWGVN: Exit: +; NEWGVN-NEXT: [[V1:%.*]] = load i32, i32* [[P1]], align 4 +; NEWGVN-NEXT: [[V2:%.*]] = load i32, i32* [[P2]], align 4 +; NEWGVN-NEXT: [[V3:%.*]] = add i32 [[V1]], [[V2]] +; NEWGVN-NEXT: ret i32 [[V3]] +; +Entry: + br i1 %cond, label %T, label %F + +T: + store i32 42, i32* %P1 + br label %Exit + +F: + store i32 13, i32* %P2 + br label %Exit + +Exit: + %V1 = load i32, i32* %P1 + %V2 = load i32, i32* %P2 + %V3 = add i32 %V1, %V2 + ret i32 %V3 +} + +define i32 @test23(i32* %P, i1 %cond1, i1 %cond2) { +; Entry +; / \ +; T F +; | / \ +; | F1 F2 +; \ / / +; v v +; Exit +; +; GVN-LABEL: @test23( +; GVN-NEXT: Entry: +; GVN-NEXT: [[P1:%.*]] = bitcast i32* [[P:%.*]] to <2 x i32>* +; GVN-NEXT: br i1 [[COND1:%.*]], label [[T:%.*]], label [[F:%.*]] +; GVN: T: +; GVN-NEXT: store i32 42, i32* [[P]], align 4 +; GVN-NEXT: br label [[EXIT:%.*]] +; GVN: F: +; GVN-NEXT: br i1 [[COND2:%.*]], label [[F1:%.*]], label [[F2:%.*]] +; GVN: F1: +; GVN-NEXT: br label [[EXIT]] +; GVN: F2: +; GVN-NEXT: br label [[EXIT]] +; GVN: Exit: +; GVN-NEXT: [[V3:%.*]] = load i32, i32* [[P]], align 4 +; GVN-NEXT: ret i32 [[V3]] +; +Entry: + %P1 = bitcast i32* %P to <2 x i32>* + %V1 = load <2 x i32>, <2 x i32>* %P1 + br i1 %cond1, label %T, label %F + +T: + store i32 42, i32* %P + br label %Exit + +F: + br i1 %cond2, label %F1, label %F2 + +F1: + %V2 = load i32, i32* %P + br label %Exit + +F2: + br label %Exit + +Exit: + %V3 = load i32, i32* %P + ret i32 %V3 +} + +define i32 @test24(i32* %P, i1 %cond1, i1 %cond2) { +; Entry +; / \ +; T F +; | / \ +; | F1 F2 +; | / | +; BB | +; \ / +; vv +; Exit +; +; OLDGVN-LABEL: @test24( +; OLDGVN-NEXT: Entry: +; OLDGVN-NEXT: [[P1:%.*]] = bitcast i32* [[P:%.*]] to <2 x i32>* +; OLDGVN-NEXT: br i1 [[COND1:%.*]], label [[T:%.*]], label [[F:%.*]] +; OLDGVN: T: +; OLDGVN-NEXT: store i32 42, i32* [[P]], align 4 +; OLDGVN-NEXT: br label [[BB:%.*]] +; OLDGVN: F: +; OLDGVN-NEXT: br i1 [[COND2:%.*]], label [[F1:%.*]], label [[F2:%.*]] +; OLDGVN: F1: +; OLDGVN-NEXT: [[V3_PRE:%.*]] = load i32, i32* [[P]], align 4 +; OLDGVN-NEXT: br label [[BB]] +; OLDGVN: F2: +; OLDGVN-NEXT: br label [[EXIT:%.*]] +; OLDGVN: BB: +; OLDGVN-NEXT: [[V3:%.*]] = phi i32 [ [[V3_PRE]], [[F1]] ], [ 42, [[T]] ] +; OLDGVN-NEXT: br label [[EXIT]] +; OLDGVN: Exit: +; OLDGVN-NEXT: [[PHI:%.*]] = phi i32 [ [[V3]], [[BB]] ], [ 100, [[F2]] ] +; OLDGVN-NEXT: ret i32 [[PHI]] +; +; NEWGVN-LABEL: @test24( +; NEWGVN-NEXT: Entry: +; NEWGVN-NEXT: [[P1:%.*]] = bitcast i32* [[P:%.*]] to <2 x i32>* +; NEWGVN-NEXT: br i1 [[COND1:%.*]], label [[T:%.*]], label [[F:%.*]] +; NEWGVN: T: +; NEWGVN-NEXT: store i32 42, i32* [[P]], align 4 +; NEWGVN-NEXT: br label [[BB:%.*]] +; NEWGVN: F: +; NEWGVN-NEXT: br i1 [[COND2:%.*]], label [[F1:%.*]], label [[F2:%.*]] +; NEWGVN: F1: +; NEWGVN-NEXT: br label [[BB]] +; NEWGVN: F2: +; NEWGVN-NEXT: br label [[EXIT:%.*]] +; NEWGVN: BB: +; NEWGVN-NEXT: [[V3:%.*]] = load i32, i32* [[P]], align 4 +; NEWGVN-NEXT: br label [[EXIT]] +; NEWGVN: Exit: +; NEWGVN-NEXT: [[PHI:%.*]] = phi i32 [ [[V3]], [[BB]] ], [ 100, [[F2]] ] +; NEWGVN-NEXT: ret i32 [[PHI]] +; +Entry: + %P1 = bitcast i32* %P to <2 x i32>* + %V1 = load <2 x i32>, <2 x i32>* %P1 + br i1 %cond1, label %T, label %F + +T: + store i32 42, i32* %P + br label %BB + +F: + br i1 %cond2, label %F1, label %F2 + +F1: + %V2 = load i32, i32* %P + br label %BB + +F2: + br label %Exit + +BB: + %V3 = load i32, i32* %P + br label %Exit + +Exit: + %phi = phi i32 [ %V3, %BB ], [ 100, %F2 ] + ret i32 %phi +} + +define i8 @test25(i32 %V1, i32* %P1, i1 %Cond) { +; Entry +; / \ +; T F +; \ / +; vv +; Exit +; +; OLDGVN-LABEL: @test25( +; OLDGVN-NEXT: Entry: +; OLDGVN-NEXT: br i1 [[COND:%.*]], label [[T:%.*]], label [[F:%.*]] +; OLDGVN: T: +; OLDGVN-NEXT: store i32 [[V1:%.*]], i32* [[P1:%.*]], align 4 +; OLDGVN-NEXT: [[TMP0:%.*]] = lshr i32 [[V1]], 16 +; OLDGVN-NEXT: [[TMP1:%.*]] = trunc i32 [[TMP0]] to i8 +; OLDGVN-NEXT: [[DOTPRE:%.*]] = bitcast i32* [[P1]] to i8* +; OLDGVN-NEXT: br label [[EXIT:%.*]] +; OLDGVN: F: +; OLDGVN-NEXT: [[P2_PHI_TRANS_INSERT:%.*]] = bitcast i32* [[P1]] to i8* +; OLDGVN-NEXT: [[GEP_PHI_TRANS_INSERT:%.*]] = getelementptr i8, i8* [[P2_PHI_TRANS_INSERT]], i32 2 +; OLDGVN-NEXT: [[V2_PRE:%.*]] = load i8, i8* [[GEP_PHI_TRANS_INSERT]], align 1 +; OLDGVN-NEXT: br label [[EXIT]] +; OLDGVN: Exit: +; OLDGVN-NEXT: [[P2_PRE_PHI:%.*]] = phi i8* [ [[P2_PHI_TRANS_INSERT]], [[F]] ], [ [[DOTPRE]], [[T]] ] +; OLDGVN-NEXT: [[V2:%.*]] = phi i8 [ [[TMP1]], [[T]] ], [ [[V2_PRE]], [[F]] ] +; OLDGVN-NEXT: [[PHI:%.*]] = phi i8 [ 0, [[T]] ], [ 100, [[F]] ] +; OLDGVN-NEXT: [[GEP:%.*]] = getelementptr i8, i8* [[P2_PRE_PHI]], i32 2 +; OLDGVN-NEXT: [[V3:%.*]] = add i8 [[PHI]], [[V2]] +; OLDGVN-NEXT: ret i8 [[V3]] +; +; NEWGVN-LABEL: @test25( +; NEWGVN-NEXT: Entry: +; NEWGVN-NEXT: br i1 [[COND:%.*]], label [[T:%.*]], label [[F:%.*]] +; NEWGVN: T: +; NEWGVN-NEXT: store i32 [[V1:%.*]], i32* [[P1:%.*]], align 4 +; NEWGVN-NEXT: br label [[EXIT:%.*]] +; NEWGVN: F: +; NEWGVN-NEXT: br label [[EXIT]] +; NEWGVN: Exit: +; NEWGVN-NEXT: [[PHI:%.*]] = phi i8 [ 0, [[T]] ], [ 100, [[F]] ] +; NEWGVN-NEXT: [[P2:%.*]] = bitcast i32* [[P1]] to i8* +; NEWGVN-NEXT: [[GEP:%.*]] = getelementptr i8, i8* [[P2]], i32 2 +; NEWGVN-NEXT: [[V2:%.*]] = load i8, i8* [[GEP]], align 1 +; NEWGVN-NEXT: [[V3:%.*]] = add i8 [[PHI]], [[V2]] +; NEWGVN-NEXT: ret i8 [[V3]] +; +Entry: + br i1 %Cond, label %T, label %F + +T: + store i32 %V1, i32* %P1 + br label %Exit + +F: + br label %Exit + +Exit: + %Phi = phi i8 [ 0, %T ], [ 100, %F ] + %P2 = bitcast i32* %P1 to i8* + %Gep = getelementptr i8, i8* %P2, i32 2 + %V2 = load i8, i8* %Gep + %V3 = add i8 %Phi, %V2 + ret i8 %V3 +} + +define i8 @test26(i32* %P1, i1 %Cond) { +; Entry +; / \ +; T F +; \ / +; vv +; Exit +; +; OLDGVN-LABEL: @test26( +; OLDGVN-NEXT: Entry: +; OLDGVN-NEXT: br i1 [[COND:%.*]], label [[T:%.*]], label [[F:%.*]] +; OLDGVN: T: +; OLDGVN-NEXT: [[V1:%.*]] = load i32, i32* [[P1:%.*]], align 4 +; OLDGVN-NEXT: [[V2:%.*]] = lshr i32 [[V1]], 16 +; OLDGVN-NEXT: [[V3:%.*]] = trunc i32 [[V2]] to i8 +; OLDGVN-NEXT: [[DOTPRE:%.*]] = bitcast i32* [[P1]] to i8* +; OLDGVN-NEXT: br label [[EXIT:%.*]] +; OLDGVN: F: +; OLDGVN-NEXT: [[P2_PHI_TRANS_INSERT:%.*]] = bitcast i32* [[P1]] to i8* +; OLDGVN-NEXT: [[GEP_PHI_TRANS_INSERT:%.*]] = getelementptr i8, i8* [[P2_PHI_TRANS_INSERT]], i32 2 +; OLDGVN-NEXT: [[V4_PRE:%.*]] = load i8, i8* [[GEP_PHI_TRANS_INSERT]], align 1 +; OLDGVN-NEXT: br label [[EXIT]] +; OLDGVN: Exit: +; OLDGVN-NEXT: [[P2_PRE_PHI:%.*]] = phi i8* [ [[P2_PHI_TRANS_INSERT]], [[F]] ], [ [[DOTPRE]], [[T]] ] +; OLDGVN-NEXT: [[V4:%.*]] = phi i8 [ [[V3]], [[T]] ], [ [[V4_PRE]], [[F]] ] +; OLDGVN-NEXT: [[PHI:%.*]] = phi i8 [ [[V3]], [[T]] ], [ 100, [[F]] ] +; OLDGVN-NEXT: [[GEP:%.*]] = getelementptr i8, i8* [[P2_PRE_PHI]], i32 2 +; OLDGVN-NEXT: [[V5:%.*]] = add i8 [[PHI]], [[V4]] +; OLDGVN-NEXT: ret i8 [[V5]] +; +; NEWGVN-LABEL: @test26( +; NEWGVN-NEXT: Entry: +; NEWGVN-NEXT: br i1 [[COND:%.*]], label [[T:%.*]], label [[F:%.*]] +; NEWGVN: T: +; NEWGVN-NEXT: [[V1:%.*]] = load i32, i32* [[P1:%.*]], align 4 +; NEWGVN-NEXT: [[V2:%.*]] = lshr i32 [[V1]], 16 +; NEWGVN-NEXT: [[V3:%.*]] = trunc i32 [[V2]] to i8 +; NEWGVN-NEXT: br label [[EXIT:%.*]] +; NEWGVN: F: +; NEWGVN-NEXT: br label [[EXIT]] +; NEWGVN: Exit: +; NEWGVN-NEXT: [[PHI:%.*]] = phi i8 [ [[V3]], [[T]] ], [ 100, [[F]] ] +; NEWGVN-NEXT: [[P2:%.*]] = bitcast i32* [[P1]] to i8* +; NEWGVN-NEXT: [[GEP:%.*]] = getelementptr i8, i8* [[P2]], i32 2 +; NEWGVN-NEXT: [[V4:%.*]] = load i8, i8* [[GEP]], align 1 +; NEWGVN-NEXT: [[V5:%.*]] = add i8 [[PHI]], [[V4]] +; NEWGVN-NEXT: ret i8 [[V5]] +; +Entry: + br i1 %Cond, label %T, label %F + +T: + %V1 = load i32, i32* %P1 + %V2 = lshr i32 %V1, 16 + %V3 = trunc i32 %V2 to i8 + br label %Exit + +F: + br label %Exit + +Exit: + %Phi = phi i8 [ %V3, %T ], [ 100, %F ] + %P2 = bitcast i32* %P1 to i8* + %Gep = getelementptr i8, i8* %P2, i32 2 + %V4 = load i8, i8* %Gep + %V5 = add i8 %Phi, %V4 + ret i8 %V5 +} + +define i32 @test27(i32 *%P1, i1 %Cond1, i1 %Cond2) { +; Entry +; / \ +; T1 F1 +; \ / +; BB1 +; / \ +; T2 F2 +; \ / +; BB2 +; | +; v +; Exit +; +; OLDGVN-LABEL: @test27( +; OLDGVN-NEXT: Entry: +; OLDGVN-NEXT: br i1 [[COND1:%.*]], label [[T1:%.*]], label [[F1:%.*]] +; OLDGVN: T1: +; OLDGVN-NEXT: br label [[BB1:%.*]] +; OLDGVN: F1: +; OLDGVN-NEXT: br label [[BB1]] +; OLDGVN: BB1: +; OLDGVN-NEXT: [[PHI1:%.*]] = phi i32 [ 5, [[T1]] ], [ 7, [[F1]] ] +; OLDGVN-NEXT: [[LD1:%.*]] = load i32, i32* [[P1:%.*]], align 4 +; OLDGVN-NEXT: [[M1:%.*]] = mul i32 [[LD1]], 5 +; OLDGVN-NEXT: [[M2:%.*]] = mul i32 [[LD1]], 7 +; OLDGVN-NEXT: [[A1:%.*]] = add i32 [[M1]], [[M2]] +; OLDGVN-NEXT: br i1 [[COND2:%.*]], label [[T2:%.*]], label [[F2:%.*]] +; OLDGVN: T2: +; OLDGVN-NEXT: br label [[BB2:%.*]] +; OLDGVN: F2: +; OLDGVN-NEXT: br label [[BB2]] +; OLDGVN: BB2: +; OLDGVN-NEXT: [[M3_PRE_PHI:%.*]] = phi i32 [ [[M2]], [[F2]] ], [ [[M1]], [[T2]] ] +; OLDGVN-NEXT: [[PHI2:%.*]] = phi i32 [ 5, [[T2]] ], [ 7, [[F2]] ] +; OLDGVN-NEXT: [[A2:%.*]] = add i32 [[A1]], [[PHI1]] +; OLDGVN-NEXT: [[A3:%.*]] = add i32 [[M3_PRE_PHI]], [[A2]] +; OLDGVN-NEXT: ret i32 [[A3]] +; +; NEWGVN-LABEL: @test27( +; NEWGVN-NEXT: Entry: +; NEWGVN-NEXT: br i1 [[COND1:%.*]], label [[T1:%.*]], label [[F1:%.*]] +; NEWGVN: T1: +; NEWGVN-NEXT: br label [[BB1:%.*]] +; NEWGVN: F1: +; NEWGVN-NEXT: br label [[BB1]] +; NEWGVN: BB1: +; NEWGVN-NEXT: [[PHI1:%.*]] = phi i32 [ 5, [[T1]] ], [ 7, [[F1]] ] +; NEWGVN-NEXT: [[LD1:%.*]] = load i32, i32* [[P1:%.*]], align 4 +; NEWGVN-NEXT: [[M1:%.*]] = mul i32 [[LD1]], 5 +; NEWGVN-NEXT: [[M2:%.*]] = mul i32 [[LD1]], 7 +; NEWGVN-NEXT: [[A1:%.*]] = add i32 [[M1]], [[M2]] +; NEWGVN-NEXT: br i1 [[COND2:%.*]], label [[T2:%.*]], label [[F2:%.*]] +; NEWGVN: T2: +; NEWGVN-NEXT: br label [[BB2:%.*]] +; NEWGVN: F2: +; NEWGVN-NEXT: br label [[BB2]] +; NEWGVN: BB2: +; NEWGVN-NEXT: [[PHI2:%.*]] = phi i32 [ 5, [[T2]] ], [ 7, [[F2]] ] +; NEWGVN-NEXT: br label [[EXIT:%.*]] +; NEWGVN: Exit: +; NEWGVN-NEXT: [[M3:%.*]] = mul i32 [[LD1]], [[PHI2]] +; NEWGVN-NEXT: [[A2:%.*]] = add i32 [[A1]], [[PHI1]] +; NEWGVN-NEXT: [[A3:%.*]] = add i32 [[M3]], [[A2]] +; NEWGVN-NEXT: ret i32 [[A3]] +; +Entry: + br i1 %Cond1, label %T1, label %F1 + +T1: + br label %BB1 + +F1: + br label %BB1 + +BB1: + %Phi1 = phi i32 [ 5, %T1 ], [ 7, %F1 ] + %Ld1 = load i32, i32 *%P1 + %M1 = mul i32 %Ld1, 5 + %M2 = mul i32 %Ld1, 7 + %A1 = add i32 %M1, %M2 + br i1 %Cond2, label %T2, label %F2 + +T2: + br label %BB2 + +F2: + br label %BB2 + +BB2: + %Phi2 = phi i32 [ 5, %T2 ], [ 7, %F2 ] + br label %Exit + +Exit: + %Ld2 = load i32, i32 *%P1 + %M3 = mul i32 %Ld2, %Phi2 + %A2 = add i32 %A1, %Phi1 + %A3 = add i32 %M3, %A2 + ret i32 %A3 +} + +define i32 @test28(i32* %P, i32 %V1, i1 %Cond1, i1 %Cond2) { +; Entry +; / \ +; T F +; / \ | +; BB1 BB2 | +; \ | / +; v v v +; Exit +; +; OLDGVN-LABEL: @test28( +; OLDGVN-NEXT: Entry: +; OLDGVN-NEXT: br i1 [[COND1:%.*]], label [[T:%.*]], label [[F:%.*]] +; OLDGVN: T: +; OLDGVN-NEXT: store i32 [[V1:%.*]], i32* [[P:%.*]], align 4 +; OLDGVN-NEXT: br i1 [[COND2:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] +; OLDGVN: F: +; OLDGVN-NEXT: store i32 13, i32* [[P]], align 4 +; OLDGVN-NEXT: br label [[EXIT:%.*]] +; OLDGVN: BB1: +; OLDGVN-NEXT: [[V2:%.*]] = add i32 [[V1]], 100 +; OLDGVN-NEXT: br label [[EXIT]] +; OLDGVN: BB2: +; OLDGVN-NEXT: [[V3:%.*]] = add i32 [[V1]], 13 +; OLDGVN-NEXT: br label [[EXIT]] +; OLDGVN: Exit: +; OLDGVN-NEXT: [[V4:%.*]] = phi i32 [ 13, [[F]] ], [ [[V1]], [[BB1]] ], [ [[V1]], [[BB2]] ] +; OLDGVN-NEXT: [[PHI:%.*]] = phi i32 [ 10, [[F]] ], [ [[V2]], [[BB1]] ], [ [[V3]], [[BB2]] ] +; OLDGVN-NEXT: [[V5:%.*]] = add i32 [[PHI]], [[V4]] +; OLDGVN-NEXT: ret i32 [[V5]] +; +; NEWGVN-LABEL: @test28( +; NEWGVN-NEXT: Entry: +; NEWGVN-NEXT: br i1 [[COND1:%.*]], label [[T:%.*]], label [[F:%.*]] +; NEWGVN: T: +; NEWGVN-NEXT: store i32 [[V1:%.*]], i32* [[P:%.*]], align 4 +; NEWGVN-NEXT: br i1 [[COND2:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] +; NEWGVN: F: +; NEWGVN-NEXT: store i32 13, i32* [[P]], align 4 +; NEWGVN-NEXT: br label [[EXIT:%.*]] +; NEWGVN: BB1: +; NEWGVN-NEXT: [[V2:%.*]] = add i32 [[V1]], 100 +; NEWGVN-NEXT: br label [[EXIT]] +; NEWGVN: BB2: +; NEWGVN-NEXT: [[V3:%.*]] = add i32 [[V1]], 13 +; NEWGVN-NEXT: br label [[EXIT]] +; NEWGVN: Exit: +; NEWGVN-NEXT: [[PHI:%.*]] = phi i32 [ 10, [[F]] ], [ [[V2]], [[BB1]] ], [ [[V3]], [[BB2]] ] +; NEWGVN-NEXT: [[V4:%.*]] = load i32, i32* [[P]], align 4 +; NEWGVN-NEXT: [[V5:%.*]] = add i32 [[PHI]], [[V4]] +; NEWGVN-NEXT: ret i32 [[V5]] +; +Entry: + br i1 %Cond1, label %T, label %F + +T: + store i32 %V1, i32* %P + br i1 %Cond2, label %BB1, label %BB2 + +F: + store i32 13, i32* %P + br label %Exit + +BB1: + %V2 = add i32 %V1, 100 + br label %Exit + +BB2: + %V3 = add i32 %V1, 13 + br label %Exit + +Exit: + %Phi = phi i32 [ 10, %F ], [ %V2, %BB1 ], [ %V3, %BB2 ] + %V4 = load i32, i32* %P + %V5 = add i32 %Phi, %V4 + ret i32 %V5 +} + +define dso_local i32 @test29(i1 %Cond, i64 %TC) align 32 { +; Entry +; | +; Loop<-----+ +; / \ | +; T F | +; \ / | +; Loop.Latch--+ +; | +; v +; Exit +; +; OLDGVN-LABEL: @test29( +; OLDGVN-NEXT: Entry: +; OLDGVN-NEXT: br label [[LOOP:%.*]] +; OLDGVN: Loop: +; OLDGVN-NEXT: [[INDEX:%.*]] = phi i64 [ 1, [[ENTRY:%.*]] ], [ [[INDEX_INC:%.*]], [[LOOP_LATCH:%.*]] ] +; OLDGVN-NEXT: br i1 [[COND:%.*]], label [[T:%.*]], label [[F:%.*]] +; OLDGVN: T: +; OLDGVN-NEXT: store i32 undef, i32* null, align 4 +; OLDGVN-NEXT: br label [[LOOP_LATCH]] +; OLDGVN: F: +; OLDGVN-NEXT: store i32 undef, i32* undef, align 4 +; OLDGVN-NEXT: [[V0_PRE:%.*]] = load i32, i32* null, align 4 +; OLDGVN-NEXT: br label [[LOOP_LATCH]] +; OLDGVN: Loop.Latch: +; OLDGVN-NEXT: [[V0:%.*]] = phi i32 [ [[V0_PRE]], [[F]] ], [ undef, [[T]] ] +; OLDGVN-NEXT: [[V1:%.*]] = xor i32 [[V0]], -1 +; OLDGVN-NEXT: [[INDEX_INC]] = add i64 [[INDEX]], 1 +; OLDGVN-NEXT: [[COND2:%.*]] = icmp ne i64 [[INDEX_INC]], [[TC:%.*]] +; OLDGVN-NEXT: br i1 [[COND2]], label [[LOOP]], label [[EXIT:%.*]] +; OLDGVN: Exit: +; OLDGVN-NEXT: ret i32 [[V1]] +; +; NEWGVN-LABEL: @test29( +; NEWGVN-NEXT: Entry: +; NEWGVN-NEXT: br label [[LOOP:%.*]] +; NEWGVN: Loop: +; NEWGVN-NEXT: [[INDEX:%.*]] = phi i64 [ 1, [[ENTRY:%.*]] ], [ [[INDEX_INC:%.*]], [[LOOP_LATCH:%.*]] ] +; NEWGVN-NEXT: br i1 [[COND:%.*]], label [[T:%.*]], label [[F:%.*]] +; NEWGVN: T: +; NEWGVN-NEXT: store i32 undef, i32* null, align 4 +; NEWGVN-NEXT: br label [[LOOP_LATCH]] +; NEWGVN: F: +; NEWGVN-NEXT: store i32 undef, i32* undef, align 4 +; NEWGVN-NEXT: br label [[LOOP_LATCH]] +; NEWGVN: Loop.Latch: +; NEWGVN-NEXT: [[V0:%.*]] = load i32, i32* null, align 4 +; NEWGVN-NEXT: [[V1:%.*]] = xor i32 [[V0]], -1 +; NEWGVN-NEXT: [[INDEX_INC]] = add i64 [[INDEX]], 1 +; NEWGVN-NEXT: [[COND2:%.*]] = icmp ne i64 [[INDEX_INC]], [[TC:%.*]] +; NEWGVN-NEXT: br i1 [[COND2]], label [[LOOP]], label [[EXIT:%.*]] +; NEWGVN: Exit: +; NEWGVN-NEXT: ret i32 [[V1]] +; +Entry: + br label %Loop + +Loop: + %Index = phi i64 [ 1, %Entry ], [ %Index.inc, %Loop.Latch ] + br i1 %Cond, label %T, label %F + +T: + store i32 undef, i32* null, align 4 + br label %Loop.Latch + +F: + store i32 undef, i32* undef, align 4 + br label %Loop.Latch + +Loop.Latch: + %Phi = phi i32* [ null, %T ], [ undef, %F ] + %V0 = load i32, i32* %Phi, align 4 + %V1 = xor i32 %V0, -1 + %Index.inc = add i64 %Index, 1 + %Cond2 = icmp ne i64 %Index.inc, %TC + br i1 %Cond2, label %Loop, label %Exit + +Exit: + ret i32 %V1 +} + +define void @test30(float* nocapture %P1, float %V1) local_unnamed_addr { +; Entry _ +; | / | +; | v | +; Loop | +; | \__| +; | +; v +; Exit +; +; GVN-LABEL: @test30( +; GVN-NEXT: Entry: +; GVN-NEXT: br label [[LOOP:%.*]] +; GVN: Loop: +; GVN-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDEX_INC:%.*]], [[LOOP]] ] +; GVN-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, float* [[P1:%.*]], i64 [[INDEX]] +; GVN-NEXT: [[V2:%.*]] = load float, float* [[ARRAYIDX]], align 4 +; GVN-NEXT: [[V3:%.*]] = fdiv fast float [[V2]], [[V1:%.*]] +; GVN-NEXT: store float [[V3]], float* [[ARRAYIDX]], align 4 +; GVN-NEXT: [[INDEX_INC]] = add nuw nsw i64 [[INDEX]], 1 +; GVN-NEXT: [[COND:%.*]] = icmp eq i64 [[INDEX_INC]], 1024 +; GVN-NEXT: br i1 [[COND]], label [[EXIT:%.*]], label [[LOOP]] +; GVN: Exit: +; GVN-NEXT: ret void +; +Entry: + br label %Loop + +Loop: + %Index = phi i64 [ 0, %Entry ], [ %Index.inc, %Loop ] + %Arrayidx = getelementptr inbounds float, float* %P1, i64 %Index + %V2 = load float, float* %Arrayidx, align 4 + %V3 = fdiv fast float %V2, %V1 + store float %V3, float* %Arrayidx, align 4 + %Index.inc = add nuw nsw i64 %Index, 1 + %Cond = icmp eq i64 %Index.inc, 1024 + br i1 %Cond, label %Exit, label %Loop + +Exit: + ret void +} + +define i32 @test31(i32* %P1, i32* %P2, i32 %V1) { +; Entry +; / | +; T | +; \ | +; F +; | +; BB +; | +; v +; Exit +; +; OLDGVN-LABEL: @test31( +; OLDGVN-NEXT: Entry: +; OLDGVN-NEXT: [[COND:%.*]] = icmp eq i32 [[V1:%.*]], 0 +; OLDGVN-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]] +; OLDGVN: T: +; OLDGVN-NEXT: [[V2:%.*]] = load i32, i32* [[P1:%.*]], align 4 +; OLDGVN-NEXT: store i32 [[V2]], i32* [[P2:%.*]], align 4 +; OLDGVN-NEXT: br label [[F]] +; OLDGVN: F: +; OLDGVN-NEXT: [[PHI:%.*]] = phi i32 [ [[V2]], [[T]] ], [ [[V1]], [[ENTRY:%.*]] ] +; OLDGVN-NEXT: [[V3:%.*]] = add i32 [[PHI]], 100 +; OLDGVN-NEXT: [[V4:%.*]] = add i32 [[V3]], [[V1]] +; OLDGVN-NEXT: [[V5:%.*]] = load i32, i32* [[P1]], align 4 +; OLDGVN-NEXT: [[V6:%.*]] = add i32 [[V5]], [[V4]] +; OLDGVN-NEXT: ret i32 [[V6]] +; +; NEWGVN-LABEL: @test31( +; NEWGVN-NEXT: Entry: +; NEWGVN-NEXT: [[COND:%.*]] = icmp eq i32 [[V1:%.*]], 0 +; NEWGVN-NEXT: br i1 [[COND]], label [[T:%.*]], label [[F:%.*]] +; NEWGVN: T: +; NEWGVN-NEXT: [[V2:%.*]] = load i32, i32* [[P1:%.*]], align 4 +; NEWGVN-NEXT: store i32 [[V2]], i32* [[P2:%.*]], align 4 +; NEWGVN-NEXT: br label [[F]] +; NEWGVN: F: +; NEWGVN-NEXT: [[PHI:%.*]] = phi i32 [ [[V2]], [[T]] ], [ [[V1]], [[ENTRY:%.*]] ] +; NEWGVN-NEXT: [[V3:%.*]] = add i32 [[PHI]], 100 +; NEWGVN-NEXT: br label [[BB:%.*]] +; NEWGVN: BB: +; NEWGVN-NEXT: [[V4:%.*]] = add i32 [[V3]], [[V1]] +; NEWGVN-NEXT: br label [[EXIT:%.*]] +; NEWGVN: Exit: +; NEWGVN-NEXT: [[V5:%.*]] = load i32, i32* [[P1]], align 4 +; NEWGVN-NEXT: [[V6:%.*]] = add i32 [[V5]], [[V4]] +; NEWGVN-NEXT: ret i32 [[V6]] +; +Entry: + %Cond = icmp eq i32 %V1, 0 + br i1 %Cond, label %T, label %F + +T: + %V2 = load i32, i32* %P1, align 4 + store i32 %V2, i32* %P2, align 4 + br label %F + +F: + %Phi = phi i32 [ %V2, %T ], [ %V1, %Entry ] + %V3 = add i32 %Phi, 100 + br label %BB + +BB: + %V4 = add i32 %V3, %V1 + br label %Exit + +Exit: + %V5 = load i32, i32* %P1, align 4 + %V6 = add i32 %V5, %V4 + ret i32 %V6 +} + +define i64 @test32(i64* %P, i64 %TC) { +; Entry _ +; | / | +; | v | +; Loop | +; | \__| +; | +; v +; Exit +; +; GVN-LABEL: @test32( +; GVN-NEXT: Entry: +; GVN-NEXT: br label [[LOOP:%.*]] +; GVN: Loop: +; GVN-NEXT: [[INDEX:%.*]] = phi i64 [ 1, [[ENTRY:%.*]] ], [ [[INDEX_INC:%.*]], [[LOOP]] ] +; GVN-NEXT: [[P1:%.*]] = getelementptr i64, i64* [[P:%.*]], i64 [[INDEX]] +; GVN-NEXT: store i64 [[INDEX]], i64* [[P1]], align 4 +; GVN-NEXT: [[V1:%.*]] = load i64, i64* [[P]], align 4 +; GVN-NEXT: [[INDEX_INC]] = add i64 [[INDEX]], 1 +; GVN-NEXT: [[COND:%.*]] = icmp ne i64 [[INDEX_INC]], [[TC:%.*]] +; GVN-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]] +; GVN: Exit: +; GVN-NEXT: ret i64 [[V1]] +; +Entry: + br label %Loop + +Loop: + %Index = phi i64 [ 1, %Entry ], [ %Index.inc, %Loop ] + %P1 = getelementptr i64, i64* %P, i64 %Index + store i64 %Index, i64* %P1 + %V1 = load i64, i64* %P + %Index.inc = add i64 %Index, 1 + %Cond = icmp ne i64 %Index.inc, %TC + br i1 %Cond, label %Loop, label %Exit + +Exit: + ret i64 %V1 +} + +define i64 @test33(i64* %P, i64 %TC, i1 %Cond1) { +; Entry +; | +; Loop<-----+ +; / \ | +; T F | +; \ / | +; Loop.Latch--+ +; | +; v +; Exit +; +; GVN-LABEL: @test33( +; GVN-NEXT: Entry: +; GVN-NEXT: br label [[LOOP:%.*]] +; GVN: Loop: +; GVN-NEXT: [[INDEX:%.*]] = phi i64 [ 1, [[ENTRY:%.*]] ], [ [[INDEX_INC:%.*]], [[LOOP_LATCH:%.*]] ] +; GVN-NEXT: [[P1:%.*]] = getelementptr i64, i64* [[P:%.*]], i64 [[INDEX]] +; GVN-NEXT: br i1 [[COND1:%.*]], label [[T:%.*]], label [[F:%.*]] +; GVN: T: +; GVN-NEXT: store i64 [[INDEX]], i64* [[P1]], align 4 +; GVN-NEXT: br label [[LOOP_LATCH]] +; GVN: F: +; GVN-NEXT: br label [[LOOP_LATCH]] +; GVN: Loop.Latch: +; GVN-NEXT: [[PHI:%.*]] = phi i64 [ 100, [[T]] ], [ 50, [[F]] ] +; GVN-NEXT: [[V1:%.*]] = load i64, i64* [[P]], align 4 +; GVN-NEXT: [[V2:%.*]] = add i64 [[V1]], [[PHI]] +; GVN-NEXT: [[INDEX_INC]] = add i64 [[INDEX]], 1 +; GVN-NEXT: [[COND2:%.*]] = icmp ne i64 [[INDEX_INC]], [[TC:%.*]] +; GVN-NEXT: br i1 [[COND2]], label [[LOOP]], label [[EXIT:%.*]] +; GVN: Exit: +; GVN-NEXT: ret i64 [[V2]] +; +Entry: + br label %Loop + +Loop: + %Index = phi i64 [ 1, %Entry ], [ %Index.inc, %Loop.Latch ] + %P1 = getelementptr i64, i64* %P, i64 %Index + br i1 %Cond1, label %T, label %F + +T: + store i64 %Index, i64* %P1 + br label %Loop.Latch + +F: + br label %Loop.Latch + +Loop.Latch: + %phi = phi i64 [ 100, %T ], [ 50, %F ] + %V1 = load i64, i64* %P + %V2 = add i64 %V1, %phi + %Index.inc = add i64 %Index, 1 + %Cond2 = icmp ne i64 %Index.inc, %TC + br i1 %Cond2, label %Loop, label %Exit + +Exit: + ret i64 %V2 +} + +define i64 @test34(i64* %P, i64 %TC, i1 %Cond1) { +; Entry +; | +; Loop<-----+ +; / \ | +; T F | +; \ / | +; Loop.Latch--+ +; | +; v +; Exit +; +; OLDGVN-LABEL: @test34( +; OLDGVN-NEXT: Entry: +; OLDGVN-NEXT: br label [[LOOP:%.*]] +; OLDGVN: Loop: +; OLDGVN-NEXT: [[INDEX:%.*]] = phi i64 [ 1, [[ENTRY:%.*]] ], [ [[INDEX_INC:%.*]], [[LOOP_LATCH:%.*]] ] +; OLDGVN-NEXT: [[P1:%.*]] = getelementptr i64, i64* [[P:%.*]], i64 [[INDEX]] +; OLDGVN-NEXT: br i1 [[COND1:%.*]], label [[T:%.*]], label [[F:%.*]] +; OLDGVN: T: +; OLDGVN-NEXT: store i64 [[INDEX]], i64* [[P1]], align 4 +; OLDGVN-NEXT: br label [[LOOP_LATCH]] +; OLDGVN: F: +; OLDGVN-NEXT: [[V1_PRE:%.*]] = load i64, i64* [[P1]], align 4 +; OLDGVN-NEXT: br label [[LOOP_LATCH]] +; OLDGVN: Loop.Latch: +; OLDGVN-NEXT: [[V1:%.*]] = phi i64 [ [[INDEX]], [[T]] ], [ [[V1_PRE]], [[F]] ] +; OLDGVN-NEXT: [[PHI:%.*]] = phi i64 [ 100, [[T]] ], [ 50, [[F]] ] +; OLDGVN-NEXT: [[V2:%.*]] = add i64 [[V1]], [[PHI]] +; OLDGVN-NEXT: [[INDEX_INC]] = add i64 [[INDEX]], 1 +; OLDGVN-NEXT: [[COND2:%.*]] = icmp ne i64 [[INDEX_INC]], [[TC:%.*]] +; OLDGVN-NEXT: br i1 [[COND2]], label [[LOOP]], label [[EXIT:%.*]] +; OLDGVN: Exit: +; OLDGVN-NEXT: ret i64 [[V2]] +; +; NEWGVN-LABEL: @test34( +; NEWGVN-NEXT: Entry: +; NEWGVN-NEXT: br label [[LOOP:%.*]] +; NEWGVN: Loop: +; NEWGVN-NEXT: [[INDEX:%.*]] = phi i64 [ 1, [[ENTRY:%.*]] ], [ [[INDEX_INC:%.*]], [[LOOP_LATCH:%.*]] ] +; NEWGVN-NEXT: [[P1:%.*]] = getelementptr i64, i64* [[P:%.*]], i64 [[INDEX]] +; NEWGVN-NEXT: br i1 [[COND1:%.*]], label [[T:%.*]], label [[F:%.*]] +; NEWGVN: T: +; NEWGVN-NEXT: store i64 [[INDEX]], i64* [[P1]], align 4 +; NEWGVN-NEXT: br label [[LOOP_LATCH]] +; NEWGVN: F: +; NEWGVN-NEXT: br label [[LOOP_LATCH]] +; NEWGVN: Loop.Latch: +; NEWGVN-NEXT: [[PHI:%.*]] = phi i64 [ 100, [[T]] ], [ 50, [[F]] ] +; NEWGVN-NEXT: [[V1:%.*]] = load i64, i64* [[P1]], align 4 +; NEWGVN-NEXT: [[V2:%.*]] = add i64 [[V1]], [[PHI]] +; NEWGVN-NEXT: [[INDEX_INC]] = add i64 [[INDEX]], 1 +; NEWGVN-NEXT: [[COND2:%.*]] = icmp ne i64 [[INDEX_INC]], [[TC:%.*]] +; NEWGVN-NEXT: br i1 [[COND2]], label [[LOOP]], label [[EXIT:%.*]] +; NEWGVN: Exit: +; NEWGVN-NEXT: ret i64 [[V2]] +; +Entry: + br label %Loop + +Loop: + %Index = phi i64 [ 1, %Entry ], [ %Index.inc, %Loop.Latch ] + %P1 = getelementptr i64, i64* %P, i64 %Index + br i1 %Cond1, label %T, label %F + +T: + store i64 %Index, i64* %P1 + br label %Loop.Latch + +F: + br label %Loop.Latch + +Loop.Latch: + %Phi = phi i64 [ 100, %T ], [ 50, %F ] + %V1 = load i64, i64* %P1 + %V2 = add i64 %V1, %Phi + %Index.inc = add i64 %Index, 1 + %Cond2 = icmp ne i64 %Index.inc, %TC + br i1 %Cond2, label %Loop, label %Exit + +Exit: + ret i64 %V2 +} + +define i64 @test35(i64* %P, i64 %TC) { +; Entry _ +; | / | +; | v | +; Loop | +; | \__| +; | +; v +; Exit +; +; OLDGVN-LABEL: @test35( +; OLDGVN-NEXT: Entry: +; OLDGVN-NEXT: [[V2_PRE:%.*]] = load i64, i64* [[P:%.*]], align 4 +; OLDGVN-NEXT: br label [[LOOP:%.*]] +; OLDGVN: Loop: +; OLDGVN-NEXT: [[INDEX:%.*]] = phi i64 [ 1, [[ENTRY:%.*]] ], [ [[INDEX_INC:%.*]], [[LOOP]] ] +; OLDGVN-NEXT: [[P1:%.*]] = getelementptr i64, i64* [[P]], i64 [[INDEX]] +; OLDGVN-NEXT: [[V1:%.*]] = load i64, i64* [[P1]], align 4 +; OLDGVN-NEXT: [[V3:%.*]] = add i64 [[V1]], [[V2_PRE]] +; OLDGVN-NEXT: [[INDEX_INC]] = add i64 [[INDEX]], 1 +; OLDGVN-NEXT: [[COND:%.*]] = icmp ne i64 [[INDEX_INC]], [[TC:%.*]] +; OLDGVN-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]] +; OLDGVN: Exit: +; OLDGVN-NEXT: ret i64 [[V3]] +; +; NEWGVN-LABEL: @test35( +; NEWGVN-NEXT: Entry: +; NEWGVN-NEXT: br label [[LOOP:%.*]] +; NEWGVN: Loop: +; NEWGVN-NEXT: [[INDEX:%.*]] = phi i64 [ 1, [[ENTRY:%.*]] ], [ [[INDEX_INC:%.*]], [[LOOP]] ] +; NEWGVN-NEXT: [[P1:%.*]] = getelementptr i64, i64* [[P:%.*]], i64 [[INDEX]] +; NEWGVN-NEXT: [[V1:%.*]] = load i64, i64* [[P1]], align 4 +; NEWGVN-NEXT: [[V2:%.*]] = load i64, i64* [[P]], align 4 +; NEWGVN-NEXT: [[V3:%.*]] = add i64 [[V1]], [[V2]] +; NEWGVN-NEXT: [[INDEX_INC]] = add i64 [[INDEX]], 1 +; NEWGVN-NEXT: [[COND:%.*]] = icmp ne i64 [[INDEX_INC]], [[TC:%.*]] +; NEWGVN-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]] +; NEWGVN: Exit: +; NEWGVN-NEXT: ret i64 [[V3]] +; +Entry: + br label %Loop + +Loop: + %Index = phi i64 [ 1, %Entry ], [ %Index.inc, %Loop ] + %P1 = getelementptr i64, i64* %P, i64 %Index + %V1 = load i64, i64* %P1 + %V2 = load i64, i64* %P + %V3 = add i64 %V1, %V2 + %Index.inc = add i64 %Index, 1 + %Cond = icmp ne i64 %Index.inc, %TC + br i1 %Cond, label %Loop, label %Exit + +Exit: + ret i64 %V3 +} + +define i64 @test36(i64* %P, i64 %TC) { +; Entry _ +; | / | +; | v | +; Loop | +; | \__| +; | +; v +; Exit +; +; GVN-LABEL: @test36( +; GVN-NEXT: Entry: +; GVN-NEXT: br label [[LOOP:%.*]] +; GVN: Loop: +; GVN-NEXT: [[INDEX:%.*]] = phi i64 [ 1, [[ENTRY:%.*]] ], [ [[INDEX_INC:%.*]], [[LOOP]] ] +; GVN-NEXT: [[P1:%.*]] = getelementptr i64, i64* [[P:%.*]], i64 [[INDEX]] +; GVN-NEXT: [[V1:%.*]] = load i64, i64* [[P1]], align 4 +; GVN-NEXT: [[V3:%.*]] = add i64 [[V1]], [[V1]] +; GVN-NEXT: [[INDEX_INC]] = add i64 [[INDEX]], 1 +; GVN-NEXT: [[COND:%.*]] = icmp ne i64 [[INDEX_INC]], [[TC:%.*]] +; GVN-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]] +; GVN: Exit: +; GVN-NEXT: ret i64 [[V3]] +; +Entry: + br label %Loop + +Loop: + %Index = phi i64 [ 1, %Entry ], [ %Index.inc, %Loop ] + %P1 = getelementptr i64, i64* %P, i64 %Index + %V1 = load i64, i64* %P1 + %V2 = load i64, i64* %P1 + %V3 = add i64 %V1, %V2 + %Index.inc = add i64 %Index, 1 + %Cond = icmp ne i64 %Index.inc, %TC + br i1 %Cond, label %Loop, label %Exit + +Exit: + ret i64 %V3 +} + +define i64 @test37(i64* %P, i64 %TC, i1 %Cond1) { +; Entry +; | +; Loop<-----+ +; / \ | +; T F | +; \ / | +; Loop.Latch--+ +; | +; v +; Exit +; +; OLDGVN-LABEL: @test37( +; OLDGVN-NEXT: Entry: +; OLDGVN-NEXT: br label [[LOOP:%.*]] +; OLDGVN: Loop: +; OLDGVN-NEXT: [[INDEX:%.*]] = phi i64 [ 1, [[ENTRY:%.*]] ], [ [[INDEX_INC:%.*]], [[LOOP_LATCH:%.*]] ] +; OLDGVN-NEXT: [[P1:%.*]] = getelementptr i64, i64* [[P:%.*]], i64 [[INDEX]] +; OLDGVN-NEXT: br i1 [[COND1:%.*]], label [[T:%.*]], label [[F:%.*]] +; OLDGVN: T: +; OLDGVN-NEXT: [[V1:%.*]] = load i64, i64* [[P1]], align 4 +; OLDGVN-NEXT: br label [[LOOP_LATCH]] +; OLDGVN: F: +; OLDGVN-NEXT: [[V2_PRE:%.*]] = load i64, i64* [[P1]], align 4 +; OLDGVN-NEXT: br label [[LOOP_LATCH]] +; OLDGVN: Loop.Latch: +; OLDGVN-NEXT: [[V2:%.*]] = phi i64 [ [[V1]], [[T]] ], [ [[V2_PRE]], [[F]] ] +; OLDGVN-NEXT: [[PHI:%.*]] = phi i64 [ [[V1]], [[T]] ], [ 100, [[F]] ] +; OLDGVN-NEXT: [[V3:%.*]] = add i64 [[PHI]], [[V2]] +; OLDGVN-NEXT: [[INDEX_INC]] = add i64 [[INDEX]], 1 +; OLDGVN-NEXT: [[COND2:%.*]] = icmp ne i64 [[INDEX_INC]], [[TC:%.*]] +; OLDGVN-NEXT: br i1 [[COND2]], label [[LOOP]], label [[EXIT:%.*]] +; OLDGVN: Exit: +; OLDGVN-NEXT: ret i64 [[V3]] +; +; NEWGVN-LABEL: @test37( +; NEWGVN-NEXT: Entry: +; NEWGVN-NEXT: br label [[LOOP:%.*]] +; NEWGVN: Loop: +; NEWGVN-NEXT: [[INDEX:%.*]] = phi i64 [ 1, [[ENTRY:%.*]] ], [ [[INDEX_INC:%.*]], [[LOOP_LATCH:%.*]] ] +; NEWGVN-NEXT: [[P1:%.*]] = getelementptr i64, i64* [[P:%.*]], i64 [[INDEX]] +; NEWGVN-NEXT: br i1 [[COND1:%.*]], label [[T:%.*]], label [[F:%.*]] +; NEWGVN: T: +; NEWGVN-NEXT: [[V1:%.*]] = load i64, i64* [[P1]], align 4 +; NEWGVN-NEXT: br label [[LOOP_LATCH]] +; NEWGVN: F: +; NEWGVN-NEXT: br label [[LOOP_LATCH]] +; NEWGVN: Loop.Latch: +; NEWGVN-NEXT: [[PHI:%.*]] = phi i64 [ [[V1]], [[T]] ], [ 100, [[F]] ] +; NEWGVN-NEXT: [[V2:%.*]] = load i64, i64* [[P1]], align 4 +; NEWGVN-NEXT: [[V3:%.*]] = add i64 [[PHI]], [[V2]] +; NEWGVN-NEXT: [[INDEX_INC]] = add i64 [[INDEX]], 1 +; NEWGVN-NEXT: [[COND2:%.*]] = icmp ne i64 [[INDEX_INC]], [[TC:%.*]] +; NEWGVN-NEXT: br i1 [[COND2]], label [[LOOP]], label [[EXIT:%.*]] +; NEWGVN: Exit: +; NEWGVN-NEXT: ret i64 [[V3]] +; +Entry: + br label %Loop + +Loop: + %Index = phi i64 [ 1, %Entry ], [ %Index.inc, %Loop.Latch ] + %P1 = getelementptr i64, i64* %P, i64 %Index + br i1 %Cond1, label %T, label %F + +T: + %V1 = load i64, i64* %P1 + br label %Loop.Latch + +F: + br label %Loop.Latch + +Loop.Latch: + %Phi = phi i64 [ %V1, %T ], [ 100, %F ] + %V2 = load i64, i64* %P1 + %V3 = add i64 %Phi, %V2 + %Index.inc = add i64 %Index, 1 + %Cond2 = icmp ne i64 %Index.inc, %TC + br i1 %Cond2, label %Loop, label %Exit + +Exit: + ret i64 %V3 +} + +define i64 @test38(i64* %P, i64 %TC, i1 %Cond1) { +; Entry +; | +; Loop<-----+ +; / \ | +; T F | +; \ / | +; Loop.Latch--+ +; | +; v +; Exit +; +; GVN-LABEL: @test38( +; GVN-NEXT: Entry: +; GVN-NEXT: br label [[LOOP:%.*]] +; GVN: Loop: +; GVN-NEXT: [[INDEX:%.*]] = phi i64 [ 1, [[ENTRY:%.*]] ], [ [[V0:%.*]], [[LOOP_LATCH:%.*]] ] +; GVN-NEXT: [[V0]] = add i64 [[INDEX]], 1 +; GVN-NEXT: [[P1:%.*]] = getelementptr i64, i64* [[P:%.*]], i64 [[V0]] +; GVN-NEXT: [[V1:%.*]] = load i64, i64* [[P1]], align 4 +; GVN-NEXT: br i1 [[COND1:%.*]], label [[T:%.*]], label [[F:%.*]] +; GVN: T: +; GVN-NEXT: br label [[LOOP_LATCH]] +; GVN: F: +; GVN-NEXT: br label [[LOOP_LATCH]] +; GVN: Loop.Latch: +; GVN-NEXT: [[PHI:%.*]] = phi i64 [ 500, [[T]] ], [ 100, [[F]] ] +; GVN-NEXT: [[P2:%.*]] = getelementptr i64, i64* [[P]], i64 [[INDEX]] +; GVN-NEXT: [[V2:%.*]] = load i64, i64* [[P2]], align 4 +; GVN-NEXT: [[V3:%.*]] = add i64 [[PHI]], [[V2]] +; GVN-NEXT: [[V4:%.*]] = add i64 [[V3]], [[V1]] +; GVN-NEXT: [[COND2:%.*]] = icmp ne i64 [[V0]], [[TC:%.*]] +; GVN-NEXT: br i1 [[COND2]], label [[LOOP]], label [[EXIT:%.*]] +; GVN: Exit: +; GVN-NEXT: ret i64 [[V4]] +; +Entry: + br label %Loop + +Loop: + %Index = phi i64 [ 1, %Entry ], [ %Index.inc, %Loop.Latch ] + %V0 = add i64 %Index, 1 + %P1 = getelementptr i64, i64* %P, i64 %V0 + %V1 = load i64, i64* %P1 + br i1 %Cond1, label %T, label %F + +T: + br label %Loop.Latch + +F: + br label %Loop.Latch + +Loop.Latch: + %Phi = phi i64 [ 500, %T ], [ 100, %F ] + %P2 = getelementptr i64, i64* %P, i64 %Index + %V2 = load i64, i64* %P2 + %V3 = add i64 %Phi, %V2 + %V4 = add i64 %V3, %V1 + %Index.inc = add i64 %Index, 1 + %Cond2 = icmp ne i64 %Index.inc, %TC + br i1 %Cond2, label %Loop, label %Exit + +Exit: + ret i64 %V4 +} + +define i64 @test39(i64* %P, i1 %Cond1, i64 %TC) { +; Entry +; | +; Loop<-----+ +; / \ | +; T F | +; \ / | +; Loop.Latch--+ +; | +; v +; Exit +; +; OLDGVN-LABEL: @test39( +; OLDGVN-NEXT: Entry: +; OLDGVN-NEXT: [[V3_PRE:%.*]] = load i64, i64* [[P:%.*]], align 4 +; OLDGVN-NEXT: br label [[LOOP:%.*]] +; OLDGVN: Loop: +; OLDGVN-NEXT: [[V3:%.*]] = phi i64 [ [[V3_PRE]], [[ENTRY:%.*]] ], [ [[TMP1:%.*]], [[LOOP_LATCH:%.*]] ] +; OLDGVN-NEXT: [[INDEX:%.*]] = phi i64 [ 1, [[ENTRY]] ], [ [[INDEX_INC:%.*]], [[LOOP_LATCH]] ] +; OLDGVN-NEXT: [[PHI:%.*]] = phi i64 [ 100, [[ENTRY]] ], [ [[V5:%.*]], [[LOOP_LATCH]] ] +; OLDGVN-NEXT: [[V4:%.*]] = add i64 [[PHI]], [[V3]] +; OLDGVN-NEXT: br i1 [[COND1:%.*]], label [[T:%.*]], label [[F:%.*]] +; OLDGVN: T: +; OLDGVN-NEXT: br label [[LOOP_LATCH]] +; OLDGVN: F: +; OLDGVN-NEXT: br label [[LOOP_LATCH]] +; OLDGVN: Loop.Latch: +; OLDGVN-NEXT: [[PHI2:%.*]] = phi i64 [ 100, [[T]] ], [ 500, [[F]] ] +; OLDGVN-NEXT: [[P1:%.*]] = bitcast i64* [[P]] to <4 x i64>* +; OLDGVN-NEXT: [[V1:%.*]] = load <4 x i64>, <4 x i64>* [[P1]], align 32 +; OLDGVN-NEXT: [[V2:%.*]] = extractelement <4 x i64> [[V1]], i64 2 +; OLDGVN-NEXT: [[V5]] = add i64 [[V2]], [[PHI2]] +; OLDGVN-NEXT: [[INDEX_INC]] = add i64 [[INDEX]], 1 +; OLDGVN-NEXT: [[COND2:%.*]] = icmp ne i64 [[INDEX_INC]], [[TC:%.*]] +; OLDGVN-NEXT: [[TMP0:%.*]] = bitcast <4 x i64> [[V1]] to i256 +; OLDGVN-NEXT: [[TMP1]] = trunc i256 [[TMP0]] to i64 +; OLDGVN-NEXT: br i1 [[COND2]], label [[LOOP]], label [[EXIT:%.*]] +; OLDGVN: Exit: +; OLDGVN-NEXT: ret i64 [[V5]] +; +; NEWGVN-LABEL: @test39( +; NEWGVN-NEXT: Entry: +; NEWGVN-NEXT: br label [[LOOP:%.*]] +; NEWGVN: Loop: +; NEWGVN-NEXT: [[INDEX:%.*]] = phi i64 [ 1, [[ENTRY:%.*]] ], [ [[INDEX_INC:%.*]], [[LOOP_LATCH:%.*]] ] +; NEWGVN-NEXT: [[PHI:%.*]] = phi i64 [ 100, [[ENTRY]] ], [ [[V5:%.*]], [[LOOP_LATCH]] ] +; NEWGVN-NEXT: [[V3:%.*]] = load i64, i64* [[P:%.*]], align 4 +; NEWGVN-NEXT: br i1 [[COND1:%.*]], label [[T:%.*]], label [[F:%.*]] +; NEWGVN: T: +; NEWGVN-NEXT: br label [[LOOP_LATCH]] +; NEWGVN: F: +; NEWGVN-NEXT: br label [[LOOP_LATCH]] +; NEWGVN: Loop.Latch: +; NEWGVN-NEXT: [[PHI2:%.*]] = phi i64 [ 100, [[T]] ], [ 500, [[F]] ] +; NEWGVN-NEXT: [[P1:%.*]] = bitcast i64* [[P]] to <4 x i64>* +; NEWGVN-NEXT: [[V1:%.*]] = load <4 x i64>, <4 x i64>* [[P1]], align 32 +; NEWGVN-NEXT: [[V2:%.*]] = extractelement <4 x i64> [[V1]], i64 2 +; NEWGVN-NEXT: [[V5]] = add i64 [[V2]], [[PHI2]] +; NEWGVN-NEXT: [[INDEX_INC]] = add i64 [[INDEX]], 1 +; NEWGVN-NEXT: [[COND2:%.*]] = icmp ne i64 [[INDEX_INC]], [[TC:%.*]] +; NEWGVN-NEXT: br i1 [[COND2]], label [[LOOP]], label [[EXIT:%.*]] +; NEWGVN: Exit: +; NEWGVN-NEXT: ret i64 [[V5]] +; +Entry: + br label %Loop + +Loop: + %Index = phi i64 [ 1, %Entry ], [ %Index.inc, %Loop.Latch ] + %Phi = phi i64 [ 100, %Entry ], [ %V5, %Loop.Latch ] + %V3 = load i64, i64* %P + %V4 = add i64 %Phi, %V3 + br i1 %Cond1, label %T, label %F + +T: + br label %Loop.Latch + +F: + br label %Loop.Latch + +Loop.Latch: + %Phi2 = phi i64 [ 100, %T ], [ 500, %F ] + %P1 = bitcast i64* %P to <4 x i64>* + %V1 = load <4 x i64>, <4 x i64>* %P1 + %V2 = extractelement <4 x i64> %V1, i64 2 + %V5 = add i64 %V2, %Phi2 + %Index.inc = add i64 %Index, 1 + %Cond2 = icmp ne i64 %Index.inc, %TC + br i1 %Cond2, label %Loop, label %Exit + +Exit: + ret i64 %V5 +} + +define i64 @test40(i64* %P, i64 %TC) { +; Entry _ +; | / | +; | v | +; Loop | +; | \__| +; | +; BB +; | +; v +; Exit +; +; OLDGVN-LABEL: @test40( +; OLDGVN-NEXT: Entry: +; OLDGVN-NEXT: [[P1_PHI_TRANS_INSERT:%.*]] = bitcast i64* [[P:%.*]] to <4 x i64>* +; OLDGVN-NEXT: [[V1_PRE:%.*]] = load <4 x i64>, <4 x i64>* [[P1_PHI_TRANS_INSERT]], align 32 +; OLDGVN-NEXT: [[TMP0:%.*]] = bitcast <4 x i64> [[V1_PRE]] to i256 +; OLDGVN-NEXT: [[TMP1:%.*]] = trunc i256 [[TMP0]] to i64 +; OLDGVN-NEXT: br label [[LOOP:%.*]] +; OLDGVN: Loop: +; OLDGVN-NEXT: [[INDEX:%.*]] = phi i64 [ 1, [[ENTRY:%.*]] ], [ [[INDEX_INC:%.*]], [[LOOP]] ] +; OLDGVN-NEXT: [[V2:%.*]] = extractelement <4 x i64> [[V1_PRE]], i64 2 +; OLDGVN-NEXT: [[V3:%.*]] = add i64 [[V2]], [[INDEX]] +; OLDGVN-NEXT: [[INDEX_INC]] = add i64 [[INDEX]], 1 +; OLDGVN-NEXT: [[COND1:%.*]] = icmp ne i64 [[INDEX_INC]], [[TC:%.*]] +; OLDGVN-NEXT: br i1 [[COND1]], label [[LOOP]], label [[BB:%.*]] +; OLDGVN: BB: +; OLDGVN-NEXT: [[V5:%.*]] = add i64 [[TMP1]], [[V3]] +; OLDGVN-NEXT: ret i64 [[V5]] +; +; NEWGVN-LABEL: @test40( +; NEWGVN-NEXT: Entry: +; NEWGVN-NEXT: br label [[LOOP:%.*]] +; NEWGVN: Loop: +; NEWGVN-NEXT: [[INDEX:%.*]] = phi i64 [ 1, [[ENTRY:%.*]] ], [ [[INDEX_INC:%.*]], [[LOOP]] ] +; NEWGVN-NEXT: [[P1:%.*]] = bitcast i64* [[P:%.*]] to <4 x i64>* +; NEWGVN-NEXT: [[V1:%.*]] = load <4 x i64>, <4 x i64>* [[P1]], align 32 +; NEWGVN-NEXT: [[V2:%.*]] = extractelement <4 x i64> [[V1]], i64 2 +; NEWGVN-NEXT: [[V3:%.*]] = add i64 [[V2]], [[INDEX]] +; NEWGVN-NEXT: [[INDEX_INC]] = add i64 [[INDEX]], 1 +; NEWGVN-NEXT: [[COND1:%.*]] = icmp ne i64 [[INDEX_INC]], [[TC:%.*]] +; NEWGVN-NEXT: br i1 [[COND1]], label [[LOOP]], label [[BB:%.*]] +; NEWGVN: BB: +; NEWGVN-NEXT: [[V4:%.*]] = load i64, i64* [[P]], align 4 +; NEWGVN-NEXT: br label [[EXIT:%.*]] +; NEWGVN: Exit: +; NEWGVN-NEXT: [[V5:%.*]] = add i64 [[V4]], [[V3]] +; NEWGVN-NEXT: ret i64 [[V5]] +; +Entry: + br label %Loop + +Loop: + %Index = phi i64 [ 1, %Entry ], [ %Index.inc, %Loop ] + %P1 = bitcast i64* %P to <4 x i64>* + %V1 = load <4 x i64>, <4 x i64>* %P1 + %V2 = extractelement <4 x i64> %V1, i64 2 + %V3 = add i64 %V2, %Index + %Index.inc = add i64 %Index, 1 + %Cond1 = icmp ne i64 %Index.inc, %TC + br i1 %Cond1, label %Loop, label %BB + +BB: + %V4 = load i64, i64* %P + br label %Exit + +Exit: + %V5 = add i64 %V4, %V3 + ret i64 %V5 +} + +define i64 @test41(i64* %P, i64 %TC) { +; Entry _ +; | / | +; | v | +; Loop | +; | \__| +; | +; BB +; | +; v +; Exit +; +; OLDGVN-LABEL: @test41( +; OLDGVN-NEXT: Entry: +; OLDGVN-NEXT: br label [[LOOP:%.*]] +; OLDGVN: Loop: +; OLDGVN-NEXT: [[INDEX:%.*]] = phi i64 [ 1, [[ENTRY:%.*]] ], [ [[INDEX_INC:%.*]], [[LOOP]] ] +; OLDGVN-NEXT: [[P1:%.*]] = bitcast i64* [[P:%.*]] to <4 x i64>* +; OLDGVN-NEXT: [[I1:%.*]] = insertelement <4 x i64> poison, i64 [[INDEX]], i32 0 +; OLDGVN-NEXT: [[I2:%.*]] = insertelement <4 x i64> [[I1]], i64 [[INDEX]], i32 1 +; OLDGVN-NEXT: [[I3:%.*]] = insertelement <4 x i64> [[I2]], i64 100, i32 2 +; OLDGVN-NEXT: [[I4:%.*]] = insertelement <4 x i64> [[I3]], i64 1000, i32 3 +; OLDGVN-NEXT: store <4 x i64> [[I4]], <4 x i64>* [[P1]], align 32 +; OLDGVN-NEXT: [[INDEX_INC]] = add i64 [[INDEX]], 1 +; OLDGVN-NEXT: [[COND:%.*]] = icmp ne i64 [[INDEX_INC]], [[TC:%.*]] +; OLDGVN-NEXT: [[TMP0:%.*]] = bitcast <4 x i64> [[I4]] to i256 +; OLDGVN-NEXT: [[TMP1:%.*]] = trunc i256 [[TMP0]] to i64 +; OLDGVN-NEXT: br i1 [[COND]], label [[LOOP]], label [[BB:%.*]] +; OLDGVN: BB: +; OLDGVN-NEXT: [[V5:%.*]] = add i64 [[TMP1]], [[TC]] +; OLDGVN-NEXT: ret i64 [[V5]] +; +; NEWGVN-LABEL: @test41( +; NEWGVN-NEXT: Entry: +; NEWGVN-NEXT: br label [[LOOP:%.*]] +; NEWGVN: Loop: +; NEWGVN-NEXT: [[INDEX:%.*]] = phi i64 [ 1, [[ENTRY:%.*]] ], [ [[INDEX_INC:%.*]], [[LOOP]] ] +; NEWGVN-NEXT: [[P1:%.*]] = bitcast i64* [[P:%.*]] to <4 x i64>* +; NEWGVN-NEXT: [[I1:%.*]] = insertelement <4 x i64> poison, i64 [[INDEX]], i32 0 +; NEWGVN-NEXT: [[I2:%.*]] = insertelement <4 x i64> [[I1]], i64 [[INDEX]], i32 1 +; NEWGVN-NEXT: [[I3:%.*]] = insertelement <4 x i64> [[I2]], i64 100, i32 2 +; NEWGVN-NEXT: [[I4:%.*]] = insertelement <4 x i64> [[I3]], i64 1000, i32 3 +; NEWGVN-NEXT: store <4 x i64> [[I4]], <4 x i64>* [[P1]], align 32 +; NEWGVN-NEXT: [[INDEX_INC]] = add i64 [[INDEX]], 1 +; NEWGVN-NEXT: [[COND:%.*]] = icmp ne i64 [[INDEX_INC]], [[TC:%.*]] +; NEWGVN-NEXT: br i1 [[COND]], label [[LOOP]], label [[BB:%.*]] +; NEWGVN: BB: +; NEWGVN-NEXT: [[V4:%.*]] = load i64, i64* [[P]], align 4 +; NEWGVN-NEXT: br label [[EXIT:%.*]] +; NEWGVN: Exit: +; NEWGVN-NEXT: [[V5:%.*]] = add i64 [[V4]], [[TC]] +; NEWGVN-NEXT: ret i64 [[V5]] +; +Entry: + br label %Loop + +Loop: + %Index = phi i64 [ 1, %Entry ], [ %Index.inc, %Loop ] + %P1 = bitcast i64* %P to <4 x i64>* + %I1 = insertelement <4 x i64> poison, i64 %Index, i32 0 + %I2 = insertelement <4 x i64> %I1, i64 %Index, i32 1 + %I3 = insertelement <4 x i64> %I2, i64 100, i32 2 + %I4 = insertelement <4 x i64> %I3, i64 1000, i32 3 + store <4 x i64> %I4, <4 x i64>* %P1 + %Index.inc = add i64 %Index, 1 + %Cond = icmp ne i64 %Index.inc, %TC + br i1 %Cond, label %Loop, label %BB + +BB: + %V4 = load i64, i64* %P + br label %Exit + +Exit: + %V5 = add i64 %V4, %Index.inc + ret i64 %V5 +} + +define i64 @test42(i64* %P, i64 %TC, i1 %Cond1) { +; Entry _ +; | / | +; | v | +; Loop | +; | \__| +; | +; BB1 +; / \ +; BB2 BB3 +; \ / +; vv +; Exit +; +; OLDGVN-LABEL: @test42( +; OLDGVN-NEXT: Entry: +; OLDGVN-NEXT: br label [[LOOP:%.*]] +; OLDGVN: Loop: +; OLDGVN-NEXT: [[INDEX:%.*]] = phi i64 [ 1, [[ENTRY:%.*]] ], [ [[INDEX_INC:%.*]], [[LOOP]] ] +; OLDGVN-NEXT: [[P1:%.*]] = bitcast i64* [[P:%.*]] to <4 x i64>* +; OLDGVN-NEXT: [[I1:%.*]] = insertelement <4 x i64> poison, i64 [[INDEX]], i32 0 +; OLDGVN-NEXT: [[I2:%.*]] = insertelement <4 x i64> [[I1]], i64 [[INDEX]], i32 1 +; OLDGVN-NEXT: [[I3:%.*]] = insertelement <4 x i64> [[I2]], i64 100, i32 2 +; OLDGVN-NEXT: [[I4:%.*]] = insertelement <4 x i64> [[I3]], i64 1000, i32 3 +; OLDGVN-NEXT: store <4 x i64> [[I4]], <4 x i64>* [[P1]], align 32 +; OLDGVN-NEXT: [[INDEX_INC]] = add i64 [[INDEX]], 1 +; OLDGVN-NEXT: [[COND:%.*]] = icmp ne i64 [[INDEX_INC]], [[TC:%.*]] +; OLDGVN-NEXT: [[TMP0:%.*]] = bitcast <4 x i64> [[I4]] to i256 +; OLDGVN-NEXT: [[TMP1:%.*]] = trunc i256 [[TMP0]] to i64 +; OLDGVN-NEXT: [[TMP2:%.*]] = trunc i256 [[TMP0]] to i128 +; OLDGVN-NEXT: [[TMP3:%.*]] = bitcast i128 [[TMP2]] to <2 x i64> +; OLDGVN-NEXT: br i1 [[COND]], label [[LOOP]], label [[BB1:%.*]] +; OLDGVN: BB1: +; OLDGVN-NEXT: br i1 [[COND1:%.*]], label [[BB2:%.*]], label [[BB3:%.*]] +; OLDGVN: BB2: +; OLDGVN-NEXT: br label [[EXIT:%.*]] +; OLDGVN: BB3: +; OLDGVN-NEXT: br label [[EXIT]] +; OLDGVN: Exit: +; OLDGVN-NEXT: [[PHI:%.*]] = phi i64 [ [[TMP1]], [[BB2]] ], [ 100, [[BB3]] ] +; OLDGVN-NEXT: [[P2:%.*]] = bitcast i64* [[P]] to <2 x i64>* +; OLDGVN-NEXT: [[V6:%.*]] = extractelement <2 x i64> [[TMP3]], i64 1 +; OLDGVN-NEXT: [[V7:%.*]] = add i64 [[PHI]], [[V6]] +; OLDGVN-NEXT: ret i64 [[V7]] +; +; NEWGVN-LABEL: @test42( +; NEWGVN-NEXT: Entry: +; NEWGVN-NEXT: br label [[LOOP:%.*]] +; NEWGVN: Loop: +; NEWGVN-NEXT: [[INDEX:%.*]] = phi i64 [ 1, [[ENTRY:%.*]] ], [ [[INDEX_INC:%.*]], [[LOOP]] ] +; NEWGVN-NEXT: [[P1:%.*]] = bitcast i64* [[P:%.*]] to <4 x i64>* +; NEWGVN-NEXT: [[I1:%.*]] = insertelement <4 x i64> poison, i64 [[INDEX]], i32 0 +; NEWGVN-NEXT: [[I2:%.*]] = insertelement <4 x i64> [[I1]], i64 [[INDEX]], i32 1 +; NEWGVN-NEXT: [[I3:%.*]] = insertelement <4 x i64> [[I2]], i64 100, i32 2 +; NEWGVN-NEXT: [[I4:%.*]] = insertelement <4 x i64> [[I3]], i64 1000, i32 3 +; NEWGVN-NEXT: store <4 x i64> [[I4]], <4 x i64>* [[P1]], align 32 +; NEWGVN-NEXT: [[INDEX_INC]] = add i64 [[INDEX]], 1 +; NEWGVN-NEXT: [[COND:%.*]] = icmp ne i64 [[INDEX_INC]], [[TC:%.*]] +; NEWGVN-NEXT: br i1 [[COND]], label [[LOOP]], label [[BB1:%.*]] +; NEWGVN: BB1: +; NEWGVN-NEXT: br i1 [[COND1:%.*]], label [[BB2:%.*]], label [[BB3:%.*]] +; NEWGVN: BB2: +; NEWGVN-NEXT: [[V4:%.*]] = load i64, i64* [[P]], align 4 +; NEWGVN-NEXT: br label [[EXIT:%.*]] +; NEWGVN: BB3: +; NEWGVN-NEXT: br label [[EXIT]] +; NEWGVN: Exit: +; NEWGVN-NEXT: [[PHI:%.*]] = phi i64 [ [[V4]], [[BB2]] ], [ 100, [[BB3]] ] +; NEWGVN-NEXT: [[P2:%.*]] = bitcast i64* [[P]] to <2 x i64>* +; NEWGVN-NEXT: [[V5:%.*]] = load <2 x i64>, <2 x i64>* [[P2]], align 16 +; NEWGVN-NEXT: [[V6:%.*]] = extractelement <2 x i64> [[V5]], i64 1 +; NEWGVN-NEXT: [[V7:%.*]] = add i64 [[PHI]], [[V6]] +; NEWGVN-NEXT: ret i64 [[V7]] +; +Entry: + br label %Loop + +Loop: + %Index = phi i64 [ 1, %Entry ], [ %Index.inc, %Loop ] + %P1 = bitcast i64* %P to <4 x i64>* + %I1 = insertelement <4 x i64> poison, i64 %Index, i32 0 + %I2 = insertelement <4 x i64> %I1, i64 %Index, i32 1 + %I3 = insertelement <4 x i64> %I2, i64 100, i32 2 + %I4 = insertelement <4 x i64> %I3, i64 1000, i32 3 + store <4 x i64> %I4, <4 x i64>* %P1 + %Index.inc = add i64 %Index, 1 + %Cond = icmp ne i64 %Index.inc, %TC + br i1 %Cond, label %Loop, label %BB1 + +BB1: + br i1 %Cond1, label %BB2, label %BB3 + +BB2: + %V4 = load i64, i64* %P + br label %Exit + +BB3: + br label %Exit + +Exit: + %Phi = phi i64 [ %V4, %BB2 ], [ 100, %BB3 ] + %P2 = bitcast i64* %P to <2 x i64>* + %V5 = load <2 x i64>, <2 x i64>* %P2 + %V6 = extractelement <2 x i64> %V5, i64 1 + %V7 = add i64 %Phi, %V6 + ret i64 %V7 +} + + +define i64 @test43(i64* %P, i64 %TC1, i1 %Cond, i64 %TC2) { +; Entry _ +; | / | +; | v | +; Loop1 | +; | \__| +; | +; BB1 +; / \ +; BB2 BB3 +; \ / _ +; | / | +; | v | +; Loop2 | +; | \__| +; | +; v +; Exit +; +; OLDGVN-LABEL: @test43( +; OLDGVN-NEXT: Entry: +; OLDGVN-NEXT: br label [[LOOP1:%.*]] +; OLDGVN: Loop1: +; OLDGVN-NEXT: [[INDEX1:%.*]] = phi i64 [ 1, [[ENTRY:%.*]] ], [ [[INDEX1_INC:%.*]], [[LOOP1]] ] +; OLDGVN-NEXT: [[P1:%.*]] = bitcast i64* [[P:%.*]] to <4 x i64>* +; OLDGVN-NEXT: [[I1:%.*]] = insertelement <4 x i64> poison, i64 [[INDEX1]], i32 0 +; OLDGVN-NEXT: [[I2:%.*]] = insertelement <4 x i64> [[I1]], i64 [[INDEX1]], i32 1 +; OLDGVN-NEXT: [[I3:%.*]] = insertelement <4 x i64> [[I2]], i64 100, i32 2 +; OLDGVN-NEXT: [[I4:%.*]] = insertelement <4 x i64> [[I3]], i64 1000, i32 3 +; OLDGVN-NEXT: store <4 x i64> [[I4]], <4 x i64>* [[P1]], align 32 +; OLDGVN-NEXT: [[INDEX1_INC]] = add i64 [[INDEX1]], 1 +; OLDGVN-NEXT: [[COND1:%.*]] = icmp ne i64 [[INDEX1_INC]], [[TC1:%.*]] +; OLDGVN-NEXT: [[TMP0:%.*]] = bitcast <4 x i64> [[I4]] to i256 +; OLDGVN-NEXT: [[TMP1:%.*]] = trunc i256 [[TMP0]] to i64 +; OLDGVN-NEXT: [[TMP2:%.*]] = trunc i256 [[TMP0]] to i128 +; OLDGVN-NEXT: [[TMP3:%.*]] = bitcast i128 [[TMP2]] to <2 x i64> +; OLDGVN-NEXT: br i1 [[COND1]], label [[LOOP1]], label [[BB1:%.*]] +; OLDGVN: BB1: +; OLDGVN-NEXT: br i1 [[COND:%.*]], label [[BB2:%.*]], label [[BB3:%.*]] +; OLDGVN: BB2: +; OLDGVN-NEXT: br label [[LOOP2:%.*]] +; OLDGVN: BB3: +; OLDGVN-NEXT: br label [[LOOP2]] +; OLDGVN: Loop2: +; OLDGVN-NEXT: [[INDEX2:%.*]] = phi i64 [ [[TMP1]], [[BB2]] ], [ 1, [[BB3]] ], [ [[INDEX2_INC:%.*]], [[LOOP2]] ] +; OLDGVN-NEXT: [[P2:%.*]] = bitcast i64* [[P]] to <2 x i64>* +; OLDGVN-NEXT: [[V6:%.*]] = extractelement <2 x i64> [[TMP3]], i64 1 +; OLDGVN-NEXT: [[V7:%.*]] = add i64 [[V6]], [[INDEX2]] +; OLDGVN-NEXT: [[INDEX2_INC]] = add i64 [[INDEX2]], 1 +; OLDGVN-NEXT: [[COND2:%.*]] = icmp ne i64 [[INDEX2_INC]], [[TC2:%.*]] +; OLDGVN-NEXT: br i1 [[COND2]], label [[LOOP2]], label [[EXIT:%.*]] +; OLDGVN: Exit: +; OLDGVN-NEXT: ret i64 [[V7]] +; +; NEWGVN-LABEL: @test43( +; NEWGVN-NEXT: Entry: +; NEWGVN-NEXT: br label [[LOOP1:%.*]] +; NEWGVN: Loop1: +; NEWGVN-NEXT: [[INDEX1:%.*]] = phi i64 [ 1, [[ENTRY:%.*]] ], [ [[INDEX1_INC:%.*]], [[LOOP1]] ] +; NEWGVN-NEXT: [[P1:%.*]] = bitcast i64* [[P:%.*]] to <4 x i64>* +; NEWGVN-NEXT: [[I1:%.*]] = insertelement <4 x i64> poison, i64 [[INDEX1]], i32 0 +; NEWGVN-NEXT: [[I2:%.*]] = insertelement <4 x i64> [[I1]], i64 [[INDEX1]], i32 1 +; NEWGVN-NEXT: [[I3:%.*]] = insertelement <4 x i64> [[I2]], i64 100, i32 2 +; NEWGVN-NEXT: [[I4:%.*]] = insertelement <4 x i64> [[I3]], i64 1000, i32 3 +; NEWGVN-NEXT: store <4 x i64> [[I4]], <4 x i64>* [[P1]], align 32 +; NEWGVN-NEXT: [[INDEX1_INC]] = add i64 [[INDEX1]], 1 +; NEWGVN-NEXT: [[COND1:%.*]] = icmp ne i64 [[INDEX1_INC]], [[TC1:%.*]] +; NEWGVN-NEXT: br i1 [[COND1]], label [[LOOP1]], label [[BB1:%.*]] +; NEWGVN: BB1: +; NEWGVN-NEXT: br i1 [[COND:%.*]], label [[BB2:%.*]], label [[BB3:%.*]] +; NEWGVN: BB2: +; NEWGVN-NEXT: [[V4:%.*]] = load i64, i64* [[P]], align 4 +; NEWGVN-NEXT: br label [[LOOP2:%.*]] +; NEWGVN: BB3: +; NEWGVN-NEXT: br label [[LOOP2]] +; NEWGVN: Loop2: +; NEWGVN-NEXT: [[INDEX2:%.*]] = phi i64 [ [[V4]], [[BB2]] ], [ 1, [[BB3]] ], [ [[INDEX2_INC:%.*]], [[LOOP2]] ] +; NEWGVN-NEXT: [[P2:%.*]] = bitcast i64* [[P]] to <2 x i64>* +; NEWGVN-NEXT: [[V5:%.*]] = load <2 x i64>, <2 x i64>* [[P2]], align 16 +; NEWGVN-NEXT: [[V6:%.*]] = extractelement <2 x i64> [[V5]], i64 1 +; NEWGVN-NEXT: [[V7:%.*]] = add i64 [[V6]], [[INDEX2]] +; NEWGVN-NEXT: [[INDEX2_INC]] = add i64 [[INDEX2]], 1 +; NEWGVN-NEXT: [[COND2:%.*]] = icmp ne i64 [[INDEX2_INC]], [[TC2:%.*]] +; NEWGVN-NEXT: br i1 [[COND2]], label [[LOOP2]], label [[EXIT:%.*]] +; NEWGVN: Exit: +; NEWGVN-NEXT: ret i64 [[V7]] +; +Entry: + br label %Loop1 + +Loop1: + %Index1 = phi i64 [ 1, %Entry ], [ %Index1.inc, %Loop1 ] + %P1 = bitcast i64* %P to <4 x i64>* + %I1 = insertelement <4 x i64> poison, i64 %Index1, i32 0 + %I2 = insertelement <4 x i64> %I1, i64 %Index1, i32 1 + %I3 = insertelement <4 x i64> %I2, i64 100, i32 2 + %I4 = insertelement <4 x i64> %I3, i64 1000, i32 3 + store <4 x i64> %I4, <4 x i64>* %P1 + %Index1.inc = add i64 %Index1, 1 + %Cond1 = icmp ne i64 %Index1.inc, %TC1 + br i1 %Cond1, label %Loop1, label %BB1 + +BB1: + br i1 %Cond, label %BB2, label %BB3 + +BB2: + %V4 = load i64, i64* %P + br label %Loop2 + +BB3: + br label %Loop2 + +Loop2: + %Index2 = phi i64 [ %V4, %BB2 ], [ 1, %BB3 ], [ %Index2.inc, %Loop2 ] + %P2 = bitcast i64* %P to <2 x i64>* + %V5 = load <2 x i64>, <2 x i64>* %P2 + %V6 = extractelement <2 x i64> %V5, i64 1 + %V7 = add i64 %V6, %Index2 + %Index2.inc = add i64 %Index2, 1 + %Cond2 = icmp ne i64 %Index2.inc, %TC2 + br i1 %Cond2, label %Loop2, label %Exit + +Exit: + ret i64 %V7 +} + + +define i64 @test44(i64* %P, i64 %TC1, i1 %Cond1, i64 %TC2) { +; Entry _ +; | / | +; | v | +; Loop1 | +; | \__| +; | +; BB1 +; / \ +; BB2 BB3 +; \ / _ +; | / | +; | v | +; Loop2 | +; | \__| +; | +; v +; Exit +; +; OLDGVN-LABEL: @test44( +; OLDGVN-NEXT: Entry: +; OLDGVN-NEXT: br label [[LOOP1:%.*]] +; OLDGVN: Loop1: +; OLDGVN-NEXT: [[INDEX1:%.*]] = phi i64 [ 1, [[ENTRY:%.*]] ], [ [[INDEX1_INC:%.*]], [[LOOP1]] ] +; OLDGVN-NEXT: [[P1:%.*]] = bitcast i64* [[P:%.*]] to <4 x i64>* +; OLDGVN-NEXT: [[I1:%.*]] = insertelement <4 x i64> poison, i64 [[INDEX1]], i32 0 +; OLDGVN-NEXT: [[I2:%.*]] = insertelement <4 x i64> [[I1]], i64 [[INDEX1]], i32 1 +; OLDGVN-NEXT: [[I3:%.*]] = insertelement <4 x i64> [[I2]], i64 100, i32 2 +; OLDGVN-NEXT: [[I4:%.*]] = insertelement <4 x i64> [[I3]], i64 1000, i32 3 +; OLDGVN-NEXT: store <4 x i64> [[I4]], <4 x i64>* [[P1]], align 32 +; OLDGVN-NEXT: [[INDEX1_INC]] = add i64 [[INDEX1]], 1 +; OLDGVN-NEXT: [[COND2:%.*]] = icmp ne i64 [[INDEX1_INC]], [[TC1:%.*]] +; OLDGVN-NEXT: [[TMP0:%.*]] = bitcast <4 x i64> [[I4]] to i256 +; OLDGVN-NEXT: [[TMP1:%.*]] = trunc i256 [[TMP0]] to i64 +; OLDGVN-NEXT: [[TMP2:%.*]] = trunc i256 [[TMP0]] to i128 +; OLDGVN-NEXT: [[TMP3:%.*]] = bitcast i128 [[TMP2]] to <2 x i64> +; OLDGVN-NEXT: br i1 [[COND2]], label [[LOOP1]], label [[BB1:%.*]] +; OLDGVN: BB1: +; OLDGVN-NEXT: br i1 [[COND1:%.*]], label [[BB2:%.*]], label [[BB3:%.*]] +; OLDGVN: BB2: +; OLDGVN-NEXT: br label [[LOOP2:%.*]] +; OLDGVN: BB3: +; OLDGVN-NEXT: br label [[LOOP2]] +; OLDGVN: Loop2: +; OLDGVN-NEXT: [[INDEX2:%.*]] = phi i64 [ [[TMP1]], [[BB2]] ], [ 1, [[BB3]] ], [ [[INDEX2_INC:%.*]], [[LOOP2]] ] +; OLDGVN-NEXT: [[P2:%.*]] = bitcast i64* [[P]] to <2 x i64>* +; OLDGVN-NEXT: [[V6:%.*]] = extractelement <2 x i64> [[TMP3]], i64 1 +; OLDGVN-NEXT: [[TMP4:%.*]] = trunc i128 [[TMP2]] to i64 +; OLDGVN-NEXT: [[V8:%.*]] = add i64 [[V6]], [[INDEX2]] +; OLDGVN-NEXT: [[V9:%.*]] = add i64 [[V8]], [[TMP4]] +; OLDGVN-NEXT: [[INDEX2_INC]] = add i64 [[INDEX2]], 1 +; OLDGVN-NEXT: [[COND3:%.*]] = icmp ne i64 [[INDEX2_INC]], [[TC2:%.*]] +; OLDGVN-NEXT: br i1 [[COND3]], label [[LOOP2]], label [[EXIT:%.*]] +; OLDGVN: Exit: +; OLDGVN-NEXT: ret i64 [[V9]] +; +; NEWGVN-LABEL: @test44( +; NEWGVN-NEXT: Entry: +; NEWGVN-NEXT: br label [[LOOP1:%.*]] +; NEWGVN: Loop1: +; NEWGVN-NEXT: [[INDEX1:%.*]] = phi i64 [ 1, [[ENTRY:%.*]] ], [ [[INDEX1_INC:%.*]], [[LOOP1]] ] +; NEWGVN-NEXT: [[P1:%.*]] = bitcast i64* [[P:%.*]] to <4 x i64>* +; NEWGVN-NEXT: [[I1:%.*]] = insertelement <4 x i64> poison, i64 [[INDEX1]], i32 0 +; NEWGVN-NEXT: [[I2:%.*]] = insertelement <4 x i64> [[I1]], i64 [[INDEX1]], i32 1 +; NEWGVN-NEXT: [[I3:%.*]] = insertelement <4 x i64> [[I2]], i64 100, i32 2 +; NEWGVN-NEXT: [[I4:%.*]] = insertelement <4 x i64> [[I3]], i64 1000, i32 3 +; NEWGVN-NEXT: store <4 x i64> [[I4]], <4 x i64>* [[P1]], align 32 +; NEWGVN-NEXT: [[INDEX1_INC]] = add i64 [[INDEX1]], 1 +; NEWGVN-NEXT: [[COND2:%.*]] = icmp ne i64 [[INDEX1_INC]], [[TC1:%.*]] +; NEWGVN-NEXT: br i1 [[COND2]], label [[LOOP1]], label [[BB1:%.*]] +; NEWGVN: BB1: +; NEWGVN-NEXT: br i1 [[COND1:%.*]], label [[BB2:%.*]], label [[BB3:%.*]] +; NEWGVN: BB2: +; NEWGVN-NEXT: [[V4:%.*]] = load i64, i64* [[P]], align 4 +; NEWGVN-NEXT: br label [[LOOP2:%.*]] +; NEWGVN: BB3: +; NEWGVN-NEXT: br label [[LOOP2]] +; NEWGVN: Loop2: +; NEWGVN-NEXT: [[INDEX2:%.*]] = phi i64 [ [[V4]], [[BB2]] ], [ 1, [[BB3]] ], [ [[INDEX2_INC:%.*]], [[LOOP2]] ] +; NEWGVN-NEXT: [[P2:%.*]] = bitcast i64* [[P]] to <2 x i64>* +; NEWGVN-NEXT: [[V5:%.*]] = load <2 x i64>, <2 x i64>* [[P2]], align 16 +; NEWGVN-NEXT: [[V6:%.*]] = extractelement <2 x i64> [[V5]], i64 1 +; NEWGVN-NEXT: [[V7:%.*]] = load i64, i64* [[P]], align 4 +; NEWGVN-NEXT: [[V8:%.*]] = add i64 [[V6]], [[INDEX2]] +; NEWGVN-NEXT: [[V9:%.*]] = add i64 [[V8]], [[V7]] +; NEWGVN-NEXT: [[INDEX2_INC]] = add i64 [[INDEX2]], 1 +; NEWGVN-NEXT: [[COND3:%.*]] = icmp ne i64 [[INDEX2_INC]], [[TC2:%.*]] +; NEWGVN-NEXT: br i1 [[COND3]], label [[LOOP2]], label [[EXIT:%.*]] +; NEWGVN: Exit: +; NEWGVN-NEXT: ret i64 [[V9]] +; +Entry: + br label %Loop1 + +Loop1: + %Index1 = phi i64 [ 1, %Entry ], [ %Index1.inc, %Loop1 ] + %P1 = bitcast i64* %P to <4 x i64>* + %I1 = insertelement <4 x i64> poison, i64 %Index1, i32 0 + %I2 = insertelement <4 x i64> %I1, i64 %Index1, i32 1 + %I3 = insertelement <4 x i64> %I2, i64 100, i32 2 + %I4 = insertelement <4 x i64> %I3, i64 1000, i32 3 + store <4 x i64> %I4, <4 x i64>* %P1 + %Index1.inc = add i64 %Index1, 1 + %Cond2 = icmp ne i64 %Index1.inc, %TC1 + br i1 %Cond2, label %Loop1, label %BB1 + +BB1: + br i1 %Cond1, label %BB2, label %BB3 + +BB2: + %V4 = load i64, i64* %P + br label %Loop2 + +BB3: + br label %Loop2 + +Loop2: + %Index2 = phi i64 [ %V4, %BB2 ], [ 1, %BB3 ], [ %Index2.inc, %Loop2 ] + %P2 = bitcast i64* %P to <2 x i64>* + %V5 = load <2 x i64>, <2 x i64>* %P2 + %V6 = extractelement <2 x i64> %V5, i64 1 + %V7 = load i64, i64* %P + %V8 = add i64 %V6, %Index2 + %V9 = add i64 %V8, %V7 + %Index2.inc = add i64 %Index2, 1 + %Cond3 = icmp ne i64 %Index2.inc, %TC2 + br i1 %Cond3, label %Loop2, label %Exit + +Exit: + ret i64 %V9 +} + +define i64 @test45(i64* %P, i64 %TC1, i1 %Cond1, i64 %TC2) { +; Entry _ +; | / | +; | v | +; Loop1 | +; | \__| +; | +; BB1 +; / \ +; BB2 BB3 +; \ / _ +; | / | +; | v | +; Loop2 | +; | \__| +; | +; v +; Exit +; +; OLDGVN-LABEL: @test45( +; OLDGVN-NEXT: Entry: +; OLDGVN-NEXT: [[P1_PHI_TRANS_INSERT:%.*]] = bitcast i64* [[P:%.*]] to <4 x i64>* +; OLDGVN-NEXT: [[V1_PRE:%.*]] = load <4 x i64>, <4 x i64>* [[P1_PHI_TRANS_INSERT]], align 32 +; OLDGVN-NEXT: [[TMP0:%.*]] = bitcast <4 x i64> [[V1_PRE]] to i256 +; OLDGVN-NEXT: [[TMP1:%.*]] = trunc i256 [[TMP0]] to i64 +; OLDGVN-NEXT: [[TMP2:%.*]] = trunc i256 [[TMP0]] to i128 +; OLDGVN-NEXT: [[TMP3:%.*]] = bitcast i128 [[TMP2]] to <2 x i64> +; OLDGVN-NEXT: br label [[LOOP1:%.*]] +; OLDGVN: Loop1: +; OLDGVN-NEXT: [[INDEX1:%.*]] = phi i64 [ 1, [[ENTRY:%.*]] ], [ [[INDEX1_INC:%.*]], [[LOOP1]] ] +; OLDGVN-NEXT: [[V2:%.*]] = extractelement <4 x i64> [[V1_PRE]], i64 2 +; OLDGVN-NEXT: [[INDEX1_INC]] = add i64 [[INDEX1]], 1 +; OLDGVN-NEXT: [[COND2:%.*]] = icmp ne i64 [[INDEX1_INC]], [[TC1:%.*]] +; OLDGVN-NEXT: br i1 [[COND2]], label [[LOOP1]], label [[BB1:%.*]] +; OLDGVN: BB1: +; OLDGVN-NEXT: br i1 [[COND1:%.*]], label [[BB2:%.*]], label [[BB3:%.*]] +; OLDGVN: BB2: +; OLDGVN-NEXT: br label [[LOOP2:%.*]] +; OLDGVN: BB3: +; OLDGVN-NEXT: br label [[LOOP2]] +; OLDGVN: Loop2: +; OLDGVN-NEXT: [[INDEX2:%.*]] = phi i64 [ [[TMP1]], [[BB2]] ], [ [[V2]], [[BB3]] ], [ [[INDEX2_INC:%.*]], [[LOOP2]] ] +; OLDGVN-NEXT: [[P2:%.*]] = bitcast i64* [[P]] to <2 x i64>* +; OLDGVN-NEXT: [[V6:%.*]] = extractelement <2 x i64> [[TMP3]], i64 1 +; OLDGVN-NEXT: [[TMP4:%.*]] = trunc i128 [[TMP2]] to i64 +; OLDGVN-NEXT: [[V8:%.*]] = add i64 [[V6]], [[INDEX2]] +; OLDGVN-NEXT: [[V9:%.*]] = add i64 [[V8]], [[TMP4]] +; OLDGVN-NEXT: [[INDEX2_INC]] = add i64 [[INDEX2]], 1 +; OLDGVN-NEXT: [[COND3:%.*]] = icmp ne i64 [[INDEX2_INC]], [[TC2:%.*]] +; OLDGVN-NEXT: br i1 [[COND3]], label [[LOOP2]], label [[EXIT:%.*]] +; OLDGVN: Exit: +; OLDGVN-NEXT: ret i64 [[V9]] +; +; NEWGVN-LABEL: @test45( +; NEWGVN-NEXT: Entry: +; NEWGVN-NEXT: br label [[LOOP1:%.*]] +; NEWGVN: Loop1: +; NEWGVN-NEXT: [[INDEX1:%.*]] = phi i64 [ 1, [[ENTRY:%.*]] ], [ [[INDEX1_INC:%.*]], [[LOOP1]] ] +; NEWGVN-NEXT: [[P1:%.*]] = bitcast i64* [[P:%.*]] to <4 x i64>* +; NEWGVN-NEXT: [[V1:%.*]] = load <4 x i64>, <4 x i64>* [[P1]], align 32 +; NEWGVN-NEXT: [[V2:%.*]] = extractelement <4 x i64> [[V1]], i64 2 +; NEWGVN-NEXT: [[INDEX1_INC]] = add i64 [[INDEX1]], 1 +; NEWGVN-NEXT: [[COND2:%.*]] = icmp ne i64 [[INDEX1_INC]], [[TC1:%.*]] +; NEWGVN-NEXT: br i1 [[COND2]], label [[LOOP1]], label [[BB1:%.*]] +; NEWGVN: BB1: +; NEWGVN-NEXT: br i1 [[COND1:%.*]], label [[BB2:%.*]], label [[BB3:%.*]] +; NEWGVN: BB2: +; NEWGVN-NEXT: [[V4:%.*]] = load i64, i64* [[P]], align 4 +; NEWGVN-NEXT: br label [[LOOP2:%.*]] +; NEWGVN: BB3: +; NEWGVN-NEXT: br label [[LOOP2]] +; NEWGVN: Loop2: +; NEWGVN-NEXT: [[INDEX2:%.*]] = phi i64 [ [[V4]], [[BB2]] ], [ [[V2]], [[BB3]] ], [ [[INDEX2_INC:%.*]], [[LOOP2]] ] +; NEWGVN-NEXT: [[P2:%.*]] = bitcast i64* [[P]] to <2 x i64>* +; NEWGVN-NEXT: [[V5:%.*]] = load <2 x i64>, <2 x i64>* [[P2]], align 16 +; NEWGVN-NEXT: [[V6:%.*]] = extractelement <2 x i64> [[V5]], i64 1 +; NEWGVN-NEXT: [[V7:%.*]] = load i64, i64* [[P]], align 4 +; NEWGVN-NEXT: [[V8:%.*]] = add i64 [[V6]], [[INDEX2]] +; NEWGVN-NEXT: [[V9:%.*]] = add i64 [[V8]], [[V7]] +; NEWGVN-NEXT: [[INDEX2_INC]] = add i64 [[INDEX2]], 1 +; NEWGVN-NEXT: [[COND3:%.*]] = icmp ne i64 [[INDEX2_INC]], [[TC2:%.*]] +; NEWGVN-NEXT: br i1 [[COND3]], label [[LOOP2]], label [[EXIT:%.*]] +; NEWGVN: Exit: +; NEWGVN-NEXT: ret i64 [[V9]] +; +Entry: + br label %Loop1 + +Loop1: + %Index1 = phi i64 [ 1, %Entry ], [ %Index1.inc, %Loop1 ] + %P1 = bitcast i64* %P to <4 x i64>* + %V1 = load <4 x i64>, <4 x i64>* %P1 + %V2 = extractelement <4 x i64> %V1, i64 2 + %Index1.inc = add i64 %Index1, 1 + %Cond2 = icmp ne i64 %Index1.inc, %TC1 + br i1 %Cond2, label %Loop1, label %BB1 + +BB1: + br i1 %Cond1, label %BB2, label %BB3 + +BB2: + %V4 = load i64, i64* %P + br label %Loop2 + +BB3: + br label %Loop2 + +Loop2: + %Index2 = phi i64 [ %V4, %BB2 ], [ %V2, %BB3 ], [ %Index2.inc, %Loop2 ] + %P2 = bitcast i64* %P to <2 x i64>* + %V5 = load <2 x i64>, <2 x i64>* %P2 + %V6 = extractelement <2 x i64> %V5, i64 1 + %V7 = load i64, i64* %P + %V8 = add i64 %V6, %Index2 + %V9 = add i64 %V8, %V7 + %Index2.inc = add i64 %Index2, 1 + %Cond3 = icmp ne i64 %Index2.inc, %TC2 + br i1 %Cond3, label %Loop2, label %Exit + +Exit: + ret i64 %V9 +} + +define i64 @test46(i64* %P, i64 %TC) { +; Entry _ +; | / | +; | v | +; Loop | +; | \__| +; | +; v +; Exit +; +; OLDGVN-LABEL: @test46( +; OLDGVN-NEXT: Entry: +; OLDGVN-NEXT: [[P2_PHI_TRANS_INSERT:%.*]] = bitcast i64* [[P:%.*]] to <2 x i64>* +; OLDGVN-NEXT: [[V1_PRE:%.*]] = load <2 x i64>, <2 x i64>* [[P2_PHI_TRANS_INSERT]], align 16 +; OLDGVN-NEXT: br label [[LOOP:%.*]] +; OLDGVN: Loop: +; OLDGVN-NEXT: [[INDEX:%.*]] = phi i64 [ 1, [[ENTRY:%.*]] ], [ [[INDEX_INC:%.*]], [[LOOP]] ] +; OLDGVN-NEXT: [[V2:%.*]] = extractelement <2 x i64> [[V1_PRE]], i64 1 +; OLDGVN-NEXT: [[V3:%.*]] = add i64 [[V2]], [[INDEX]] +; OLDGVN-NEXT: [[TMP0:%.*]] = bitcast <2 x i64> [[V1_PRE]] to i128 +; OLDGVN-NEXT: [[TMP1:%.*]] = trunc i128 [[TMP0]] to i64 +; OLDGVN-NEXT: [[V5:%.*]] = add i64 [[V3]], [[TMP1]] +; OLDGVN-NEXT: [[INDEX_INC]] = add i64 [[INDEX]], 1 +; OLDGVN-NEXT: [[COND:%.*]] = icmp ne i64 [[INDEX_INC]], [[TC:%.*]] +; OLDGVN-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]] +; OLDGVN: Exit: +; OLDGVN-NEXT: ret i64 [[V5]] +; +; NEWGVN-LABEL: @test46( +; NEWGVN-NEXT: Entry: +; NEWGVN-NEXT: br label [[LOOP:%.*]] +; NEWGVN: Loop: +; NEWGVN-NEXT: [[INDEX:%.*]] = phi i64 [ 1, [[ENTRY:%.*]] ], [ [[INDEX_INC:%.*]], [[LOOP]] ] +; NEWGVN-NEXT: [[P2:%.*]] = bitcast i64* [[P:%.*]] to <2 x i64>* +; NEWGVN-NEXT: [[V1:%.*]] = load <2 x i64>, <2 x i64>* [[P2]], align 16 +; NEWGVN-NEXT: [[V2:%.*]] = extractelement <2 x i64> [[V1]], i64 1 +; NEWGVN-NEXT: [[V3:%.*]] = add i64 [[V2]], [[INDEX]] +; NEWGVN-NEXT: [[V4:%.*]] = load i64, i64* [[P]], align 4 +; NEWGVN-NEXT: [[V5:%.*]] = add i64 [[V3]], [[V4]] +; NEWGVN-NEXT: [[INDEX_INC]] = add i64 [[INDEX]], 1 +; NEWGVN-NEXT: [[COND:%.*]] = icmp ne i64 [[INDEX_INC]], [[TC:%.*]] +; NEWGVN-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]] +; NEWGVN: Exit: +; NEWGVN-NEXT: ret i64 [[V5]] +; +Entry: + br label %Loop + +Loop: + %Index = phi i64 [ 1, %Entry ], [ %Index.inc, %Loop ] + %P2 = bitcast i64* %P to <2 x i64>* + %V1 = load <2 x i64>, <2 x i64>* %P2 + %V2 = extractelement <2 x i64> %V1, i64 1 + %V3 = add i64 %V2, %Index + %V4 = load i64, i64* %P + %V5 = add i64 %V3, %V4 + %Index.inc = add i64 %Index, 1 + %Cond = icmp ne i64 %Index.inc, %TC + br i1 %Cond, label %Loop, label %Exit + +Exit: + ret i64 %V5 +} + +define i64 @test47(i64* %P, i64 %TC) { +; Entry _ +; | / | +; | v | +; Loop | +; | \__| +; | +; v +; Exit +; +; OLDGVN-LABEL: @test47( +; OLDGVN-NEXT: Entry: +; OLDGVN-NEXT: [[V1_PRE:%.*]] = load i64, i64* [[P:%.*]], align 4 +; OLDGVN-NEXT: [[P2_PHI_TRANS_INSERT:%.*]] = bitcast i64* [[P]] to <2 x i64>* +; OLDGVN-NEXT: [[V2_PRE:%.*]] = load <2 x i64>, <2 x i64>* [[P2_PHI_TRANS_INSERT]], align 16 +; OLDGVN-NEXT: br label [[LOOP:%.*]] +; OLDGVN: Loop: +; OLDGVN-NEXT: [[V1:%.*]] = phi i64 [ [[V1_PRE]], [[ENTRY:%.*]] ], [ [[TMP1:%.*]], [[LOOP]] ] +; OLDGVN-NEXT: [[INDEX:%.*]] = phi i64 [ 1, [[ENTRY]] ], [ [[INDEX_INC:%.*]], [[LOOP]] ] +; OLDGVN-NEXT: [[V3:%.*]] = extractelement <2 x i64> [[V2_PRE]], i64 1 +; OLDGVN-NEXT: [[V4:%.*]] = add i64 [[V3]], [[INDEX]] +; OLDGVN-NEXT: [[V5:%.*]] = add i64 [[V1]], [[V4]] +; OLDGVN-NEXT: [[INDEX_INC]] = add i64 [[INDEX]], 1 +; OLDGVN-NEXT: [[COND:%.*]] = icmp ne i64 [[INDEX_INC]], [[TC:%.*]] +; OLDGVN-NEXT: [[TMP0:%.*]] = bitcast <2 x i64> [[V2_PRE]] to i128 +; OLDGVN-NEXT: [[TMP1]] = trunc i128 [[TMP0]] to i64 +; OLDGVN-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]] +; OLDGVN: Exit: +; OLDGVN-NEXT: ret i64 [[V5]] +; +; NEWGVN-LABEL: @test47( +; NEWGVN-NEXT: Entry: +; NEWGVN-NEXT: br label [[LOOP:%.*]] +; NEWGVN: Loop: +; NEWGVN-NEXT: [[INDEX:%.*]] = phi i64 [ 1, [[ENTRY:%.*]] ], [ [[INDEX_INC:%.*]], [[LOOP]] ] +; NEWGVN-NEXT: [[V1:%.*]] = load i64, i64* [[P:%.*]], align 4 +; NEWGVN-NEXT: [[P2:%.*]] = bitcast i64* [[P]] to <2 x i64>* +; NEWGVN-NEXT: [[V2:%.*]] = load <2 x i64>, <2 x i64>* [[P2]], align 16 +; NEWGVN-NEXT: [[V3:%.*]] = extractelement <2 x i64> [[V2]], i64 1 +; NEWGVN-NEXT: [[V4:%.*]] = add i64 [[V3]], [[INDEX]] +; NEWGVN-NEXT: [[V5:%.*]] = add i64 [[V1]], [[V4]] +; NEWGVN-NEXT: [[INDEX_INC]] = add i64 [[INDEX]], 1 +; NEWGVN-NEXT: [[COND:%.*]] = icmp ne i64 [[INDEX_INC]], [[TC:%.*]] +; NEWGVN-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]] +; NEWGVN: Exit: +; NEWGVN-NEXT: ret i64 [[V5]] +; +Entry: + br label %Loop + +Loop: + %Index = phi i64 [ 1, %Entry ], [ %Index.inc, %Loop ] + %V1 = load i64, i64* %P + %P2 = bitcast i64* %P to <2 x i64>* + %V2 = load <2 x i64>, <2 x i64>* %P2 + %V3 = extractelement <2 x i64> %V2, i64 1 + %V4 = add i64 %V3, %Index + %V5 = add i64 %V1, %V4 + %Index.inc = add i64 %Index, 1 + %Cond = icmp ne i64 %Index.inc, %TC + br i1 %Cond, label %Loop, label %Exit + +Exit: + ret i64 %V5 +} + +define i64 @test48(i64* %P, i64 %TC) { +; Entry _ +; | / | +; | v | +; Loop | +; | \__| +; | +; v +; Exit +; +; OLDGVN-LABEL: @test48( +; OLDGVN-NEXT: Entry: +; OLDGVN-NEXT: [[V1_PRE:%.*]] = load i64, i64* [[P:%.*]], align 4 +; OLDGVN-NEXT: br label [[LOOP:%.*]] +; OLDGVN: Loop: +; OLDGVN-NEXT: [[V1:%.*]] = phi i64 [ [[V1_PRE]], [[ENTRY:%.*]] ], [ [[TMP3:%.*]], [[LOOP]] ] +; OLDGVN-NEXT: [[INDEX:%.*]] = phi i64 [ 1, [[ENTRY]] ], [ [[INDEX_INC:%.*]], [[LOOP]] ] +; OLDGVN-NEXT: [[P1:%.*]] = bitcast i64* [[P]] to <4 x i64>* +; OLDGVN-NEXT: [[I1:%.*]] = insertelement <4 x i64> poison, i64 [[INDEX]], i32 0 +; OLDGVN-NEXT: [[I2:%.*]] = insertelement <4 x i64> [[I1]], i64 [[INDEX]], i32 1 +; OLDGVN-NEXT: [[I3:%.*]] = insertelement <4 x i64> [[I2]], i64 100, i32 2 +; OLDGVN-NEXT: [[I4:%.*]] = insertelement <4 x i64> [[I3]], i64 1000, i32 3 +; OLDGVN-NEXT: store <4 x i64> [[I4]], <4 x i64>* [[P1]], align 32 +; OLDGVN-NEXT: [[P2:%.*]] = bitcast i64* [[P]] to <2 x i64>* +; OLDGVN-NEXT: [[TMP0:%.*]] = bitcast <4 x i64> [[I4]] to i256 +; OLDGVN-NEXT: [[TMP1:%.*]] = trunc i256 [[TMP0]] to i128 +; OLDGVN-NEXT: [[TMP2:%.*]] = bitcast i128 [[TMP1]] to <2 x i64> +; OLDGVN-NEXT: [[V3:%.*]] = extractelement <2 x i64> [[TMP2]], i64 1 +; OLDGVN-NEXT: [[V4:%.*]] = add i64 [[V1]], [[V3]] +; OLDGVN-NEXT: [[INDEX_INC]] = add i64 [[INDEX]], 1 +; OLDGVN-NEXT: [[COND:%.*]] = icmp ne i64 [[INDEX_INC]], [[TC:%.*]] +; OLDGVN-NEXT: [[TMP3]] = trunc i128 [[TMP1]] to i64 +; OLDGVN-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]] +; OLDGVN: Exit: +; OLDGVN-NEXT: ret i64 [[V4]] +; +; NEWGVN-LABEL: @test48( +; NEWGVN-NEXT: Entry: +; NEWGVN-NEXT: br label [[LOOP:%.*]] +; NEWGVN: Loop: +; NEWGVN-NEXT: [[INDEX:%.*]] = phi i64 [ 1, [[ENTRY:%.*]] ], [ [[INDEX_INC:%.*]], [[LOOP]] ] +; NEWGVN-NEXT: [[V1:%.*]] = load i64, i64* [[P:%.*]], align 4 +; NEWGVN-NEXT: [[P1:%.*]] = bitcast i64* [[P]] to <4 x i64>* +; NEWGVN-NEXT: [[I1:%.*]] = insertelement <4 x i64> poison, i64 [[INDEX]], i32 0 +; NEWGVN-NEXT: [[I2:%.*]] = insertelement <4 x i64> [[I1]], i64 [[INDEX]], i32 1 +; NEWGVN-NEXT: [[I3:%.*]] = insertelement <4 x i64> [[I2]], i64 100, i32 2 +; NEWGVN-NEXT: [[I4:%.*]] = insertelement <4 x i64> [[I3]], i64 1000, i32 3 +; NEWGVN-NEXT: store <4 x i64> [[I4]], <4 x i64>* [[P1]], align 32 +; NEWGVN-NEXT: [[P2:%.*]] = bitcast i64* [[P]] to <2 x i64>* +; NEWGVN-NEXT: [[V2:%.*]] = load <2 x i64>, <2 x i64>* [[P2]], align 16 +; NEWGVN-NEXT: [[V3:%.*]] = extractelement <2 x i64> [[V2]], i64 1 +; NEWGVN-NEXT: [[V4:%.*]] = add i64 [[V1]], [[V3]] +; NEWGVN-NEXT: [[INDEX_INC]] = add i64 [[INDEX]], 1 +; NEWGVN-NEXT: [[COND:%.*]] = icmp ne i64 [[INDEX_INC]], [[TC:%.*]] +; NEWGVN-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]] +; NEWGVN: Exit: +; NEWGVN-NEXT: ret i64 [[V4]] +; +Entry: + br label %Loop + +Loop: + %Index = phi i64 [ 1, %Entry ], [ %Index.inc, %Loop ] + %V1 = load i64, i64* %P + %P1 = bitcast i64* %P to <4 x i64>* + %I1 = insertelement <4 x i64> poison, i64 %Index, i32 0 + %I2 = insertelement <4 x i64> %I1, i64 %Index, i32 1 + %I3 = insertelement <4 x i64> %I2, i64 100, i32 2 + %I4 = insertelement <4 x i64> %I3, i64 1000, i32 3 + store <4 x i64> %I4, <4 x i64>* %P1 + %P2 = bitcast i64* %P to <2 x i64>* + %V2 = load <2 x i64>, <2 x i64>* %P2 + %V3 = extractelement <2 x i64> %V2, i64 1 + %V4 = add i64 %V1, %V3 + %Index.inc = add i64 %Index, 1 + %Cond = icmp ne i64 %Index.inc, %TC + br i1 %Cond, label %Loop, label %Exit + +Exit: + ret i64 %V4 +} + +define void @test49(i64* %P, i64 %TC) { +; Entry _ +; | / | +; | v | +; Loop | +; | \__| +; | +; v +; Exit +; +; OLDGVN-LABEL: @test49( +; OLDGVN-NEXT: Entry: +; OLDGVN-NEXT: [[V1_PRE:%.*]] = load i64, i64* [[P:%.*]], align 4 +; OLDGVN-NEXT: br label [[LOOP:%.*]] +; OLDGVN: Loop: +; OLDGVN-NEXT: [[V1:%.*]] = phi i64 [ [[V1_PRE]], [[ENTRY:%.*]] ], [ [[TMP1:%.*]], [[LOOP]] ] +; OLDGVN-NEXT: [[INDEX:%.*]] = phi i64 [ 1, [[ENTRY]] ], [ [[INDEX_INC:%.*]], [[LOOP]] ] +; OLDGVN-NEXT: [[P1:%.*]] = bitcast i64* [[P]] to <4 x i64>* +; OLDGVN-NEXT: [[I1:%.*]] = insertelement <4 x i64> poison, i64 [[INDEX]], i32 0 +; OLDGVN-NEXT: [[I2:%.*]] = insertelement <4 x i64> [[I1]], i64 [[V1]], i32 1 +; OLDGVN-NEXT: [[I3:%.*]] = insertelement <4 x i64> [[I2]], i64 100, i32 2 +; OLDGVN-NEXT: [[I4:%.*]] = insertelement <4 x i64> [[I3]], i64 1000, i32 3 +; OLDGVN-NEXT: store <4 x i64> [[I4]], <4 x i64>* [[P1]], align 32 +; OLDGVN-NEXT: [[INDEX_INC]] = add i64 [[INDEX]], 1 +; OLDGVN-NEXT: [[COND:%.*]] = icmp ne i64 [[INDEX_INC]], [[TC:%.*]] +; OLDGVN-NEXT: [[TMP0:%.*]] = bitcast <4 x i64> [[I4]] to i256 +; OLDGVN-NEXT: [[TMP1]] = trunc i256 [[TMP0]] to i64 +; OLDGVN-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]] +; OLDGVN: Exit: +; OLDGVN-NEXT: ret void +; +; NEWGVN-LABEL: @test49( +; NEWGVN-NEXT: Entry: +; NEWGVN-NEXT: br label [[LOOP:%.*]] +; NEWGVN: Loop: +; NEWGVN-NEXT: [[INDEX:%.*]] = phi i64 [ 1, [[ENTRY:%.*]] ], [ [[INDEX_INC:%.*]], [[LOOP]] ] +; NEWGVN-NEXT: [[V1:%.*]] = load i64, i64* [[P:%.*]], align 4 +; NEWGVN-NEXT: [[P1:%.*]] = bitcast i64* [[P]] to <4 x i64>* +; NEWGVN-NEXT: [[I1:%.*]] = insertelement <4 x i64> poison, i64 [[INDEX]], i32 0 +; NEWGVN-NEXT: [[I2:%.*]] = insertelement <4 x i64> [[I1]], i64 [[V1]], i32 1 +; NEWGVN-NEXT: [[I3:%.*]] = insertelement <4 x i64> [[I2]], i64 100, i32 2 +; NEWGVN-NEXT: [[I4:%.*]] = insertelement <4 x i64> [[I3]], i64 1000, i32 3 +; NEWGVN-NEXT: store <4 x i64> [[I4]], <4 x i64>* [[P1]], align 32 +; NEWGVN-NEXT: [[INDEX_INC]] = add i64 [[INDEX]], 1 +; NEWGVN-NEXT: [[COND:%.*]] = icmp ne i64 [[INDEX_INC]], [[TC:%.*]] +; NEWGVN-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]] +; NEWGVN: Exit: +; NEWGVN-NEXT: ret void +; +Entry: + br label %Loop + +Loop: + %Index = phi i64 [ 1, %Entry ], [ %Index.inc, %Loop ] + %V1 = load i64, i64* %P + %P1 = bitcast i64* %P to <4 x i64>* + %I1 = insertelement <4 x i64> poison, i64 %Index, i32 0 + %I2 = insertelement <4 x i64> %I1, i64 %V1, i32 1 + %I3 = insertelement <4 x i64> %I2, i64 100, i32 2 + %I4 = insertelement <4 x i64> %I3, i64 1000, i32 3 + store <4 x i64> %I4, <4 x i64>* %P1 + %Index.inc = add i64 %Index, 1 + %Cond = icmp ne i64 %Index.inc, %TC + br i1 %Cond, label %Loop, label %Exit + +Exit: + ret void +} + +define i64 @test50(i64* %P, i64 %TC1, i1 %Cond1, i64 %TC2) { +; Entry _ +; | / | +; | v | +; Loop1 | +; | \__| +; | +; BB1 +; / \ +; BB2 BB3 +; \ / _ +; | / | +; | v | +; Loop2 | +; | \__| +; | +; v +; Exit +; +; OLDGVN-LABEL: @test50( +; OLDGVN-NEXT: Entry: +; OLDGVN-NEXT: [[P1_PHI_TRANS_INSERT:%.*]] = bitcast i64* [[P:%.*]] to <4 x i64>* +; OLDGVN-NEXT: [[V1_PRE:%.*]] = load <4 x i64>, <4 x i64>* [[P1_PHI_TRANS_INSERT]], align 32 +; OLDGVN-NEXT: [[TMP0:%.*]] = bitcast <4 x i64> [[V1_PRE]] to i256 +; OLDGVN-NEXT: [[TMP1:%.*]] = trunc i256 [[TMP0]] to i64 +; OLDGVN-NEXT: br label [[LOOP1:%.*]] +; OLDGVN: Loop1: +; OLDGVN-NEXT: [[INDEX1:%.*]] = phi i64 [ 1, [[ENTRY:%.*]] ], [ [[INDEX1_INC:%.*]], [[LOOP1]] ] +; OLDGVN-NEXT: [[V2:%.*]] = extractelement <4 x i64> [[V1_PRE]], i64 2 +; OLDGVN-NEXT: [[INDEX1_INC]] = add i64 [[INDEX1]], 1 +; OLDGVN-NEXT: [[COND2:%.*]] = icmp ne i64 [[INDEX1_INC]], [[TC1:%.*]] +; OLDGVN-NEXT: br i1 [[COND2]], label [[LOOP1]], label [[BB1:%.*]] +; OLDGVN: BB1: +; OLDGVN-NEXT: br i1 [[COND1:%.*]], label [[BB2:%.*]], label [[BB3:%.*]] +; OLDGVN: BB2: +; OLDGVN-NEXT: br label [[LOOP2:%.*]] +; OLDGVN: BB3: +; OLDGVN-NEXT: br label [[LOOP2]] +; OLDGVN: Loop2: +; OLDGVN-NEXT: [[INDEX2:%.*]] = phi i64 [ [[TMP1]], [[BB2]] ], [ [[V2]], [[BB3]] ], [ [[INDEX2_INC:%.*]], [[LOOP2]] ] +; OLDGVN-NEXT: [[P2:%.*]] = bitcast i64* [[P]] to <2 x i64>* +; OLDGVN-NEXT: [[V5:%.*]] = load <2 x i64>, <2 x i64>* [[P2]], align 16 +; OLDGVN-NEXT: [[V6:%.*]] = extractelement <2 x i64> [[V5]], i64 1 +; OLDGVN-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[V5]] to i128 +; OLDGVN-NEXT: [[TMP3:%.*]] = trunc i128 [[TMP2]] to i64 +; OLDGVN-NEXT: [[V8:%.*]] = add i64 [[V6]], [[INDEX2]] +; OLDGVN-NEXT: [[V9:%.*]] = add i64 [[V8]], [[TMP3]] +; OLDGVN-NEXT: store i64 [[V9]], i64* [[P]], align 4 +; OLDGVN-NEXT: [[INDEX2_INC]] = add i64 [[INDEX2]], 1 +; OLDGVN-NEXT: [[COND3:%.*]] = icmp ne i64 [[INDEX2_INC]], [[TC2:%.*]] +; OLDGVN-NEXT: br i1 [[COND3]], label [[LOOP2]], label [[EXIT:%.*]] +; OLDGVN: Exit: +; OLDGVN-NEXT: ret i64 [[V9]] +; +; NEWGVN-LABEL: @test50( +; NEWGVN-NEXT: Entry: +; NEWGVN-NEXT: br label [[LOOP1:%.*]] +; NEWGVN: Loop1: +; NEWGVN-NEXT: [[INDEX1:%.*]] = phi i64 [ 1, [[ENTRY:%.*]] ], [ [[INDEX1_INC:%.*]], [[LOOP1]] ] +; NEWGVN-NEXT: [[P1:%.*]] = bitcast i64* [[P:%.*]] to <4 x i64>* +; NEWGVN-NEXT: [[V1:%.*]] = load <4 x i64>, <4 x i64>* [[P1]], align 32 +; NEWGVN-NEXT: [[V2:%.*]] = extractelement <4 x i64> [[V1]], i64 2 +; NEWGVN-NEXT: [[INDEX1_INC]] = add i64 [[INDEX1]], 1 +; NEWGVN-NEXT: [[COND2:%.*]] = icmp ne i64 [[INDEX1_INC]], [[TC1:%.*]] +; NEWGVN-NEXT: br i1 [[COND2]], label [[LOOP1]], label [[BB1:%.*]] +; NEWGVN: BB1: +; NEWGVN-NEXT: br i1 [[COND1:%.*]], label [[BB2:%.*]], label [[BB3:%.*]] +; NEWGVN: BB2: +; NEWGVN-NEXT: [[V4:%.*]] = load i64, i64* [[P]], align 4 +; NEWGVN-NEXT: br label [[LOOP2:%.*]] +; NEWGVN: BB3: +; NEWGVN-NEXT: br label [[LOOP2]] +; NEWGVN: Loop2: +; NEWGVN-NEXT: [[INDEX2:%.*]] = phi i64 [ [[V4]], [[BB2]] ], [ [[V2]], [[BB3]] ], [ [[INDEX2_INC:%.*]], [[LOOP2]] ] +; NEWGVN-NEXT: [[P2:%.*]] = bitcast i64* [[P]] to <2 x i64>* +; NEWGVN-NEXT: [[V5:%.*]] = load <2 x i64>, <2 x i64>* [[P2]], align 16 +; NEWGVN-NEXT: [[V6:%.*]] = extractelement <2 x i64> [[V5]], i64 1 +; NEWGVN-NEXT: [[V7:%.*]] = load i64, i64* [[P]], align 4 +; NEWGVN-NEXT: [[V8:%.*]] = add i64 [[V6]], [[INDEX2]] +; NEWGVN-NEXT: [[V9:%.*]] = add i64 [[V8]], [[V7]] +; NEWGVN-NEXT: store i64 [[V9]], i64* [[P]], align 4 +; NEWGVN-NEXT: [[INDEX2_INC]] = add i64 [[INDEX2]], 1 +; NEWGVN-NEXT: [[COND3:%.*]] = icmp ne i64 [[INDEX2_INC]], [[TC2:%.*]] +; NEWGVN-NEXT: br i1 [[COND3]], label [[LOOP2]], label [[EXIT:%.*]] +; NEWGVN: Exit: +; NEWGVN-NEXT: ret i64 [[V9]] +; +Entry: + br label %Loop1 + +Loop1: + %Index1 = phi i64 [ 1, %Entry ], [ %Index1.inc, %Loop1 ] + %P1 = bitcast i64* %P to <4 x i64>* + %V1 = load <4 x i64>, <4 x i64>* %P1 + %V2 = extractelement <4 x i64> %V1, i64 2 + %Index1.inc = add i64 %Index1, 1 + %Cond2 = icmp ne i64 %Index1.inc, %TC1 + br i1 %Cond2, label %Loop1, label %BB1 + +BB1: + br i1 %Cond1, label %BB2, label %BB3 + +BB2: + %V4 = load i64, i64* %P + br label %Loop2 + +BB3: + br label %Loop2 + +Loop2: + %Index2 = phi i64 [ %V4, %BB2 ], [ %V2, %BB3 ], [ %Index2.inc, %Loop2 ] + %P2 = bitcast i64* %P to <2 x i64>* + %V5 = load <2 x i64>, <2 x i64>* %P2 + %V6 = extractelement <2 x i64> %V5, i64 1 + %V7 = load i64, i64* %P + %V8 = add i64 %V6, %Index2 + %V9 = add i64 %V8, %V7 + store i64 %V9, i64* %P + %Index2.inc = add i64 %Index2, 1 + %Cond3 = icmp ne i64 %Index2.inc, %TC2 + br i1 %Cond3, label %Loop2, label %Exit + +Exit: + ret i64 %V9 +} + +define i64 @test51(i64* %P, i64 %TC, i1 %Cond) { +; Entry +; | +; Loop<-----+ +; / \ | +; BB1 BB2 | +; \ / | +; BB3 | +; | | +; Loop.Latch--+ +; | +; v +; Exit +; +; OLDGVN-LABEL: @test51( +; OLDGVN-NEXT: Entry: +; OLDGVN-NEXT: [[P1_PHI_TRANS_INSERT:%.*]] = bitcast i64* [[P:%.*]] to <4 x i64>* +; OLDGVN-NEXT: [[V1_PRE:%.*]] = load <4 x i64>, <4 x i64>* [[P1_PHI_TRANS_INSERT]], align 32 +; OLDGVN-NEXT: br label [[LOOP:%.*]] +; OLDGVN: Loop: +; OLDGVN-NEXT: [[INDEX:%.*]] = phi i64 [ 1, [[ENTRY:%.*]] ], [ [[INDEX_INC:%.*]], [[BB3:%.*]] ] +; OLDGVN-NEXT: [[V2:%.*]] = extractelement <4 x i64> [[V1_PRE]], i64 2 +; OLDGVN-NEXT: [[TMP0:%.*]] = bitcast <4 x i64> [[V1_PRE]] to i256 +; OLDGVN-NEXT: [[TMP1:%.*]] = trunc i256 [[TMP0]] to i64 +; OLDGVN-NEXT: [[V4:%.*]] = add i64 [[TMP1]], [[V2]] +; OLDGVN-NEXT: br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] +; OLDGVN: BB1: +; OLDGVN-NEXT: br label [[BB3]] +; OLDGVN: BB2: +; OLDGVN-NEXT: br label [[BB3]] +; OLDGVN: BB3: +; OLDGVN-NEXT: [[PHI:%.*]] = phi i64 [ [[V4]], [[BB1]] ], [ [[TMP1]], [[BB2]] ] +; OLDGVN-NEXT: [[V6:%.*]] = add i64 [[PHI]], [[INDEX]] +; OLDGVN-NEXT: [[INDEX_INC]] = add i64 [[INDEX]], 1 +; OLDGVN-NEXT: [[COND1:%.*]] = icmp ne i64 [[INDEX_INC]], [[TC:%.*]] +; OLDGVN-NEXT: br i1 [[COND1]], label [[LOOP]], label [[EXIT:%.*]] +; OLDGVN: Exit: +; OLDGVN-NEXT: ret i64 [[V6]] +; +; NEWGVN-LABEL: @test51( +; NEWGVN-NEXT: Entry: +; NEWGVN-NEXT: br label [[LOOP:%.*]] +; NEWGVN: Loop: +; NEWGVN-NEXT: [[INDEX:%.*]] = phi i64 [ 1, [[ENTRY:%.*]] ], [ [[INDEX_INC:%.*]], [[LOOP_LATCH:%.*]] ] +; NEWGVN-NEXT: [[P1:%.*]] = bitcast i64* [[P:%.*]] to <4 x i64>* +; NEWGVN-NEXT: [[V1:%.*]] = load <4 x i64>, <4 x i64>* [[P1]], align 32 +; NEWGVN-NEXT: [[V2:%.*]] = extractelement <4 x i64> [[V1]], i64 2 +; NEWGVN-NEXT: [[V3:%.*]] = load i64, i64* [[P]], align 4 +; NEWGVN-NEXT: [[V4:%.*]] = add i64 [[V3]], [[V2]] +; NEWGVN-NEXT: br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] +; NEWGVN: BB1: +; NEWGVN-NEXT: br label [[BB3:%.*]] +; NEWGVN: BB2: +; NEWGVN-NEXT: br label [[BB3]] +; NEWGVN: BB3: +; NEWGVN-NEXT: [[PHI:%.*]] = phi i64 [ [[V4]], [[BB1]] ], [ [[V3]], [[BB2]] ] +; NEWGVN-NEXT: [[V6:%.*]] = add i64 [[PHI]], [[INDEX]] +; NEWGVN-NEXT: br label [[LOOP_LATCH]] +; NEWGVN: Loop.Latch: +; NEWGVN-NEXT: [[INDEX_INC]] = add i64 [[INDEX]], 1 +; NEWGVN-NEXT: [[COND1:%.*]] = icmp ne i64 [[INDEX_INC]], [[TC:%.*]] +; NEWGVN-NEXT: br i1 [[COND1]], label [[LOOP]], label [[EXIT:%.*]] +; NEWGVN: Exit: +; NEWGVN-NEXT: ret i64 [[V6]] +; +Entry: + br label %Loop + +Loop: + %Index = phi i64 [ 1, %Entry ], [ %Index.inc, %Loop.Latch ] + %P1 = bitcast i64* %P to <4 x i64>* + %V1 = load <4 x i64>, <4 x i64>* %P1 + %V2 = extractelement <4 x i64> %V1, i64 2 + %V3 = load i64, i64* %P + %V4 = add i64 %V3, %V2 + br i1 %Cond, label %BB1, label %BB2 + +BB1: + br label %BB3 + +BB2: + %V5 = load i64, i64* %P + br label %BB3 + +BB3: + %Phi = phi i64 [ %V4, %BB1 ], [ %V5, %BB2 ] + %V6 = add i64 %Phi, %Index + br label %Loop.Latch + +Loop.Latch: + %Index.inc = add i64 %Index, 1 + %Cond1 = icmp ne i64 %Index.inc, %TC + br i1 %Cond1, label %Loop, label %Exit + +Exit: + ret i64 %V6 +} + +define i64 @test52(i64* %P, i64 %TC, i1 %Cond1) { +; Entry +; | +; Loop<-----+ +; / \ | +; BB1 BB2 | +; \ / | +; BB3 | +; | | +; Loop.Latch--+ +; | +; v +; Exit +; +; OLDGVN-LABEL: @test52( +; OLDGVN-NEXT: Entry: +; OLDGVN-NEXT: [[P1_PHI_TRANS_INSERT:%.*]] = bitcast i64* [[P:%.*]] to <4 x i64>* +; OLDGVN-NEXT: [[V1_PRE:%.*]] = load <4 x i64>, <4 x i64>* [[P1_PHI_TRANS_INSERT]], align 32 +; OLDGVN-NEXT: br label [[LOOP:%.*]] +; OLDGVN: Loop: +; OLDGVN-NEXT: [[V1:%.*]] = phi <4 x i64> [ [[V1_PRE]], [[ENTRY:%.*]] ], [ [[I1:%.*]], [[BB3:%.*]] ] +; OLDGVN-NEXT: [[INDEX:%.*]] = phi i64 [ 1, [[ENTRY]] ], [ [[INDEX_INC:%.*]], [[BB3]] ] +; OLDGVN-NEXT: [[I1]] = insertelement <4 x i64> [[V1]], i64 [[INDEX]], i32 1 +; OLDGVN-NEXT: store <4 x i64> [[I1]], <4 x i64>* [[P1_PHI_TRANS_INSERT]], align 32 +; OLDGVN-NEXT: [[TMP0:%.*]] = bitcast <4 x i64> [[I1]] to i256 +; OLDGVN-NEXT: [[TMP1:%.*]] = trunc i256 [[TMP0]] to i64 +; OLDGVN-NEXT: br i1 [[COND1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] +; OLDGVN: BB1: +; OLDGVN-NEXT: br label [[BB3]] +; OLDGVN: BB2: +; OLDGVN-NEXT: br label [[BB3]] +; OLDGVN: BB3: +; OLDGVN-NEXT: [[PHI:%.*]] = phi i64 [ 100, [[BB1]] ], [ [[TMP1]], [[BB2]] ] +; OLDGVN-NEXT: [[V3:%.*]] = add i64 [[PHI]], [[INDEX]] +; OLDGVN-NEXT: [[INDEX_INC]] = add i64 [[INDEX]], 1 +; OLDGVN-NEXT: [[COND2:%.*]] = icmp ne i64 [[INDEX_INC]], [[TC:%.*]] +; OLDGVN-NEXT: br i1 [[COND2]], label [[LOOP]], label [[EXIT:%.*]] +; OLDGVN: Exit: +; OLDGVN-NEXT: ret i64 [[V3]] +; +; NEWGVN-LABEL: @test52( +; NEWGVN-NEXT: Entry: +; NEWGVN-NEXT: br label [[LOOP:%.*]] +; NEWGVN: Loop: +; NEWGVN-NEXT: [[INDEX:%.*]] = phi i64 [ 1, [[ENTRY:%.*]] ], [ [[INDEX_INC:%.*]], [[LOOP_LATCH:%.*]] ] +; NEWGVN-NEXT: [[P1:%.*]] = bitcast i64* [[P:%.*]] to <4 x i64>* +; NEWGVN-NEXT: [[V1:%.*]] = load <4 x i64>, <4 x i64>* [[P1]], align 32 +; NEWGVN-NEXT: [[I1:%.*]] = insertelement <4 x i64> [[V1]], i64 [[INDEX]], i32 1 +; NEWGVN-NEXT: store <4 x i64> [[I1]], <4 x i64>* [[P1]], align 32 +; NEWGVN-NEXT: br i1 [[COND1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] +; NEWGVN: BB1: +; NEWGVN-NEXT: br label [[BB3:%.*]] +; NEWGVN: BB2: +; NEWGVN-NEXT: [[V2:%.*]] = load i64, i64* [[P]], align 4 +; NEWGVN-NEXT: br label [[BB3]] +; NEWGVN: BB3: +; NEWGVN-NEXT: [[PHI:%.*]] = phi i64 [ 100, [[BB1]] ], [ [[V2]], [[BB2]] ] +; NEWGVN-NEXT: [[V3:%.*]] = add i64 [[PHI]], [[INDEX]] +; NEWGVN-NEXT: br label [[LOOP_LATCH]] +; NEWGVN: Loop.Latch: +; NEWGVN-NEXT: [[INDEX_INC]] = add i64 [[INDEX]], 1 +; NEWGVN-NEXT: [[COND2:%.*]] = icmp ne i64 [[INDEX_INC]], [[TC:%.*]] +; NEWGVN-NEXT: br i1 [[COND2]], label [[LOOP]], label [[EXIT:%.*]] +; NEWGVN: Exit: +; NEWGVN-NEXT: ret i64 [[V3]] +; +Entry: + br label %Loop + +Loop: + %Index = phi i64 [ 1, %Entry ], [ %Index.inc, %Loop.Latch ] + %P1 = bitcast i64* %P to <4 x i64>* + %V1 = load <4 x i64>, <4 x i64>* %P1 + %I1 = insertelement <4 x i64> %V1, i64 %Index, i32 1 + store <4 x i64> %I1, <4 x i64>* %P1 + br i1 %Cond1, label %BB1, label %BB2 + +BB1: + br label %BB3 + +BB2: + %V2 = load i64, i64* %P + br label %BB3 + +BB3: + %Phi = phi i64 [ 100, %BB1 ], [ %V2, %BB2 ] + %V3 = add i64 %Phi, %Index + br label %Loop.Latch + +Loop.Latch: + %Index.inc = add i64 %Index, 1 + %Cond2 = icmp ne i64 %Index.inc, %TC + br i1 %Cond2, label %Loop, label %Exit + +Exit: + ret i64 %V3 +} + +define i64 @test53(i64* %P, i64 %TC, i1 %Cond1) { +; Entry +; | +; Loop<-----+ +; / \ | +; BB1 BB2 | +; \ / | +; BB3 | +; | | +; Loop.Latch--+ +; | +; v +; Exit +; +; OLDGVN-LABEL: @test53( +; OLDGVN-NEXT: Entry: +; OLDGVN-NEXT: [[P1_PHI_TRANS_INSERT:%.*]] = bitcast i64* [[P:%.*]] to <4 x i64>* +; OLDGVN-NEXT: [[V1_PRE:%.*]] = load <4 x i64>, <4 x i64>* [[P1_PHI_TRANS_INSERT]], align 32 +; OLDGVN-NEXT: br label [[LOOP:%.*]] +; OLDGVN: Loop: +; OLDGVN-NEXT: [[V1:%.*]] = phi <4 x i64> [ [[V1_PRE]], [[ENTRY:%.*]] ], [ [[V12:%.*]], [[BB3:%.*]] ] +; OLDGVN-NEXT: [[INDEX:%.*]] = phi i64 [ 1, [[ENTRY]] ], [ [[INDEX_INC:%.*]], [[BB3]] ] +; OLDGVN-NEXT: [[TMP0:%.*]] = bitcast <4 x i64> [[V1]] to i256 +; OLDGVN-NEXT: [[TMP1:%.*]] = trunc i256 [[TMP0]] to i64 +; OLDGVN-NEXT: br i1 [[COND1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] +; OLDGVN: BB1: +; OLDGVN-NEXT: [[I1:%.*]] = insertelement <4 x i64> [[V1]], i64 [[INDEX]], i32 1 +; OLDGVN-NEXT: store <4 x i64> [[I1]], <4 x i64>* [[P1_PHI_TRANS_INSERT]], align 32 +; OLDGVN-NEXT: [[TMP2:%.*]] = bitcast <4 x i64> [[I1]] to i256 +; OLDGVN-NEXT: [[TMP3:%.*]] = trunc i256 [[TMP2]] to i64 +; OLDGVN-NEXT: br label [[BB3]] +; OLDGVN: BB2: +; OLDGVN-NEXT: br label [[BB3]] +; OLDGVN: BB3: +; OLDGVN-NEXT: [[V12]] = phi <4 x i64> [ [[V1]], [[BB2]] ], [ [[I1]], [[BB1]] ] +; OLDGVN-NEXT: [[V2:%.*]] = phi i64 [ [[TMP1]], [[BB2]] ], [ [[TMP3]], [[BB1]] ] +; OLDGVN-NEXT: [[V3:%.*]] = add i64 [[V2]], [[INDEX]] +; OLDGVN-NEXT: [[INDEX_INC]] = add i64 [[INDEX]], 1 +; OLDGVN-NEXT: [[COND2:%.*]] = icmp ne i64 [[INDEX_INC]], [[TC:%.*]] +; OLDGVN-NEXT: br i1 [[COND2]], label [[LOOP]], label [[EXIT:%.*]] +; OLDGVN: Exit: +; OLDGVN-NEXT: ret i64 [[V3]] +; +; NEWGVN-LABEL: @test53( +; NEWGVN-NEXT: Entry: +; NEWGVN-NEXT: br label [[LOOP:%.*]] +; NEWGVN: Loop: +; NEWGVN-NEXT: [[INDEX:%.*]] = phi i64 [ 1, [[ENTRY:%.*]] ], [ [[INDEX_INC:%.*]], [[LOOP_LATCH:%.*]] ] +; NEWGVN-NEXT: [[P1:%.*]] = bitcast i64* [[P:%.*]] to <4 x i64>* +; NEWGVN-NEXT: [[V1:%.*]] = load <4 x i64>, <4 x i64>* [[P1]], align 32 +; NEWGVN-NEXT: br i1 [[COND1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] +; NEWGVN: BB1: +; NEWGVN-NEXT: [[I1:%.*]] = insertelement <4 x i64> [[V1]], i64 [[INDEX]], i32 1 +; NEWGVN-NEXT: store <4 x i64> [[I1]], <4 x i64>* [[P1]], align 32 +; NEWGVN-NEXT: br label [[BB3:%.*]] +; NEWGVN: BB2: +; NEWGVN-NEXT: br label [[BB3]] +; NEWGVN: BB3: +; NEWGVN-NEXT: [[V2:%.*]] = load i64, i64* [[P]], align 4 +; NEWGVN-NEXT: [[V3:%.*]] = add i64 [[V2]], [[INDEX]] +; NEWGVN-NEXT: br label [[LOOP_LATCH]] +; NEWGVN: Loop.Latch: +; NEWGVN-NEXT: [[INDEX_INC]] = add i64 [[INDEX]], 1 +; NEWGVN-NEXT: [[COND2:%.*]] = icmp ne i64 [[INDEX_INC]], [[TC:%.*]] +; NEWGVN-NEXT: br i1 [[COND2]], label [[LOOP]], label [[EXIT:%.*]] +; NEWGVN: Exit: +; NEWGVN-NEXT: ret i64 [[V3]] +; +Entry: + br label %Loop + +Loop: + %Index = phi i64 [ 1, %Entry ], [ %Index.inc, %Loop.Latch ] + %P1 = bitcast i64* %P to <4 x i64>* + %V1 = load <4 x i64>, <4 x i64>* %P1 + br i1 %Cond1, label %BB1, label %BB2 + +BB1: + %I1 = insertelement <4 x i64> %V1, i64 %Index, i32 1 + store <4 x i64> %I1, <4 x i64>* %P1 + br label %BB3 + +BB2: + br label %BB3 + +BB3: + %V2 = load i64, i64* %P + %V3 = add i64 %V2, %Index + br label %Loop.Latch + +Loop.Latch: + %Index.inc = add i64 %Index, 1 + %Cond2 = icmp ne i64 %Index.inc, %TC + br i1 %Cond2, label %Loop, label %Exit + +Exit: + ret i64 %V3 +} + +define i32 @test54(i32* %P, i32 %V1, i1 %Cond1) { +; Entry +; / \ +; BB1 BB2 +; \ / +; BB3 +; / | +; BB4 | +; \ | +; v v +; Exit +; +; OLDGVN-LABEL: @test54( +; OLDGVN-NEXT: Entry: +; OLDGVN-NEXT: store i32 5, i32* [[P:%.*]], align 4 +; OLDGVN-NEXT: br i1 [[COND1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] +; OLDGVN: BB1: +; OLDGVN-NEXT: br label [[BB3:%.*]] +; OLDGVN: BB2: +; OLDGVN-NEXT: store i32 5, i32* [[P]], align 4 +; OLDGVN-NEXT: br label [[BB3]] +; OLDGVN: BB3: +; OLDGVN-NEXT: [[PHI1:%.*]] = phi i32 [ 10, [[BB1]] ], [ 5, [[BB2]] ] +; OLDGVN-NEXT: [[COND2:%.*]] = icmp ne i32 [[V1:%.*]], 0 +; OLDGVN-NEXT: br i1 [[COND2]], label [[BB4:%.*]], label [[EXIT:%.*]] +; OLDGVN: BB4: +; OLDGVN-NEXT: [[V6:%.*]] = add nsw i32 [[PHI1]], 5 +; OLDGVN-NEXT: br label [[EXIT]] +; OLDGVN: Exit: +; OLDGVN-NEXT: [[PHI2:%.*]] = phi i32 [ [[PHI1]], [[BB3]] ], [ [[V6]], [[BB4]] ] +; OLDGVN-NEXT: ret i32 [[PHI2]] +; +; NEWGVN-LABEL: @test54( +; NEWGVN-NEXT: Entry: +; NEWGVN-NEXT: store i32 5, i32* [[P:%.*]], align 4 +; NEWGVN-NEXT: br i1 [[COND1:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] +; NEWGVN: BB1: +; NEWGVN-NEXT: br label [[BB3:%.*]] +; NEWGVN: BB2: +; NEWGVN-NEXT: br label [[BB3]] +; NEWGVN: BB3: +; NEWGVN-NEXT: [[PHI1:%.*]] = phi i32 [ 10, [[BB1]] ], [ 5, [[BB2]] ] +; NEWGVN-NEXT: [[COND2:%.*]] = icmp ne i32 [[V1:%.*]], 0 +; NEWGVN-NEXT: br i1 [[COND2]], label [[BB4:%.*]], label [[EXIT:%.*]] +; NEWGVN: BB4: +; NEWGVN-NEXT: [[V6:%.*]] = add nsw i32 [[PHI1]], 5 +; NEWGVN-NEXT: br label [[EXIT]] +; NEWGVN: Exit: +; NEWGVN-NEXT: [[PHI2:%.*]] = phi i32 [ [[PHI1]], [[BB3]] ], [ [[V6]], [[BB4]] ] +; NEWGVN-NEXT: ret i32 [[PHI2]] +; +Entry: + store i32 5, i32* %P, align 4 + br i1 %Cond1, label %BB1, label %BB2 + +BB1: + %V3 = load i32, i32* %P, align 4 + %V4 = add nsw i32 5, %V3 + br label %BB3 + +BB2: + store i32 5, i32* %P, align 4 + br label %BB3 + +BB3: + %Phi1 = phi i32 [ %V4, %BB1 ], [ 5, %BB2 ] + %Cond2 = icmp ne i32 %V1, 0 + br i1 %Cond2, label %BB4, label %Exit + +BB4: + %V5 = load i32, i32* %P, align 4 + %V6 = add nsw i32 %Phi1, %V5 + br label %Exit + +Exit: + %Phi2 = phi i32 [ %Phi1, %BB3 ], [ %V6, %BB4 ] + ret i32 %Phi2 +} + +define i32 @test55(i32* %P, <2 x i32> %V1, <4 x i32> %V2, i1 %Cond) { +; Entry +; / \ +; T F +; \ / +; vv +; Exit +; +; OLDGVN-LABEL: @test55( +; OLDGVN-NEXT: Entry: +; OLDGVN-NEXT: br i1 [[COND:%.*]], label [[T:%.*]], label [[F:%.*]] +; OLDGVN: T: +; OLDGVN-NEXT: [[P1:%.*]] = bitcast i32* [[P:%.*]] to <2 x i32>* +; OLDGVN-NEXT: store <2 x i32> [[V1:%.*]], <2 x i32>* [[P1]], align 4 +; OLDGVN-NEXT: [[TMP0:%.*]] = bitcast <2 x i32> [[V1]] to i64 +; OLDGVN-NEXT: [[TMP1:%.*]] = trunc i64 [[TMP0]] to i32 +; OLDGVN-NEXT: br label [[EXIT:%.*]] +; OLDGVN: F: +; OLDGVN-NEXT: [[P2:%.*]] = bitcast i32* [[P]] to <4 x i32>* +; OLDGVN-NEXT: store <4 x i32> [[V2:%.*]], <4 x i32>* [[P2]], align 4 +; OLDGVN-NEXT: [[TMP2:%.*]] = bitcast <4 x i32> [[V2]] to i128 +; OLDGVN-NEXT: [[TMP3:%.*]] = trunc i128 [[TMP2]] to i32 +; OLDGVN-NEXT: br label [[EXIT]] +; OLDGVN: Exit: +; OLDGVN-NEXT: [[V5:%.*]] = phi i32 [ [[TMP1]], [[T]] ], [ [[TMP3]], [[F]] ] +; OLDGVN-NEXT: [[V6:%.*]] = add i32 [[V5]], [[V5]] +; OLDGVN-NEXT: ret i32 [[V5]] +; +; NEWGVN-LABEL: @test55( +; NEWGVN-NEXT: Entry: +; NEWGVN-NEXT: br i1 [[COND:%.*]], label [[T:%.*]], label [[F:%.*]] +; NEWGVN: T: +; NEWGVN-NEXT: [[P1:%.*]] = bitcast i32* [[P:%.*]] to <2 x i32>* +; NEWGVN-NEXT: store <2 x i32> [[V1:%.*]], <2 x i32>* [[P1]], align 4 +; NEWGVN-NEXT: [[V3:%.*]] = load i32, i32* [[P]], align 4 +; NEWGVN-NEXT: br label [[EXIT:%.*]] +; NEWGVN: F: +; NEWGVN-NEXT: [[P2:%.*]] = bitcast i32* [[P]] to <4 x i32>* +; NEWGVN-NEXT: store <4 x i32> [[V2:%.*]], <4 x i32>* [[P2]], align 4 +; NEWGVN-NEXT: [[V4:%.*]] = load i32, i32* [[P]], align 4 +; NEWGVN-NEXT: br label [[EXIT]] +; NEWGVN: Exit: +; NEWGVN-NEXT: [[PHI:%.*]] = phi i32 [ [[V3]], [[T]] ], [ [[V4]], [[F]] ] +; NEWGVN-NEXT: [[V5:%.*]] = load i32, i32* [[P]], align 4 +; NEWGVN-NEXT: ret i32 [[V5]] +; +Entry: + br i1 %Cond, label %T, label %F + +T: + %P1 = bitcast i32* %P to <2 x i32>* + store <2 x i32> %V1, <2 x i32>* %P1, align 4 + %V3 = load i32, i32* %P, align 4 + br label %Exit + +F: + %P2 = bitcast i32* %P to <4 x i32>* + store <4 x i32> %V2, <4 x i32>* %P2, align 4 + %V4 = load i32, i32* %P, align 4 + br label %Exit + +Exit: + %Phi = phi i32 [ %V3, %T ], [ %V4, %F ] + %V5 = load i32, i32* %P, align 4 + %V6 = add i32 %Phi, %V5 + ret i32 %V5 +} + +declare void @foo() #0 + +define i32 @test56(i32* %P, i1 %Cond) { +; Entry +; / \ +; T F +; \ / +; vv +; Exit +; +; GVN-LABEL: @test56( +; GVN-NEXT: Entry: +; GVN-NEXT: br i1 [[COND:%.*]], label [[T:%.*]], label [[F:%.*]] +; GVN: T: +; GVN-NEXT: [[P1:%.*]] = bitcast i32* [[P:%.*]] to <2 x i32>* +; GVN-NEXT: [[V1:%.*]] = load <2 x i32>, <2 x i32>* [[P1]], align 8 +; GVN-NEXT: [[V2:%.*]] = extractelement <2 x i32> [[V1]], i64 1 +; GVN-NEXT: br label [[EXIT:%.*]] +; GVN: F: +; GVN-NEXT: br label [[EXIT]] +; GVN: Exit: +; GVN-NEXT: [[PHI:%.*]] = phi i32 [ [[V2]], [[T]] ], [ 100, [[F]] ] +; GVN-NEXT: call void @foo() +; GVN-NEXT: [[V3:%.*]] = load i32, i32* [[P]], align 8 +; GVN-NEXT: [[V4:%.*]] = add i32 [[V3]], [[PHI]] +; GVN-NEXT: ret i32 [[V4]] +; +Entry: + br i1 %Cond, label %T, label %F + +T: + %P1 = bitcast i32* %P to <2 x i32>* + %V1 = load <2 x i32>, <2 x i32>* %P1 + %V2 = extractelement <2 x i32> %V1, i64 1 + br label %Exit + +F: + br label %Exit + +Exit: + %Phi = phi i32 [ %V2, %T ], [ 100, %F ] + call void @foo() + %V3 = load i32, i32* %P, align 8 + %V4 = add i32 %V3, %Phi + ret i32 %V4 +} + +define i32 @test57(i32* %P, i1 %Cond, i32 %V) { +; Entry +; / \ +; T F +; \ / +; vv +; Exit +; +; GVN-LABEL: @test57( +; GVN-NEXT: Entry: +; GVN-NEXT: br i1 [[COND:%.*]], label [[T:%.*]], label [[F:%.*]] +; GVN: T: +; GVN-NEXT: store i32 [[V:%.*]], i32* [[P:%.*]], align 4 +; GVN-NEXT: br label [[EXIT:%.*]] +; GVN: F: +; GVN-NEXT: br label [[EXIT]] +; GVN: Exit: +; GVN-NEXT: call void @foo() +; GVN-NEXT: [[V3:%.*]] = load i32, i32* [[P]], align 8 +; GVN-NEXT: [[V4:%.*]] = add i32 [[V3]], 100 +; GVN-NEXT: ret i32 [[V4]] +; +Entry: + br i1 %Cond, label %T, label %F + +T: + store i32 %V, i32* %P + br label %Exit + +F: + br label %Exit + +Exit: + call void @foo() + %V3 = load i32, i32* %P, align 8 + %V4 = add i32 %V3, 100 + ret i32 %V4 +} + +attributes #0 = { readnone }