diff --git a/llvm/test/Transforms/NewGVN/load_coercion_between_loads.ll b/llvm/test/Transforms/NewGVN/load_coercion_between_loads.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/NewGVN/load_coercion_between_loads.ll @@ -0,0 +1,465 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -S -gvn < %s | FileCheck %s -check-prefixes=OLDGVN +; RUN: opt -S -newgvn < %s | FileCheck %s -check-prefixes=NEWGVN + +define i8 @test1(i32* %P1) { +; OLDGVN-LABEL: @test1( +; OLDGVN-NEXT: [[V1:%.*]] = load i32, i32* [[P1:%.*]], align 4 +; OLDGVN-NEXT: [[P2:%.*]] = bitcast i32* [[P1]] to i8* +; OLDGVN-NEXT: [[TMP1:%.*]] = trunc i32 [[V1]] to i8 +; OLDGVN-NEXT: [[V4:%.*]] = add i8 [[TMP1]], [[TMP1]] +; OLDGVN-NEXT: ret i8 [[V4]] +; +; NEWGVN-LABEL: @test1( +; NEWGVN-NEXT: [[V1:%.*]] = load i32, i32* [[P1:%.*]], align 4 +; NEWGVN-NEXT: [[P2:%.*]] = bitcast i32* [[P1]] to i8* +; NEWGVN-NEXT: [[V2:%.*]] = load i8, i8* [[P2]], align 1 +; NEWGVN-NEXT: [[V3:%.*]] = trunc i32 [[V1]] to i8 +; NEWGVN-NEXT: [[V4:%.*]] = add i8 [[V2]], [[V3]] +; NEWGVN-NEXT: ret i8 [[V4]] +; + %V1 = load i32, i32* %P1 + %P2 = bitcast i32* %P1 to i8* + %V2 = load i8, i8* %P2 + %V3 = trunc i32 %V1 to i8 + %V4 = add i8 %V2, %V3 + ret i8 %V4 +} + +define i32 @test2(i8* %P) { +; OLDGVN-LABEL: @test2( +; OLDGVN-NEXT: entry: +; 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: [[P2:%.*]] = bitcast i8* [[P]] to i32* +; OLDGVN-NEXT: [[TMP0:%.*]] = bitcast <2 x i32> [[V1]] to i64 +; OLDGVN-NEXT: [[TMP1:%.*]] = trunc i64 [[TMP0]] to i32 +; OLDGVN-NEXT: [[V5:%.*]] = add i32 [[TMP1]], [[TMP1]] +; OLDGVN-NEXT: ret i32 [[V5]] +; +; NEWGVN-LABEL: @test2( +; NEWGVN-NEXT: entry: +; 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: [[P2:%.*]] = bitcast i8* [[P]] to i32* +; NEWGVN-NEXT: [[V2:%.*]] = load i32, i32* [[P2]], align 4 +; NEWGVN-NEXT: [[V3:%.*]] = bitcast <2 x i32> [[V1]] to i64 +; NEWGVN-NEXT: [[V4:%.*]] = trunc i64 [[V3]] to i32 +; NEWGVN-NEXT: [[V5:%.*]] = add i32 [[V2]], [[V4]] +; NEWGVN-NEXT: ret i32 [[V5]] +; +entry: + %P1 = bitcast i8* %P to <2 x i32>* + %V1 = load <2 x i32>, <2 x i32>* %P1 + %P2 = bitcast i8* %P to i32* + %V2 = load i32, i32* %P2 + %V3 = bitcast <2 x i32> %V1 to i64 + %V4 = trunc i64 %V3 to i32 + %V5 = add i32 %V2, %V4 + ret i32 %V5 +} + +define <{<2 x i32>, i32}> @test3(i8* %P) { +; OLDGVN-LABEL: @test3( +; OLDGVN-NEXT: entry: +; 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: [[P2:%.*]] = bitcast i8* [[P]] to i32* +; OLDGVN-NEXT: [[TMP0:%.*]] = bitcast <2 x i32> [[V1]] to i64 +; OLDGVN-NEXT: [[TMP1:%.*]] = trunc i64 [[TMP0]] to i32 +; OLDGVN-NEXT: [[I1:%.*]] = insertvalue <{ <2 x i32>, i32 }> undef, <2 x i32> [[V1]], 0 +; OLDGVN-NEXT: [[I2:%.*]] = insertvalue <{ <2 x i32>, i32 }> [[I1]], i32 [[TMP1]], 1 +; OLDGVN-NEXT: ret <{ <2 x i32>, i32 }> [[I2]] +; +; NEWGVN-LABEL: @test3( +; NEWGVN-NEXT: entry: +; 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: [[P2:%.*]] = bitcast i8* [[P]] to i32* +; NEWGVN-NEXT: [[V2:%.*]] = load i32, i32* [[P2]], align 4 +; NEWGVN-NEXT: [[I1:%.*]] = insertvalue <{ <2 x i32>, i32 }> undef, <2 x i32> [[V1]], 0 +; NEWGVN-NEXT: [[I2:%.*]] = insertvalue <{ <2 x i32>, i32 }> [[I1]], i32 [[V2]], 1 +; NEWGVN-NEXT: ret <{ <2 x i32>, i32 }> [[I2]] +; +entry: + %P1 = bitcast i8* %P to <2 x i32>* + %V1 = load <2 x i32>, <2 x i32>* %P1 + %P2 = bitcast i8* %P to i32* + %V2 = load i32, i32* %P2 + %I1 = insertvalue <{<2 x i32>, i32}> undef, <2 x i32> %V1, 0 + %I2 = insertvalue <{<2 x i32>, i32}> %I1, i32 %V2, 1 + ret <{<2 x i32>, i32}> %I2 +} + +define <{<2 x i32>, i32}> @test4(i8* %P) { +; OLDGVN-LABEL: @test4( +; OLDGVN-NEXT: entry: +; OLDGVN-NEXT: [[P2:%.*]] = bitcast i8* [[P:%.*]] to i32* +; OLDGVN-NEXT: [[V2:%.*]] = load i32, i32* [[P2]], align 4 +; 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: [[I1:%.*]] = insertvalue <{ <2 x i32>, i32 }> undef, <2 x i32> [[V1]], 0 +; OLDGVN-NEXT: [[I2:%.*]] = insertvalue <{ <2 x i32>, i32 }> [[I1]], i32 [[V2]], 1 +; OLDGVN-NEXT: ret <{ <2 x i32>, i32 }> [[I2]] +; +; NEWGVN-LABEL: @test4( +; NEWGVN-NEXT: entry: +; NEWGVN-NEXT: [[P2:%.*]] = bitcast i8* [[P:%.*]] to i32* +; NEWGVN-NEXT: [[V2:%.*]] = load i32, i32* [[P2]], align 4 +; 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: [[I1:%.*]] = insertvalue <{ <2 x i32>, i32 }> undef, <2 x i32> [[V1]], 0 +; NEWGVN-NEXT: [[I2:%.*]] = insertvalue <{ <2 x i32>, i32 }> [[I1]], i32 [[V2]], 1 +; NEWGVN-NEXT: ret <{ <2 x i32>, i32 }> [[I2]] +; +entry: + %P2 = bitcast i8* %P to i32* + %V2 = load i32, i32* %P2 + %P1 = bitcast i8* %P to <2 x i32>* + %V1 = load <2 x i32>, <2 x i32>* %P1 + %I1 = insertvalue <{<2 x i32>, i32}> undef, <2 x i32> %V1, 0 + %I2 = insertvalue <{<2 x i32>, i32}> %I1, i32 %V2, 1 + ret <{<2 x i32>, i32}> %I2 +} + +define <{<2 x i32>, i32, i32}> @test5(i8* %P) { +; OLDGVN-LABEL: @test5( +; OLDGVN-NEXT: entry: +; OLDGVN-NEXT: [[P0:%.*]] = bitcast i8* [[P:%.*]] to i32* +; OLDGVN-NEXT: [[V0:%.*]] = load i32, i32* [[P0]], align 4 +; 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: [[TMP0:%.*]] = bitcast <2 x i32> [[V1]] to i64 +; OLDGVN-NEXT: [[TMP1:%.*]] = trunc i64 [[TMP0]] to i32 +; OLDGVN-NEXT: [[I1:%.*]] = insertvalue <{ <2 x i32>, i32, i32 }> undef, <2 x i32> [[V1]], 0 +; OLDGVN-NEXT: [[I2:%.*]] = insertvalue <{ <2 x i32>, i32, i32 }> [[I1]], i32 [[TMP1]], 1 +; OLDGVN-NEXT: [[I3:%.*]] = insertvalue <{ <2 x i32>, i32, i32 }> [[I2]], i32 [[V0]], 2 +; OLDGVN-NEXT: ret <{ <2 x i32>, i32, i32 }> [[I3]] +; +; NEWGVN-LABEL: @test5( +; NEWGVN-NEXT: entry: +; NEWGVN-NEXT: [[P0:%.*]] = bitcast i8* [[P:%.*]] to i32* +; NEWGVN-NEXT: [[V0:%.*]] = load i32, i32* [[P0]], align 4 +; 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: [[I1:%.*]] = insertvalue <{ <2 x i32>, i32, i32 }> undef, <2 x i32> [[V1]], 0 +; NEWGVN-NEXT: [[I2:%.*]] = insertvalue <{ <2 x i32>, i32, i32 }> [[I1]], i32 [[V0]], 1 +; NEWGVN-NEXT: [[I3:%.*]] = insertvalue <{ <2 x i32>, i32, i32 }> [[I2]], i32 [[V0]], 2 +; NEWGVN-NEXT: ret <{ <2 x i32>, i32, i32 }> [[I3]] +; +entry: + %P0 = bitcast i8* %P to i32* + %V0 = load i32, i32* %P0 + %P1 = bitcast i8* %P to <2 x i32>* + %V1 = load <2 x i32>, <2 x i32>* %P1 + %P2 = bitcast i8* %P to i32* + %V2 = load i32, i32* %P2 + %I1 = insertvalue <{<2 x i32>, i32, i32}> undef, <2 x i32> %V1, 0 + %I2 = insertvalue <{<2 x i32>, i32, i32}> %I1, i32 %V2, 1 + %I3 = insertvalue <{<2 x i32>, i32, i32}> %I2, i32 %V0, 2 + ret <{<2 x i32>, i32, i32}> %I3 +} + +define <{<4 x i32>, <2 x i32>, i32, <2 x i32>}> @test6(i8* %P) { +; OLDGVN-LABEL: @test6( +; OLDGVN-NEXT: entry: +; OLDGVN-NEXT: [[P1:%.*]] = bitcast i8* [[P:%.*]] to <4 x i32>* +; OLDGVN-NEXT: [[V1:%.*]] = load <4 x i32>, <4 x i32>* [[P1]], align 16 +; OLDGVN-NEXT: [[P2:%.*]] = bitcast i8* [[P]] to <2 x i32>* +; OLDGVN-NEXT: [[TMP0:%.*]] = bitcast <4 x i32> [[V1]] to i128 +; OLDGVN-NEXT: [[TMP1:%.*]] = trunc i128 [[TMP0]] to i64 +; OLDGVN-NEXT: [[TMP2:%.*]] = bitcast i64 [[TMP1]] to <2 x i32> +; OLDGVN-NEXT: [[P3:%.*]] = bitcast i8* [[P]] to i32* +; OLDGVN-NEXT: [[TMP3:%.*]] = trunc i128 [[TMP0]] to i32 +; OLDGVN-NEXT: [[I1:%.*]] = insertvalue <{ <4 x i32>, <2 x i32>, i32, <2 x i32> }> undef, <4 x i32> [[V1]], 0 +; OLDGVN-NEXT: [[I2:%.*]] = insertvalue <{ <4 x i32>, <2 x i32>, i32, <2 x i32> }> [[I1]], <2 x i32> [[TMP2]], 1 +; OLDGVN-NEXT: [[I3:%.*]] = insertvalue <{ <4 x i32>, <2 x i32>, i32, <2 x i32> }> [[I2]], i32 [[TMP3]], 2 +; OLDGVN-NEXT: [[I4:%.*]] = insertvalue <{ <4 x i32>, <2 x i32>, i32, <2 x i32> }> [[I3]], <2 x i32> [[TMP2]], 3 +; OLDGVN-NEXT: ret <{ <4 x i32>, <2 x i32>, i32, <2 x i32> }> [[I4]] +; +; NEWGVN-LABEL: @test6( +; NEWGVN-NEXT: entry: +; NEWGVN-NEXT: [[P1:%.*]] = bitcast i8* [[P:%.*]] to <4 x i32>* +; NEWGVN-NEXT: [[V1:%.*]] = load <4 x i32>, <4 x i32>* [[P1]], align 16 +; NEWGVN-NEXT: [[P2:%.*]] = bitcast i8* [[P]] to <2 x i32>* +; NEWGVN-NEXT: [[V2:%.*]] = load <2 x i32>, <2 x i32>* [[P2]], align 8 +; NEWGVN-NEXT: [[P3:%.*]] = bitcast i8* [[P]] to i32* +; NEWGVN-NEXT: [[V3:%.*]] = load i32, i32* [[P3]], align 4 +; NEWGVN-NEXT: [[I1:%.*]] = insertvalue <{ <4 x i32>, <2 x i32>, i32, <2 x i32> }> undef, <4 x i32> [[V1]], 0 +; NEWGVN-NEXT: [[I2:%.*]] = insertvalue <{ <4 x i32>, <2 x i32>, i32, <2 x i32> }> [[I1]], <2 x i32> [[V2]], 1 +; NEWGVN-NEXT: [[I3:%.*]] = insertvalue <{ <4 x i32>, <2 x i32>, i32, <2 x i32> }> [[I2]], i32 [[V3]], 2 +; NEWGVN-NEXT: [[I4:%.*]] = insertvalue <{ <4 x i32>, <2 x i32>, i32, <2 x i32> }> [[I3]], <2 x i32> [[V2]], 3 +; NEWGVN-NEXT: ret <{ <4 x i32>, <2 x i32>, i32, <2 x i32> }> [[I4]] +; +entry: + %P1 = bitcast i8* %P to <4 x i32>* + %V1 = load <4 x i32>, <4 x i32>* %P1 + %P2 = bitcast i8* %P to <2 x i32>* + %V2 = load <2 x i32>, <2 x i32>* %P2 + %P3 = bitcast i8* %P to i32* + %V3 = load i32, i32* %P3 + %V4 = load <2 x i32>, <2 x i32>* %P2 + %I1 = insertvalue <{<4 x i32>, <2 x i32>, i32, <2 x i32>}> undef, <4 x i32> %V1, 0 + %I2 = insertvalue <{<4 x i32>,<2 x i32>, i32, <2 x i32>}> %I1, <2 x i32> %V2, 1 + %I3 = insertvalue <{<4 x i32>, <2 x i32>, i32, <2 x i32>}> %I2, i32 %V3, 2 + %I4 = insertvalue <{<4 x i32>, <2 x i32>, i32, <2 x i32>}> %I3, <2 x i32> %V4, 3 + ret <{<4 x i32>, <2 x i32>, i32, <2 x i32>}> %I4 +} + +define float @test7(i32* %P1, i1 %cond) { +; OLDGVN-LABEL: @test7( +; OLDGVN-NEXT: [[V1:%.*]] = load i32, i32* [[P1:%.*]], align 4 +; OLDGVN-NEXT: [[P2:%.*]] = bitcast i32* [[P1]] to float* +; OLDGVN-NEXT: [[TMP1:%.*]] = bitcast i32 [[V1]] to float +; OLDGVN-NEXT: br i1 [[COND:%.*]], label [[T:%.*]], label [[F:%.*]] +; OLDGVN: T: +; OLDGVN-NEXT: ret float [[TMP1]] +; OLDGVN: F: +; OLDGVN-NEXT: ret float [[TMP1]] +; +; NEWGVN-LABEL: @test7( +; NEWGVN-NEXT: [[V1:%.*]] = load i32, i32* [[P1:%.*]], align 4 +; NEWGVN-NEXT: [[P2:%.*]] = bitcast i32* [[P1]] to float* +; NEWGVN-NEXT: [[V2:%.*]] = load float, float* [[P2]], align 4 +; NEWGVN-NEXT: br i1 [[COND:%.*]], label [[T:%.*]], label [[F:%.*]] +; NEWGVN: T: +; NEWGVN-NEXT: ret float [[V2]] +; NEWGVN: F: +; NEWGVN-NEXT: [[V3:%.*]] = bitcast i32 [[V1]] to float +; NEWGVN-NEXT: ret float [[V3]] +; + %V1 = load i32, i32* %P1 + %P2 = bitcast i32* %P1 to float* + %V2 = load float, float* %P2 + br i1 %cond, label %T, label %F +T: + ret float %V2 + +F: + %V3 = bitcast i32 %V1 to float + ret float %V3 +} + +define <{<2 x i32>, i32, i32, i32, i32}> @test8(i8* %P) { +; OLDGVN-LABEL: @test8( +; OLDGVN-NEXT: entry: +; OLDGVN-NEXT: [[P0:%.*]] = bitcast i8* [[P:%.*]] to i32* +; OLDGVN-NEXT: [[V0:%.*]] = load i32, i32* [[P0]], align 4 +; 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: [[TMP0:%.*]] = bitcast <2 x i32> [[V1]] to i64 +; OLDGVN-NEXT: [[TMP1:%.*]] = trunc i64 [[TMP0]] to i32 +; OLDGVN-NEXT: [[I1:%.*]] = insertvalue <{ <2 x i32>, i32, i32, i32, i32 }> undef, <2 x i32> [[V1]], 0 +; OLDGVN-NEXT: [[I2:%.*]] = insertvalue <{ <2 x i32>, i32, i32, i32, i32 }> [[I1]], i32 [[TMP1]], 1 +; OLDGVN-NEXT: [[I3:%.*]] = insertvalue <{ <2 x i32>, i32, i32, i32, i32 }> [[I2]], i32 [[V0]], 2 +; OLDGVN-NEXT: [[I4:%.*]] = insertvalue <{ <2 x i32>, i32, i32, i32, i32 }> [[I3]], i32 [[TMP1]], 3 +; OLDGVN-NEXT: [[I5:%.*]] = insertvalue <{ <2 x i32>, i32, i32, i32, i32 }> [[I4]], i32 [[TMP1]], 4 +; OLDGVN-NEXT: ret <{ <2 x i32>, i32, i32, i32, i32 }> [[I5]] +; +; NEWGVN-LABEL: @test8( +; NEWGVN-NEXT: entry: +; NEWGVN-NEXT: [[P0:%.*]] = bitcast i8* [[P:%.*]] to i32* +; NEWGVN-NEXT: [[V0:%.*]] = load i32, i32* [[P0]], align 4 +; 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: [[I1:%.*]] = insertvalue <{ <2 x i32>, i32, i32, i32, i32 }> undef, <2 x i32> [[V1]], 0 +; NEWGVN-NEXT: [[I2:%.*]] = insertvalue <{ <2 x i32>, i32, i32, i32, i32 }> [[I1]], i32 [[V0]], 1 +; NEWGVN-NEXT: [[I3:%.*]] = insertvalue <{ <2 x i32>, i32, i32, i32, i32 }> [[I2]], i32 [[V0]], 2 +; NEWGVN-NEXT: [[I4:%.*]] = insertvalue <{ <2 x i32>, i32, i32, i32, i32 }> [[I3]], i32 [[V0]], 3 +; NEWGVN-NEXT: [[I5:%.*]] = insertvalue <{ <2 x i32>, i32, i32, i32, i32 }> [[I4]], i32 [[V0]], 4 +; NEWGVN-NEXT: ret <{ <2 x i32>, i32, i32, i32, i32 }> [[I5]] +; +entry: + %P0 = bitcast i8* %P to i32* + %V0 = load i32, i32* %P0 + %P1 = bitcast i8* %P to <2 x i32>* + %V1 = load <2 x i32>, <2 x i32>* %P1 + %P2 = bitcast i8* %P to i32* + %V2 = load i32, i32* %P2 + %I1 = insertvalue <{<2 x i32>, i32, i32, i32, i32}> undef, <2 x i32> %V1, 0 + %I2 = insertvalue <{<2 x i32>, i32, i32, i32, i32}> %I1, i32 %V2, 1 + %I3 = insertvalue <{<2 x i32>, i32, i32, i32, i32}> %I2, i32 %V0, 2 + %P3 = bitcast i8* %P to i32* + %V3 = load i32, i32* %P3 + %I4 = insertvalue <{<2 x i32>, i32, i32, i32, i32}> %I3, i32 %V3, 3 + %P4 = bitcast i8* %P to i32* + %V4 = load i32, i32* %P4 + %I5 = insertvalue <{<2 x i32>, i32, i32, i32, i32}> %I4, i32 %V4, 4 + ret <{<2 x i32>, i32, i32, i32, i32}> %I5 +} + +define <{<4 x i32>, <2 x i32>, i32, <2 x i32>}> @test9(i8* %P) { +; OLDGVN-LABEL: @test9( +; OLDGVN-NEXT: entry: +; OLDGVN-NEXT: [[P1:%.*]] = bitcast i8* [[P:%.*]] to <4 x i32>* +; OLDGVN-NEXT: [[V1:%.*]] = load <4 x i32>, <4 x i32>* [[P1]], align 16 +; OLDGVN-NEXT: [[P2:%.*]] = bitcast i8* [[P]] to <2 x i32>* +; OLDGVN-NEXT: [[TMP0:%.*]] = bitcast <4 x i32> [[V1]] to i128 +; OLDGVN-NEXT: [[TMP1:%.*]] = trunc i128 [[TMP0]] to i64 +; OLDGVN-NEXT: [[TMP2:%.*]] = bitcast i64 [[TMP1]] to <2 x i32> +; OLDGVN-NEXT: [[P3:%.*]] = bitcast i8* [[P]] to i32* +; OLDGVN-NEXT: [[TMP3:%.*]] = trunc i128 [[TMP0]] to i32 +; OLDGVN-NEXT: [[I1:%.*]] = insertvalue <{ <4 x i32>, <2 x i32>, i32, <2 x i32> }> undef, <4 x i32> [[V1]], 0 +; OLDGVN-NEXT: [[I2:%.*]] = insertvalue <{ <4 x i32>, <2 x i32>, i32, <2 x i32> }> [[I1]], <2 x i32> [[TMP2]], 1 +; OLDGVN-NEXT: [[I3:%.*]] = insertvalue <{ <4 x i32>, <2 x i32>, i32, <2 x i32> }> [[I2]], i32 [[TMP3]], 2 +; OLDGVN-NEXT: [[I4:%.*]] = insertvalue <{ <4 x i32>, <2 x i32>, i32, <2 x i32> }> [[I3]], <2 x i32> [[TMP2]], 3 +; OLDGVN-NEXT: ret <{ <4 x i32>, <2 x i32>, i32, <2 x i32> }> [[I4]] +; +; NEWGVN-LABEL: @test9( +; NEWGVN-NEXT: entry: +; NEWGVN-NEXT: [[P1:%.*]] = bitcast i8* [[P:%.*]] to <4 x i32>* +; NEWGVN-NEXT: [[V1:%.*]] = load <4 x i32>, <4 x i32>* [[P1]], align 16 +; NEWGVN-NEXT: [[P2:%.*]] = bitcast i8* [[P]] to <2 x i32>* +; NEWGVN-NEXT: [[V2:%.*]] = load <2 x i32>, <2 x i32>* [[P2]], align 8 +; NEWGVN-NEXT: [[P3:%.*]] = bitcast i8* [[P]] to i32* +; NEWGVN-NEXT: [[V3:%.*]] = load i32, i32* [[P3]], align 4 +; NEWGVN-NEXT: [[I1:%.*]] = insertvalue <{ <4 x i32>, <2 x i32>, i32, <2 x i32> }> undef, <4 x i32> [[V1]], 0 +; NEWGVN-NEXT: [[I2:%.*]] = insertvalue <{ <4 x i32>, <2 x i32>, i32, <2 x i32> }> [[I1]], <2 x i32> [[V2]], 1 +; NEWGVN-NEXT: [[I3:%.*]] = insertvalue <{ <4 x i32>, <2 x i32>, i32, <2 x i32> }> [[I2]], i32 [[V3]], 2 +; NEWGVN-NEXT: [[I4:%.*]] = insertvalue <{ <4 x i32>, <2 x i32>, i32, <2 x i32> }> [[I3]], <2 x i32> [[V2]], 3 +; NEWGVN-NEXT: ret <{ <4 x i32>, <2 x i32>, i32, <2 x i32> }> [[I4]] +; +entry: + %P1 = bitcast i8* %P to <4 x i32>* + %V1 = load <4 x i32>, <4 x i32>* %P1 + %P2 = bitcast i8* %P to <2 x i32>* + %V2 = load <2 x i32>, <2 x i32>* %P2 + %P3 = bitcast i8* %P to i32* + %V3 = load i32, i32* %P3 + %V4 = load <2 x i32>, <2 x i32>* %P2 + %I1 = insertvalue <{<4 x i32>, <2 x i32>, i32, <2 x i32>}> undef, <4 x i32> %V1, 0 + %I2 = insertvalue <{<4 x i32>,<2 x i32>, i32, <2 x i32>}> %I1, <2 x i32> %V2, 1 + %I3 = insertvalue <{<4 x i32>, <2 x i32>, i32, <2 x i32>}> %I2, i32 %V3, 2 + %I4 = insertvalue <{<4 x i32>, <2 x i32>, i32, <2 x i32>}> %I3, <2 x i32> %V4, 3 + ret <{<4 x i32>, <2 x i32>, i32, <2 x i32>}> %I4 +} + +define <{<4 x i32>, <2 x i32>, i32}> @test10(i8* %P, i1 %cond) { +; OLDGVN-LABEL: @test10( +; OLDGVN-NEXT: entry: +; OLDGVN-NEXT: [[P1:%.*]] = bitcast i8* [[P:%.*]] to <4 x i32>* +; OLDGVN-NEXT: [[V1:%.*]] = load <4 x i32>, <4 x i32>* [[P1]], align 16 +; OLDGVN-NEXT: [[I1:%.*]] = insertvalue <{ <4 x i32>, <2 x i32>, i32 }> undef, <4 x i32> [[V1]], 0 +; OLDGVN-NEXT: [[TMP0:%.*]] = bitcast <4 x i32> [[V1]] to i128 +; OLDGVN-NEXT: [[TMP1:%.*]] = trunc i128 [[TMP0]] to i32 +; OLDGVN-NEXT: [[TMP2:%.*]] = trunc i128 [[TMP0]] to i64 +; OLDGVN-NEXT: [[TMP3:%.*]] = bitcast i64 [[TMP2]] to <2 x i32> +; OLDGVN-NEXT: br i1 [[COND:%.*]], label [[T:%.*]], label [[F:%.*]] +; OLDGVN: T: +; OLDGVN-NEXT: [[P2:%.*]] = bitcast i8* [[P]] to <2 x i32>* +; OLDGVN-NEXT: [[I2:%.*]] = insertvalue <{ <4 x i32>, <2 x i32>, i32 }> [[I1]], <2 x i32> [[TMP3]], 1 +; OLDGVN-NEXT: ret <{ <4 x i32>, <2 x i32>, i32 }> [[I2]] +; OLDGVN: F: +; OLDGVN-NEXT: [[P3:%.*]] = bitcast i8* [[P]] to i32* +; OLDGVN-NEXT: [[I3:%.*]] = insertvalue <{ <4 x i32>, <2 x i32>, i32 }> [[I1]], i32 [[TMP1]], 2 +; OLDGVN-NEXT: ret <{ <4 x i32>, <2 x i32>, i32 }> [[I3]] +; +; NEWGVN-LABEL: @test10( +; NEWGVN-NEXT: entry: +; NEWGVN-NEXT: [[P1:%.*]] = bitcast i8* [[P:%.*]] to <4 x i32>* +; NEWGVN-NEXT: [[V1:%.*]] = load <4 x i32>, <4 x i32>* [[P1]], align 16 +; NEWGVN-NEXT: [[I1:%.*]] = insertvalue <{ <4 x i32>, <2 x i32>, i32 }> undef, <4 x i32> [[V1]], 0 +; NEWGVN-NEXT: br i1 [[COND:%.*]], label [[T:%.*]], label [[F:%.*]] +; NEWGVN: T: +; NEWGVN-NEXT: [[P2:%.*]] = bitcast i8* [[P]] to <2 x i32>* +; NEWGVN-NEXT: [[V2:%.*]] = load <2 x i32>, <2 x i32>* [[P2]], align 8 +; NEWGVN-NEXT: [[I2:%.*]] = insertvalue <{ <4 x i32>, <2 x i32>, i32 }> [[I1]], <2 x i32> [[V2]], 1 +; NEWGVN-NEXT: ret <{ <4 x i32>, <2 x i32>, i32 }> [[I2]] +; NEWGVN: F: +; NEWGVN-NEXT: [[P3:%.*]] = bitcast i8* [[P]] to i32* +; NEWGVN-NEXT: [[V3:%.*]] = load i32, i32* [[P3]], align 4 +; NEWGVN-NEXT: [[I3:%.*]] = insertvalue <{ <4 x i32>, <2 x i32>, i32 }> [[I1]], i32 [[V3]], 2 +; NEWGVN-NEXT: ret <{ <4 x i32>, <2 x i32>, i32 }> [[I3]] +; +entry: + %P1 = bitcast i8* %P to <4 x i32>* + %V1 = load <4 x i32>, <4 x i32>* %P1 + %I1 = insertvalue <{<4 x i32>, <2 x i32>, i32}> undef, <4 x i32> %V1, 0 + br i1 %cond, label %T, label %F +T: + %P2 = bitcast i8* %P to <2 x i32>* + %V2 = load <2 x i32>, <2 x i32>* %P2 + %I2 = insertvalue <{<4 x i32>,<2 x i32>, i32}> %I1, <2 x i32> %V2, 1 + ret <{<4 x i32>, <2 x i32>, i32}> %I2 + +F: + %P3 = bitcast i8* %P to i32* + %V3 = load i32, i32* %P3 + %I3 = insertvalue <{<4 x i32>, <2 x i32>, i32}> %I1, i32 %V3, 2 + ret <{<4 x i32>, <2 x i32>, i32}> %I3 +} + +define <{<2 x i32>, i32, float}> @test11(i8* %P) { +; OLDGVN-LABEL: @test11( +; OLDGVN-NEXT: entry: +; 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: [[P2:%.*]] = bitcast i8* [[P]] to i32* +; OLDGVN-NEXT: [[TMP0:%.*]] = bitcast <2 x i32> [[V1]] to i64 +; OLDGVN-NEXT: [[TMP1:%.*]] = trunc i64 [[TMP0]] to i32 +; OLDGVN-NEXT: [[P3:%.*]] = bitcast i8* [[P]] to float* +; OLDGVN-NEXT: [[TMP2:%.*]] = bitcast i32 [[TMP1]] to float +; OLDGVN-NEXT: [[I1:%.*]] = insertvalue <{ <2 x i32>, i32, float }> undef, <2 x i32> [[V1]], 0 +; OLDGVN-NEXT: [[I2:%.*]] = insertvalue <{ <2 x i32>, i32, float }> [[I1]], i32 [[TMP1]], 1 +; OLDGVN-NEXT: [[I3:%.*]] = insertvalue <{ <2 x i32>, i32, float }> [[I2]], float [[TMP2]], 2 +; OLDGVN-NEXT: ret <{ <2 x i32>, i32, float }> [[I3]] +; +; NEWGVN-LABEL: @test11( +; NEWGVN-NEXT: entry: +; 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: [[P2:%.*]] = bitcast i8* [[P]] to i32* +; NEWGVN-NEXT: [[V2:%.*]] = load i32, i32* [[P2]], align 4 +; NEWGVN-NEXT: [[P3:%.*]] = bitcast i8* [[P]] to float* +; NEWGVN-NEXT: [[V3:%.*]] = load float, float* [[P3]], align 4 +; NEWGVN-NEXT: [[I1:%.*]] = insertvalue <{ <2 x i32>, i32, float }> undef, <2 x i32> [[V1]], 0 +; NEWGVN-NEXT: [[I2:%.*]] = insertvalue <{ <2 x i32>, i32, float }> [[I1]], i32 [[V2]], 1 +; NEWGVN-NEXT: [[I3:%.*]] = insertvalue <{ <2 x i32>, i32, float }> [[I2]], float [[V3]], 2 +; NEWGVN-NEXT: ret <{ <2 x i32>, i32, float }> [[I3]] +; +entry: + %P1 = bitcast i8* %P to <2 x i32>* + %V1 = load <2 x i32>, <2 x i32>* %P1 + %P2 = bitcast i8* %P to i32* + %V2 = load i32, i32* %P2 + %P3 = bitcast i8* %P to float* + %V3 = load float, float* %P3 + %I1 = insertvalue <{<2 x i32>, i32, float}> undef, <2 x i32> %V1, 0 + %I2 = insertvalue <{<2 x i32>, i32, float}> %I1, i32 %V2, 1 + %I3 = insertvalue <{<2 x i32>, i32, float}> %I2, float %V3, 2 + ret <{<2 x i32>, i32, float}> %I3 +} + +define i8 @test12(i32* %P1, i32 %V) { +; OLDGVN-LABEL: @test12( +; OLDGVN-NEXT: [[V1:%.*]] = load i32, i32* [[P1:%.*]], align 4 +; OLDGVN-NEXT: [[P2:%.*]] = bitcast i32* [[P1]] to i8* +; OLDGVN-NEXT: [[TMP1:%.*]] = trunc i32 [[V1]] to i8 +; OLDGVN-NEXT: store i32 [[V:%.*]], i32* [[P1]], align 4 +; OLDGVN-NEXT: [[TMP2:%.*]] = trunc i32 [[V]] to i8 +; OLDGVN-NEXT: [[V5:%.*]] = add i8 [[TMP1]], [[TMP1]] +; OLDGVN-NEXT: [[V6:%.*]] = add i8 [[TMP2]], [[V5]] +; OLDGVN-NEXT: ret i8 [[V6]] +; +; NEWGVN-LABEL: @test12( +; NEWGVN-NEXT: [[V1:%.*]] = load i32, i32* [[P1:%.*]], align 4 +; NEWGVN-NEXT: [[P2:%.*]] = bitcast i32* [[P1]] to i8* +; NEWGVN-NEXT: [[V2:%.*]] = load i8, i8* [[P2]], align 1 +; NEWGVN-NEXT: [[V3:%.*]] = trunc i32 [[V1]] to i8 +; NEWGVN-NEXT: store i32 [[V:%.*]], i32* [[P1]], align 4 +; NEWGVN-NEXT: [[TMP1:%.*]] = trunc i32 [[V]] to i8 +; NEWGVN-NEXT: [[V5:%.*]] = add i8 [[V2]], [[V3]] +; NEWGVN-NEXT: [[V6:%.*]] = add i8 [[TMP1]], [[V5]] +; NEWGVN-NEXT: ret i8 [[V6]] +; + %V1 = load i32, i32* %P1 + %P2 = bitcast i32* %P1 to i8* + %V2 = load i8, i8* %P2 + %V3 = trunc i32 %V1 to i8 + store i32 %V, i32* %P1 + %P4 = bitcast i32* %P1 to i8* + %V4 = load i8, i8* %P4 + %V5 = add i8 %V2, %V3 + %V6 = add i8 %V4, %V5 + ret i8 %V6 +}