brintos

brintos / llvm-project-archived public Read only

0
0
Text · 28.2 KiB · de64bf2 Raw
540 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -O3 -S -mtriple=x86_64-- -mcpu=x86-64    | FileCheck %s --check-prefixes=CHECK,SSE,SSE23; RUN: opt < %s -O3 -S -mtriple=x86_64-- -mcpu=x86-64-v2 | FileCheck %s --check-prefixes=CHECK,SSE,SSE44; RUN: opt < %s -O3 -S -mtriple=x86_64-- -mcpu=x86-64-v3 | FileCheck %s --check-prefixes=CHECK,AVX5; RUN: opt < %s -O3 -S -mtriple=x86_64-- -mcpu=x86-64-v4 | FileCheck %s --check-prefixes=CHECK,AVX6; RUN: opt < %s -passes="default<O3>" -S -mtriple=x86_64-- -mcpu=x86-64    | FileCheck %s --check-prefixes=CHECK,SSE,SSE27; RUN: opt < %s -passes="default<O3>" -S -mtriple=x86_64-- -mcpu=x86-64-v2 | FileCheck %s --check-prefixes=CHECK,SSE,SSE48; RUN: opt < %s -passes="default<O3>" -S -mtriple=x86_64-- -mcpu=x86-64-v3 | FileCheck %s --check-prefixes=CHECK,AVX9; RUN: opt < %s -passes="default<O3>" -S -mtriple=x86_64-- -mcpu=x86-64-v4 | FileCheck %s --check-prefixes=CHECK,AVX10 11; Ideally, this should reach the backend with 1 fsub, 1 fadd, and 1 shuffle.12; That may require some coordination between VectorCombine, SLP, and other passes.13; The end goal is to get a single "vaddsubps" instruction for x86 with AVX.14 15define <2 x double> @test_addsub_v2f64(<2 x double> %A, <2 x double> %B) {16; CHECK-LABEL: @test_addsub_v2f64(17; CHECK-NEXT:    [[TMP1:%.*]] = fsub <2 x double> [[A:%.*]], [[B:%.*]]18; CHECK-NEXT:    [[TMP2:%.*]] = fadd <2 x double> [[A]], [[B]]19; CHECK-NEXT:    [[TMP3:%.*]] = shufflevector <2 x double> [[TMP1]], <2 x double> [[TMP2]], <2 x i32> <i32 0, i32 3>20; CHECK-NEXT:    ret <2 x double> [[TMP3]]21;22  %1 = extractelement <2 x double> %A, i32 023  %2 = extractelement <2 x double> %B, i32 024  %sub = fsub double %1, %225  %3 = extractelement <2 x double> %A, i32 126  %4 = extractelement <2 x double> %B, i32 127  %add = fadd double %3, %428  %vecinsert1 = insertelement <2 x double> undef, double %sub, i32 029  %vecinsert2 = insertelement <2 x double> %vecinsert1, double %add, i32 130  ret <2 x double> %vecinsert231}32 33define <4 x double> @test_addsub_v4f64(<4 x double> %A, <4 x double> %B) {34; CHECK-LABEL: @test_addsub_v4f64(35; CHECK-NEXT:    [[TMP1:%.*]] = fsub <4 x double> [[A:%.*]], [[B:%.*]]36; CHECK-NEXT:    [[TMP2:%.*]] = fadd <4 x double> [[A]], [[B]]37; CHECK-NEXT:    [[TMP3:%.*]] = shufflevector <4 x double> [[TMP1]], <4 x double> [[TMP2]], <4 x i32> <i32 0, i32 5, i32 2, i32 7>38; CHECK-NEXT:    ret <4 x double> [[TMP3]]39;40  %1 = extractelement <4 x double> %A, i32 041  %2 = extractelement <4 x double> %B, i32 042  %sub = fsub double %1, %243  %3 = extractelement <4 x double> %A, i32 244  %4 = extractelement <4 x double> %B, i32 245  %sub2 = fsub double %3, %446  %5 = extractelement <4 x double> %A, i32 147  %6 = extractelement <4 x double> %B, i32 148  %add = fadd double %5, %649  %7 = extractelement <4 x double> %A, i32 350  %8 = extractelement <4 x double> %B, i32 351  %add2 = fadd double %7, %852  %vecinsert1 = insertelement <4 x double> undef, double %add, i32 153  %vecinsert2 = insertelement <4 x double> %vecinsert1, double %add2, i32 354  %vecinsert3 = insertelement <4 x double> %vecinsert2, double %sub, i32 055  %vecinsert4 = insertelement <4 x double> %vecinsert3, double %sub2, i32 256  ret <4 x double> %vecinsert457}58 59define <8 x double> @test_addsub_v8f64(<8 x double> %A, <8 x double> %B) {60; SSE2-LABEL: @test_addsub_v8f64(61; SSE2-NEXT:    [[TMP1:%.*]] = fsub <8 x double> [[A:%.*]], [[B:%.*]]62; SSE2-NEXT:    [[TMP2:%.*]] = shufflevector <8 x double> [[TMP1]], <8 x double> poison, <4 x i32> <i32 0, i32 2, i32 4, i32 6>63; SSE2-NEXT:    [[TMP3:%.*]] = fadd <8 x double> [[A]], [[B]]64; SSE2-NEXT:    [[TMP4:%.*]] = shufflevector <8 x double> [[TMP3]], <8 x double> poison, <4 x i32> <i32 1, i32 3, i32 5, i32 7>65; SSE2-NEXT:    [[TMP5:%.*]] = shufflevector <4 x double> [[TMP2]], <4 x double> [[TMP4]], <8 x i32> <i32 0, i32 4, i32 1, i32 5, i32 2, i32 6, i32 3, i32 7>66; SSE2-NEXT:    ret <8 x double> [[TMP5]]67;68; SSE4-LABEL: @test_addsub_v8f64(69; SSE4-NEXT:    [[TMP1:%.*]] = fsub <8 x double> [[A:%.*]], [[B:%.*]]70; SSE4-NEXT:    [[TMP2:%.*]] = fadd <8 x double> [[A]], [[B]]71; SSE4-NEXT:    [[TMP3:%.*]] = shufflevector <8 x double> [[TMP1]], <8 x double> [[TMP2]], <8 x i32> <i32 0, i32 9, i32 2, i32 11, i32 4, i32 13, i32 6, i32 15>72; SSE4-NEXT:    ret <8 x double> [[TMP3]]73;74; AVX-LABEL: @test_addsub_v8f64(75; AVX-NEXT:    [[TMP1:%.*]] = fsub <8 x double> [[A:%.*]], [[B:%.*]]76; AVX-NEXT:    [[TMP2:%.*]] = fadd <8 x double> [[A]], [[B]]77; AVX-NEXT:    [[TMP3:%.*]] = shufflevector <8 x double> [[TMP1]], <8 x double> [[TMP2]], <8 x i32> <i32 0, i32 9, i32 2, i32 11, i32 4, i32 13, i32 6, i32 15>78; AVX-NEXT:    ret <8 x double> [[TMP3]]79;80  %1 = extractelement <8 x double> %A, i32 081  %2 = extractelement <8 x double> %B, i32 082  %sub = fsub double %1, %283  %3 = extractelement <8 x double> %A, i32 284  %4 = extractelement <8 x double> %B, i32 285  %sub2 = fsub double %3, %486  %5 = extractelement <8 x double> %A, i32 187  %6 = extractelement <8 x double> %B, i32 188  %add = fadd double %5, %689  %7 = extractelement <8 x double> %A, i32 390  %8 = extractelement <8 x double> %B, i32 391  %add2 = fadd double %7, %892  %9 = extractelement <8 x double> %A, i32 493  %10 = extractelement <8 x double> %B, i32 494  %sub3 = fsub double %9, %1095  %11 = extractelement <8 x double> %A, i32 696  %12 = extractelement <8 x double> %B, i32 697  %sub4 = fsub double %11, %1298  %13 = extractelement <8 x double> %A, i32 599  %14 = extractelement <8 x double> %B, i32 5100  %add3 = fadd double %13, %14101  %15 = extractelement <8 x double> %A, i32 7102  %16 = extractelement <8 x double> %B, i32 7103  %add4 = fadd double %15, %16104  %vecinsert1 = insertelement <8 x double> undef, double %add, i32 1105  %vecinsert2 = insertelement <8 x double> %vecinsert1, double %add2, i32 3106  %vecinsert3 = insertelement <8 x double> %vecinsert2, double %sub, i32 0107  %vecinsert4 = insertelement <8 x double> %vecinsert3, double %sub2, i32 2108  %vecinsert5 = insertelement <8 x double> %vecinsert4, double %add3, i32 5109  %vecinsert6 = insertelement <8 x double> %vecinsert5, double %add4, i32 7110  %vecinsert7 = insertelement <8 x double> %vecinsert6, double %sub3, i32 4111  %vecinsert8 = insertelement <8 x double> %vecinsert7, double %sub4, i32 6112  ret <8 x double> %vecinsert8113}114 115define <2 x float> @test_addsub_v2f32(<2 x float> %v0, <2 x float> %v1) {116; CHECK-LABEL: @test_addsub_v2f32(117; CHECK-NEXT:    [[TMP1:%.*]] = fsub <2 x float> [[V0:%.*]], [[V1:%.*]]118; CHECK-NEXT:    [[TMP2:%.*]] = fadd <2 x float> [[V0]], [[V1]]119; CHECK-NEXT:    [[TMP3:%.*]] = shufflevector <2 x float> [[TMP1]], <2 x float> [[TMP2]], <2 x i32> <i32 0, i32 3>120; CHECK-NEXT:    ret <2 x float> [[TMP3]]121;122  %v2 = extractelement <2 x float> %v0, i32 0123  %v3 = extractelement <2 x float> %v1, i32 0124  %v4 = extractelement <2 x float> %v0, i32 1125  %v5 = extractelement <2 x float> %v1, i32 1126  %sub = fsub float %v2, %v3127  %add = fadd float %v5, %v4128  %res0 = insertelement <2 x float> undef, float %sub, i32 0129  %res1 = insertelement <2 x float> %res0, float %add, i32 1130  ret <2 x float> %res1131}132 133define <4 x float> @test_addsub_v4f32(<4 x float> %A, <4 x float> %B) {134; CHECK-LABEL: @test_addsub_v4f32(135; CHECK-NEXT:    [[TMP1:%.*]] = fsub <4 x float> [[A:%.*]], [[B:%.*]]136; CHECK-NEXT:    [[TMP2:%.*]] = fadd <4 x float> [[A]], [[B]]137; CHECK-NEXT:    [[TMP3:%.*]] = shufflevector <4 x float> [[TMP1]], <4 x float> [[TMP2]], <4 x i32> <i32 0, i32 5, i32 2, i32 7>138; CHECK-NEXT:    ret <4 x float> [[TMP3]]139;140  %1 = extractelement <4 x float> %A, i32 0141  %2 = extractelement <4 x float> %B, i32 0142  %sub = fsub float %1, %2143  %3 = extractelement <4 x float> %A, i32 2144  %4 = extractelement <4 x float> %B, i32 2145  %sub2 = fsub float %3, %4146  %5 = extractelement <4 x float> %A, i32 1147  %6 = extractelement <4 x float> %B, i32 1148  %add = fadd float %5, %6149  %7 = extractelement <4 x float> %A, i32 3150  %8 = extractelement <4 x float> %B, i32 3151  %add2 = fadd float %7, %8152  %vecinsert1 = insertelement <4 x float> undef, float %add, i32 1153  %vecinsert2 = insertelement <4 x float> %vecinsert1, float %add2, i32 3154  %vecinsert3 = insertelement <4 x float> %vecinsert2, float %sub, i32 0155  %vecinsert4 = insertelement <4 x float> %vecinsert3, float %sub2, i32 2156  ret <4 x float> %vecinsert4157}158 159define <8 x float> @test_v8f32(<8 x float> %A, <8 x float> %B) {160; SSE2-LABEL: @test_v8f32(161; SSE2-NEXT:    [[TMP1:%.*]] = fsub <8 x float> [[A:%.*]], [[B:%.*]]162; SSE2-NEXT:    [[TMP2:%.*]] = shufflevector <8 x float> [[TMP1]], <8 x float> poison, <4 x i32> <i32 0, i32 2, i32 4, i32 6>163; SSE2-NEXT:    [[TMP3:%.*]] = fadd <8 x float> [[A]], [[B]]164; SSE2-NEXT:    [[TMP4:%.*]] = shufflevector <8 x float> [[TMP3]], <8 x float> poison, <4 x i32> <i32 1, i32 3, i32 5, i32 7>165; SSE2-NEXT:    [[TMP5:%.*]] = shufflevector <4 x float> [[TMP2]], <4 x float> [[TMP4]], <8 x i32> <i32 0, i32 4, i32 1, i32 5, i32 2, i32 6, i32 3, i32 7>166; SSE2-NEXT:    ret <8 x float> [[TMP5]]167;168; SSE4-LABEL: @test_v8f32(169; SSE4-NEXT:    [[TMP1:%.*]] = fsub <8 x float> [[A:%.*]], [[B:%.*]]170; SSE4-NEXT:    [[TMP2:%.*]] = fadd <8 x float> [[A]], [[B]]171; SSE4-NEXT:    [[TMP3:%.*]] = shufflevector <8 x float> [[TMP1]], <8 x float> [[TMP2]], <8 x i32> <i32 0, i32 9, i32 2, i32 11, i32 4, i32 13, i32 6, i32 15>172; SSE4-NEXT:    ret <8 x float> [[TMP3]]173;174; AVX-LABEL: @test_v8f32(175; AVX-NEXT:    [[TMP1:%.*]] = fsub <8 x float> [[A:%.*]], [[B:%.*]]176; AVX-NEXT:    [[TMP2:%.*]] = fadd <8 x float> [[A]], [[B]]177; AVX-NEXT:    [[TMP3:%.*]] = shufflevector <8 x float> [[TMP1]], <8 x float> [[TMP2]], <8 x i32> <i32 0, i32 9, i32 2, i32 11, i32 4, i32 13, i32 6, i32 15>178; AVX-NEXT:    ret <8 x float> [[TMP3]]179;180  %1 = extractelement <8 x float> %A, i32 0181  %2 = extractelement <8 x float> %B, i32 0182  %sub = fsub float %1, %2183  %3 = extractelement <8 x float> %A, i32 2184  %4 = extractelement <8 x float> %B, i32 2185  %sub2 = fsub float %3, %4186  %5 = extractelement <8 x float> %A, i32 1187  %6 = extractelement <8 x float> %B, i32 1188  %add = fadd float %5, %6189  %7 = extractelement <8 x float> %A, i32 3190  %8 = extractelement <8 x float> %B, i32 3191  %add2 = fadd float %7, %8192  %9 = extractelement <8 x float> %A, i32 4193  %10 = extractelement <8 x float> %B, i32 4194  %sub3 = fsub float %9, %10195  %11 = extractelement <8 x float> %A, i32 6196  %12 = extractelement <8 x float> %B, i32 6197  %sub4 = fsub float %11, %12198  %13 = extractelement <8 x float> %A, i32 5199  %14 = extractelement <8 x float> %B, i32 5200  %add3 = fadd float %13, %14201  %15 = extractelement <8 x float> %A, i32 7202  %16 = extractelement <8 x float> %B, i32 7203  %add4 = fadd float %15, %16204  %vecinsert1 = insertelement <8 x float> undef, float %add, i32 1205  %vecinsert2 = insertelement <8 x float> %vecinsert1, float %add2, i32 3206  %vecinsert3 = insertelement <8 x float> %vecinsert2, float %sub, i32 0207  %vecinsert4 = insertelement <8 x float> %vecinsert3, float %sub2, i32 2208  %vecinsert5 = insertelement <8 x float> %vecinsert4, float %add3, i32 5209  %vecinsert6 = insertelement <8 x float> %vecinsert5, float %add4, i32 7210  %vecinsert7 = insertelement <8 x float> %vecinsert6, float %sub3, i32 4211  %vecinsert8 = insertelement <8 x float> %vecinsert7, float %sub4, i32 6212  ret <8 x float> %vecinsert8213}214 215define <16 x float> @test_addsub_v16f32(<16 x float> %A, <16 x float> %B) {216; SSE2-LABEL: @test_addsub_v16f32(217; SSE2-NEXT:    [[TMP1:%.*]] = fsub <16 x float> [[A:%.*]], [[B:%.*]]218; SSE2-NEXT:    [[TMP2:%.*]] = shufflevector <16 x float> [[TMP1]], <16 x float> poison, <8 x i32> <i32 0, i32 2, i32 4, i32 6, i32 8, i32 10, i32 12, i32 14>219; SSE2-NEXT:    [[TMP3:%.*]] = fadd <16 x float> [[A]], [[B]]220; SSE2-NEXT:    [[TMP4:%.*]] = shufflevector <16 x float> [[TMP3]], <16 x float> poison, <8 x i32> <i32 1, i32 3, i32 5, i32 7, i32 9, i32 11, i32 13, i32 15>221; SSE2-NEXT:    [[TMP5:%.*]] = shufflevector <8 x float> [[TMP2]], <8 x float> [[TMP4]], <16 x i32> <i32 0, i32 8, i32 1, i32 9, i32 2, i32 10, i32 3, i32 11, i32 4, i32 12, i32 5, i32 13, i32 6, i32 14, i32 7, i32 15>222; SSE2-NEXT:    ret <16 x float> [[TMP5]]223;224; SSE4-LABEL: @test_addsub_v16f32(225; SSE4-NEXT:    [[TMP1:%.*]] = fsub <16 x float> [[A:%.*]], [[B:%.*]]226; SSE4-NEXT:    [[TMP2:%.*]] = fadd <16 x float> [[A]], [[B]]227; SSE4-NEXT:    [[TMP3:%.*]] = shufflevector <16 x float> [[TMP1]], <16 x float> [[TMP2]], <16 x i32> <i32 0, i32 17, i32 2, i32 19, i32 4, i32 21, i32 6, i32 23, i32 8, i32 25, i32 10, i32 27, i32 12, i32 29, i32 14, i32 31>228; SSE4-NEXT:    ret <16 x float> [[TMP3]]229;230; AVX-LABEL: @test_addsub_v16f32(231; AVX-NEXT:    [[TMP1:%.*]] = fsub <16 x float> [[A:%.*]], [[B:%.*]]232; AVX-NEXT:    [[TMP2:%.*]] = fadd <16 x float> [[A]], [[B]]233; AVX-NEXT:    [[TMP3:%.*]] = shufflevector <16 x float> [[TMP1]], <16 x float> [[TMP2]], <16 x i32> <i32 0, i32 17, i32 2, i32 19, i32 4, i32 21, i32 6, i32 23, i32 8, i32 25, i32 10, i32 27, i32 12, i32 29, i32 14, i32 31>234; AVX-NEXT:    ret <16 x float> [[TMP3]]235;236  %1 = extractelement <16 x float> %A, i32 0237  %2 = extractelement <16 x float> %B, i32 0238  %sub = fsub float %1, %2239  %3 = extractelement <16 x float> %A, i32 2240  %4 = extractelement <16 x float> %B, i32 2241  %sub2 = fsub float %3, %4242  %5 = extractelement <16 x float> %A, i32 1243  %6 = extractelement <16 x float> %B, i32 1244  %add = fadd float %5, %6245  %7 = extractelement <16 x float> %A, i32 3246  %8 = extractelement <16 x float> %B, i32 3247  %add2 = fadd float %7, %8248  %9 = extractelement <16 x float> %A, i32 4249  %10 = extractelement <16 x float> %B, i32 4250  %sub3 = fsub float %9, %10251  %11 = extractelement <16 x float> %A, i32 6252  %12 = extractelement <16 x float> %B, i32 6253  %sub4 = fsub float %11, %12254  %13 = extractelement <16 x float> %A, i32 5255  %14 = extractelement <16 x float> %B, i32 5256  %add3 = fadd float %13, %14257  %15 = extractelement <16 x float> %A, i32 7258  %16 = extractelement <16 x float> %B, i32 7259  %add4 = fadd float %15, %16260  %17 = extractelement <16 x float> %A, i32 8261  %18 = extractelement <16 x float> %B, i32 8262  %sub5 = fsub float %17, %18263  %19 = extractelement <16 x float> %A, i32 10264  %20 = extractelement <16 x float> %B, i32 10265  %sub6 = fsub float %19, %20266  %21 = extractelement <16 x float> %A, i32 9267  %22 = extractelement <16 x float> %B, i32 9268  %add5 = fadd float %21, %22269  %23 = extractelement <16 x float> %A, i32 11270  %24 = extractelement <16 x float> %B, i32 11271  %add6 = fadd float %23, %24272  %25 = extractelement <16 x float> %A, i32 12273  %26 = extractelement <16 x float> %B, i32 12274  %sub7 = fsub float %25, %26275  %27 = extractelement <16 x float> %A, i32 14276  %28 = extractelement <16 x float> %B, i32 14277  %sub8 = fsub float %27, %28278  %29 = extractelement <16 x float> %A, i32 13279  %30 = extractelement <16 x float> %B, i32 13280  %add7 = fadd float %29, %30281  %31 = extractelement <16 x float> %A, i32 15282  %32 = extractelement <16 x float> %B, i32 15283  %add8 = fadd float %31, %32284  %vecinsert1 = insertelement <16 x float> undef, float %add, i32 1285  %vecinsert2 = insertelement <16 x float> %vecinsert1, float %add2, i32 3286  %vecinsert3 = insertelement <16 x float> %vecinsert2, float %sub, i32 0287  %vecinsert4 = insertelement <16 x float> %vecinsert3, float %sub2, i32 2288  %vecinsert5 = insertelement <16 x float> %vecinsert4, float %add3, i32 5289  %vecinsert6 = insertelement <16 x float> %vecinsert5, float %add4, i32 7290  %vecinsert7 = insertelement <16 x float> %vecinsert6, float %sub3, i32 4291  %vecinsert8 = insertelement <16 x float> %vecinsert7, float %sub4, i32 6292  %vecinsert9 = insertelement <16 x float> %vecinsert8, float %add5, i32 9293  %vecinsert10 = insertelement <16 x float> %vecinsert9, float %add6, i32 11294  %vecinsert11 = insertelement <16 x float> %vecinsert10, float %sub5, i32 8295  %vecinsert12 = insertelement <16 x float> %vecinsert11, float %sub6, i32 10296  %vecinsert13 = insertelement <16 x float> %vecinsert12, float %add7, i32 13297  %vecinsert14 = insertelement <16 x float> %vecinsert13, float %add8, i32 15298  %vecinsert15 = insertelement <16 x float> %vecinsert14, float %sub7, i32 12299  %vecinsert16 = insertelement <16 x float> %vecinsert15, float %sub8, i32 14300  ret <16 x float> %vecinsert16301}302 303; Test that non-sequential / partial add-sub patterns are still folded.304 305define <4 x float> @test_addsub_v4f32_shuffle_1302(<4 x float> %A, <4 x float> %B) {306; CHECK-LABEL: @test_addsub_v4f32_shuffle_1302(307; CHECK-NEXT:    [[TMP1:%.*]] = fsub <4 x float> [[A:%.*]], [[B:%.*]]308; CHECK-NEXT:    [[TMP2:%.*]] = fadd <4 x float> [[A]], [[B]]309; CHECK-NEXT:    [[TMP3:%.*]] = shufflevector <4 x float> [[TMP1]], <4 x float> [[TMP2]], <4 x i32> <i32 0, i32 5, i32 2, i32 7>310; CHECK-NEXT:    ret <4 x float> [[TMP3]]311;312  %1 = extractelement <4 x float> %A, i32 0313  %2 = extractelement <4 x float> %B, i32 0314  %sub = fsub float %1, %2315  %3 = extractelement <4 x float> %A, i32 2316  %4 = extractelement <4 x float> %B, i32 2317  %sub2 = fsub float %3, %4318  %5 = extractelement <4 x float> %A, i32 1319  %6 = extractelement <4 x float> %B, i32 1320  %add = fadd float %5, %6321  %7 = extractelement <4 x float> %A, i32 3322  %8 = extractelement <4 x float> %B, i32 3323  %add2 = fadd float %7, %8324  %vecinsert1 = insertelement <4 x float> undef, float %add, i32 1325  %vecinsert2 = insertelement <4 x float> %vecinsert1, float %add2, i32 3326  %vecinsert3 = insertelement <4 x float> %vecinsert2, float %sub, i32 0327  %vecinsert4 = insertelement <4 x float> %vecinsert3, float %sub2, i32 2328  ret <4 x float> %vecinsert4329}330 331define <4 x float> @test_addsub_v4f32_partial_23(<4 x float> %A, <4 x float> %B) {332; CHECK-LABEL: @test_addsub_v4f32_partial_23(333; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <4 x float> [[A:%.*]], <4 x float> poison, <2 x i32> <i32 2, i32 3>334; CHECK-NEXT:    [[TMP2:%.*]] = shufflevector <4 x float> [[B:%.*]], <4 x float> poison, <2 x i32> <i32 2, i32 3>335; CHECK-NEXT:    [[TMP3:%.*]] = fsub <2 x float> [[TMP1]], [[TMP2]]336; CHECK-NEXT:    [[TMP4:%.*]] = fadd <2 x float> [[TMP1]], [[TMP2]]337; CHECK-NEXT:    [[TMP5:%.*]] = shufflevector <2 x float> [[TMP3]], <2 x float> [[TMP4]], <4 x i32> <i32 0, i32 3, i32 poison, i32 poison>338; CHECK-NEXT:    [[VECINSERT21:%.*]] = shufflevector <4 x float> [[TMP5]], <4 x float> <float undef, float undef, float poison, float poison>, <4 x i32> <i32 4, i32 5, i32 0, i32 1>339; CHECK-NEXT:    ret <4 x float> [[VECINSERT21]]340;341  %1 = extractelement <4 x float> %A, i32 2342  %2 = extractelement <4 x float> %B, i32 2343  %sub2 = fsub float %1, %2344  %3 = extractelement <4 x float> %A, i32 3345  %4 = extractelement <4 x float> %B, i32 3346  %add2 = fadd float %3, %4347  %vecinsert1 = insertelement <4 x float> undef, float %sub2, i32 2348  %vecinsert2 = insertelement <4 x float> %vecinsert1, float %add2, i32 3349  ret <4 x float> %vecinsert2350}351 352define <4 x float> @test_addsub_v4f32_partial_03(<4 x float> %A, <4 x float> %B) {353; CHECK-LABEL: @test_addsub_v4f32_partial_03(354; CHECK-NEXT:    [[FOLDEXTEXTBINOP:%.*]] = fsub <4 x float> [[A:%.*]], [[B:%.*]]355; CHECK-NEXT:    [[FOLDEXTEXTBINOP2:%.*]] = fadd <4 x float> [[A]], [[B]]356; CHECK-NEXT:    [[VECINSERT1:%.*]] = shufflevector <4 x float> [[FOLDEXTEXTBINOP]], <4 x float> <float poison, float undef, float undef, float poison>, <4 x i32> <i32 0, i32 5, i32 6, i32 poison>357; CHECK-NEXT:    [[VECINSERT2:%.*]] = shufflevector <4 x float> [[VECINSERT1]], <4 x float> [[FOLDEXTEXTBINOP2]], <4 x i32> <i32 0, i32 1, i32 2, i32 7>358; CHECK-NEXT:    ret <4 x float> [[VECINSERT2]]359;360  %1 = extractelement <4 x float> %A, i32 0361  %2 = extractelement <4 x float> %B, i32 0362  %sub = fsub float %1, %2363  %3 = extractelement <4 x float> %A, i32 3364  %4 = extractelement <4 x float> %B, i32 3365  %add = fadd float %4, %3366  %vecinsert1 = insertelement <4 x float> undef, float %sub, i32 0367  %vecinsert2 = insertelement <4 x float> %vecinsert1, float %add, i32 3368  ret <4 x float> %vecinsert2369}370 371define <4 x float> @test_addsub_v4f32_partial_12(<4 x float> %A, <4 x float> %B) {372; CHECK-LABEL: @test_addsub_v4f32_partial_12(373; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <4 x float> [[A:%.*]], <4 x float> poison, <2 x i32> <i32 1, i32 2>374; CHECK-NEXT:    [[TMP2:%.*]] = shufflevector <4 x float> [[B:%.*]], <4 x float> poison, <2 x i32> <i32 1, i32 2>375; CHECK-NEXT:    [[TMP3:%.*]] = fadd <2 x float> [[TMP1]], [[TMP2]]376; CHECK-NEXT:    [[TMP4:%.*]] = fsub <2 x float> [[TMP1]], [[TMP2]]377; CHECK-NEXT:    [[TMP5:%.*]] = shufflevector <2 x float> [[TMP3]], <2 x float> [[TMP4]], <4 x i32> <i32 0, i32 3, i32 poison, i32 poison>378; CHECK-NEXT:    [[VECINSERT21:%.*]] = shufflevector <4 x float> [[TMP5]], <4 x float> <float undef, float poison, float poison, float undef>, <4 x i32> <i32 4, i32 0, i32 1, i32 7>379; CHECK-NEXT:    ret <4 x float> [[VECINSERT21]]380;381  %1 = extractelement <4 x float> %A, i32 2382  %2 = extractelement <4 x float> %B, i32 2383  %sub = fsub float %1, %2384  %3 = extractelement <4 x float> %A, i32 1385  %4 = extractelement <4 x float> %B, i32 1386  %add = fadd float %3, %4387  %vecinsert1 = insertelement <4 x float> undef, float %sub, i32 2388  %vecinsert2 = insertelement <4 x float> %vecinsert1, float %add, i32 1389  ret <4 x float> %vecinsert2390}391 392define <4 x float> @test_addsub_v4f32_partial_01(<4 x float> %A, <4 x float> %B) {393; CHECK-LABEL: @test_addsub_v4f32_partial_01(394; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <4 x float> [[A:%.*]], <4 x float> poison, <2 x i32> <i32 0, i32 1>395; CHECK-NEXT:    [[TMP2:%.*]] = shufflevector <4 x float> [[B:%.*]], <4 x float> poison, <2 x i32> <i32 0, i32 1>396; CHECK-NEXT:    [[TMP3:%.*]] = fsub <2 x float> [[TMP1]], [[TMP2]]397; CHECK-NEXT:    [[TMP4:%.*]] = fadd <2 x float> [[TMP1]], [[TMP2]]398; CHECK-NEXT:    [[TMP5:%.*]] = shufflevector <2 x float> [[TMP3]], <2 x float> [[TMP4]], <2 x i32> <i32 0, i32 3>399; CHECK-NEXT:    [[TMP6:%.*]] = shufflevector <2 x float> [[TMP5]], <2 x float> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3>400; CHECK-NEXT:    ret <4 x float> [[TMP6]]401;402  %1 = extractelement <4 x float> %A, i32 0403  %2 = extractelement <4 x float> %B, i32 0404  %sub2 = fsub float %1, %2405  %3 = extractelement <4 x float> %A, i32 1406  %4 = extractelement <4 x float> %B, i32 1407  %add2 = fadd float %3, %4408  %vecinsert1 = insertelement <4 x float> undef, float %sub2, i32 0409  %vecinsert2 = insertelement <4 x float> %vecinsert1, float %add2, i32 1410  ret <4 x float> %vecinsert2411}412 413define <4 x float> @PR45015(<4 x float> %arg, <4 x float> %arg1) {414; CHECK-LABEL: @PR45015(415; CHECK-NEXT:    [[TMP1:%.*]] = fsub <4 x float> [[ARG:%.*]], [[ARG1:%.*]]416; CHECK-NEXT:    [[TMP2:%.*]] = fadd <4 x float> [[ARG]], [[ARG1]]417; CHECK-NEXT:    [[T16:%.*]] = shufflevector <4 x float> [[TMP1]], <4 x float> [[TMP2]], <4 x i32> <i32 0, i32 5, i32 2, i32 7>418; CHECK-NEXT:    ret <4 x float> [[T16]]419;420  %t = extractelement <4 x float> %arg, i32 0421  %t2 = extractelement <4 x float> %arg1, i32 0422  %t3 = fsub float %t, %t2423  %t4 = insertelement <4 x float> undef, float %t3, i32 0424  %t5 = extractelement <4 x float> %arg, i32 1425  %t6 = extractelement <4 x float> %arg1, i32 1426  %t7 = fadd float %t5, %t6427  %t8 = insertelement <4 x float> %t4, float %t7, i32 1428  %t9 = extractelement <4 x float> %arg, i32 2429  %t10 = extractelement <4 x float> %arg1, i32 2430  %t11 = fsub float %t9, %t10431  %t12 = insertelement <4 x float> %t8, float %t11, i32 2432  %t13 = extractelement <4 x float> %arg, i32 3433  %t14 = extractelement <4 x float> %arg1, i32 3434  %t15 = fadd float %t13, %t14435  %t16 = insertelement <4 x float> %t12, float %t15, i32 3436  ret <4 x float> %t16437}438 439; PR42022 - https://bugs.llvm.org/show_bug.cgi?id=42022440 441%struct.Vector4 = type { float, float, float, float }442 443define { <2 x float>, <2 x float> } @add_aggregate(<2 x float> %a0, <2 x float> %a1, <2 x float> %b0, <2 x float> %b1) {444; CHECK-LABEL: @add_aggregate(445; CHECK-NEXT:    [[TMP1:%.*]] = fadd <2 x float> [[A0:%.*]], [[B0:%.*]]446; CHECK-NEXT:    [[TMP2:%.*]] = fadd <2 x float> [[A1:%.*]], [[B1:%.*]]447; CHECK-NEXT:    [[FCA_0_INSERT:%.*]] = insertvalue { <2 x float>, <2 x float> } undef, <2 x float> [[TMP1]], 0448; CHECK-NEXT:    [[FCA_1_INSERT:%.*]] = insertvalue { <2 x float>, <2 x float> } [[FCA_0_INSERT]], <2 x float> [[TMP2]], 1449; CHECK-NEXT:    ret { <2 x float>, <2 x float> } [[FCA_1_INSERT]]450;451  %a00 = extractelement <2 x float> %a0, i32 0452  %b00 = extractelement <2 x float> %b0, i32 0453  %add = fadd float %a00, %b00454  %retval.0.0.insert = insertelement <2 x float> undef, float %add, i32 0455  %a01 = extractelement <2 x float> %a0, i32 1456  %b01 = extractelement <2 x float> %b0, i32 1457  %add4 = fadd float %a01, %b01458  %retval.0.1.insert = insertelement <2 x float> %retval.0.0.insert, float %add4, i32 1459  %a10 = extractelement <2 x float> %a1, i32 0460  %b10 = extractelement <2 x float> %b1, i32 0461  %add7 = fadd float %a10, %b10462  %retval.1.0.insert = insertelement <2 x float> undef, float %add7, i32 0463  %a11 = extractelement <2 x float> %a1, i32 1464  %b11 = extractelement <2 x float> %b1, i32 1465  %add10 = fadd float %a11, %b11466  %retval.1.1.insert = insertelement <2 x float> %retval.1.0.insert, float %add10, i32 1467  %fca.0.insert = insertvalue { <2 x float>, <2 x float> } undef, <2 x float> %retval.0.1.insert, 0468  %fca.1.insert = insertvalue { <2 x float>, <2 x float> } %fca.0.insert, <2 x float> %retval.1.1.insert, 1469  ret { <2 x float>, <2 x float> } %fca.1.insert470}471 472define void @add_aggregate_store(<2 x float> %a0, <2 x float> %a1, <2 x float> %b0, <2 x float> %b1, ptr nocapture dereferenceable(16) %r) {473; CHECK-LABEL: @add_aggregate_store(474; CHECK-NEXT:    [[TMP1:%.*]] = fadd <2 x float> [[A0:%.*]], [[B0:%.*]]475; CHECK-NEXT:    [[TMP2:%.*]] = fadd <2 x float> [[A1:%.*]], [[B1:%.*]]476; CHECK-NEXT:    [[TMP3:%.*]] = shufflevector <2 x float> [[TMP1]], <2 x float> [[TMP2]], <4 x i32> <i32 0, i32 1, i32 2, i32 3>477; CHECK-NEXT:    store <4 x float> [[TMP3]], ptr [[R:%.*]], align 4478; CHECK-NEXT:    ret void479;480  %a00 = extractelement <2 x float> %a0, i32 0481  %b00 = extractelement <2 x float> %b0, i32 0482  %add = fadd float %a00, %b00483  store float %add, ptr %r, align 4484  %a01 = extractelement <2 x float> %a0, i32 1485  %b01 = extractelement <2 x float> %b0, i32 1486  %add4 = fadd float %a01, %b01487  %r1 = getelementptr inbounds %struct.Vector4, ptr %r, i64 0, i32 1488  store float %add4, ptr %r1, align 4489  %a10 = extractelement <2 x float> %a1, i32 0490  %b10 = extractelement <2 x float> %b1, i32 0491  %add7 = fadd float %a10, %b10492  %r2 = getelementptr inbounds %struct.Vector4, ptr %r, i64 0, i32 2493  store float %add7, ptr %r2, align 4494  %a11 = extractelement <2 x float> %a1, i32 1495  %b11 = extractelement <2 x float> %b1, i32 1496  %add10 = fadd float %a11, %b11497  %r3 = getelementptr inbounds %struct.Vector4, ptr %r, i64 0, i32 3498  store float %add10, ptr %r3, align 4499  ret void500}501 502; PR58139503define <2 x double> @_mm_complexmult_pd_naive(<2 x double> %a, <2 x double> %b) {504; SSE-LABEL: @_mm_complexmult_pd_naive(505; SSE-NEXT:    [[TMP2:%.*]] = shufflevector <2 x double> [[A:%.*]], <2 x double> poison, <2 x i32> <i32 1, i32 1>506; SSE-NEXT:    [[TMP3:%.*]] = fneg <2 x double> [[B:%.*]]507; SSE-NEXT:    [[TMP4:%.*]] = shufflevector <2 x double> [[TMP3]], <2 x double> [[B]], <2 x i32> <i32 1, i32 2>508; SSE-NEXT:    [[TMP5:%.*]] = fmul <2 x double> [[TMP2]], [[TMP4]]509; SSE-NEXT:    [[TMP6:%.*]] = shufflevector <2 x double> [[A]], <2 x double> poison, <2 x i32> zeroinitializer510; SSE-NEXT:    [[TMP7:%.*]] = tail call <2 x double> @llvm.fmuladd.v2f64(<2 x double> [[TMP6]], <2 x double> [[B]], <2 x double> [[TMP5]])511; SSE-NEXT:    ret <2 x double> [[TMP7]]512;513; AVX-LABEL: @_mm_complexmult_pd_naive(514; AVX-NEXT:    [[A0:%.*]] = extractelement <2 x double> [[A:%.*]], i64 0515; AVX-NEXT:    [[A1:%.*]] = extractelement <2 x double> [[A]], i64 1516; AVX-NEXT:    [[B0:%.*]] = extractelement <2 x double> [[B:%.*]], i64 0517; AVX-NEXT:    [[B1:%.*]] = extractelement <2 x double> [[B]], i64 1518; AVX-NEXT:    [[MUL10:%.*]] = fmul double [[A1]], [[B0]]519; AVX-NEXT:    [[TMP1:%.*]] = fneg double [[B1]]520; AVX-NEXT:    [[NEG11:%.*]] = fmul double [[A1]], [[TMP1]]521; AVX-NEXT:    [[MADD0:%.*]] = tail call double @llvm.fmuladd.f64(double [[A0]], double [[B0]], double [[NEG11]])522; AVX-NEXT:    [[MADD1:%.*]] = tail call double @llvm.fmuladd.f64(double [[A0]], double [[B1]], double [[MUL10]])523; AVX-NEXT:    [[RES0:%.*]] = insertelement <2 x double> poison, double [[MADD0]], i64 0524; AVX-NEXT:    [[RES1:%.*]] = insertelement <2 x double> [[RES0]], double [[MADD1]], i64 1525; AVX-NEXT:    ret <2 x double> [[RES1]]526;527  %a0 = extractelement <2 x double> %a, i32 0528  %a1 = extractelement <2 x double> %a, i32 1529  %b0 = extractelement <2 x double> %b, i32 0530  %b1 = extractelement <2 x double> %b, i32 1531  %mul10 = fmul double %a1, %b0532  %mul11 = fmul double %a1, %b1533  %neg11 = fneg double %mul11534  %madd0 = call double @llvm.fmuladd.f64(double %a0, double %b0, double %neg11)535  %madd1 = call double @llvm.fmuladd.f64(double %a0, double %b1, double %mul10)536  %res0 = insertelement <2 x double> undef, double %madd0, i32 0537  %res1 = insertelement <2 x double> %res0, double %madd1, i32 1538  ret <2 x double> %res1539}540