brintos

brintos / llvm-project-archived public Read only

0
0
Text · 27.6 KiB · 9f3244d Raw
536 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> poison, 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> poison, 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> poison, 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> poison, 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> poison, 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> poison, 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> poison, 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> poison, 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:    [[VECINSERT21:%.*]] = shufflevector <2 x float> [[TMP3]], <2 x float> [[TMP4]], <4 x i32> <i32 poison, i32 poison, i32 0, i32 3>338; CHECK-NEXT:    ret <4 x float> [[VECINSERT21]]339;340  %1 = extractelement <4 x float> %A, i32 2341  %2 = extractelement <4 x float> %B, i32 2342  %sub2 = fsub float %1, %2343  %3 = extractelement <4 x float> %A, i32 3344  %4 = extractelement <4 x float> %B, i32 3345  %add2 = fadd float %3, %4346  %vecinsert1 = insertelement <4 x float> poison, float %sub2, i32 2347  %vecinsert2 = insertelement <4 x float> %vecinsert1, float %add2, i32 3348  ret <4 x float> %vecinsert2349}350 351define <4 x float> @test_addsub_v4f32_partial_03(<4 x float> %A, <4 x float> %B) {352; CHECK-LABEL: @test_addsub_v4f32_partial_03(353; CHECK-NEXT:    [[FOLDEXTEXTBINOP:%.*]] = fsub <4 x float> [[A:%.*]], [[B:%.*]]354; CHECK-NEXT:    [[FOLDEXTEXTBINOP2:%.*]] = fadd <4 x float> [[A]], [[B]]355; CHECK-NEXT:    [[VECINSERT2:%.*]] = shufflevector <4 x float> [[FOLDEXTEXTBINOP]], <4 x float> [[FOLDEXTEXTBINOP2]], <4 x i32> <i32 0, i32 poison, i32 poison, i32 7>356; CHECK-NEXT:    ret <4 x float> [[VECINSERT2]]357;358  %1 = extractelement <4 x float> %A, i32 0359  %2 = extractelement <4 x float> %B, i32 0360  %sub = fsub float %1, %2361  %3 = extractelement <4 x float> %A, i32 3362  %4 = extractelement <4 x float> %B, i32 3363  %add = fadd float %4, %3364  %vecinsert1 = insertelement <4 x float> poison, float %sub, i32 0365  %vecinsert2 = insertelement <4 x float> %vecinsert1, float %add, i32 3366  ret <4 x float> %vecinsert2367}368 369define <4 x float> @test_addsub_v4f32_partial_12(<4 x float> %A, <4 x float> %B) {370; CHECK-LABEL: @test_addsub_v4f32_partial_12(371; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <4 x float> [[A:%.*]], <4 x float> poison, <2 x i32> <i32 1, i32 2>372; CHECK-NEXT:    [[TMP2:%.*]] = shufflevector <4 x float> [[B:%.*]], <4 x float> poison, <2 x i32> <i32 1, i32 2>373; CHECK-NEXT:    [[TMP3:%.*]] = fadd <2 x float> [[TMP1]], [[TMP2]]374; CHECK-NEXT:    [[TMP4:%.*]] = fsub <2 x float> [[TMP1]], [[TMP2]]375; CHECK-NEXT:    [[VECINSERT21:%.*]] = shufflevector <2 x float> [[TMP3]], <2 x float> [[TMP4]], <4 x i32> <i32 poison, i32 0, i32 3, i32 poison>376; CHECK-NEXT:    ret <4 x float> [[VECINSERT21]]377;378  %1 = extractelement <4 x float> %A, i32 2379  %2 = extractelement <4 x float> %B, i32 2380  %sub = fsub float %1, %2381  %3 = extractelement <4 x float> %A, i32 1382  %4 = extractelement <4 x float> %B, i32 1383  %add = fadd float %3, %4384  %vecinsert1 = insertelement <4 x float> poison, float %sub, i32 2385  %vecinsert2 = insertelement <4 x float> %vecinsert1, float %add, i32 1386  ret <4 x float> %vecinsert2387}388 389define <4 x float> @test_addsub_v4f32_partial_01(<4 x float> %A, <4 x float> %B) {390; CHECK-LABEL: @test_addsub_v4f32_partial_01(391; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <4 x float> [[A:%.*]], <4 x float> poison, <2 x i32> <i32 0, i32 1>392; CHECK-NEXT:    [[TMP2:%.*]] = shufflevector <4 x float> [[B:%.*]], <4 x float> poison, <2 x i32> <i32 0, i32 1>393; CHECK-NEXT:    [[TMP3:%.*]] = fsub <2 x float> [[TMP1]], [[TMP2]]394; CHECK-NEXT:    [[TMP4:%.*]] = fadd <2 x float> [[TMP1]], [[TMP2]]395; CHECK-NEXT:    [[TMP6:%.*]] = shufflevector <2 x float> [[TMP3]], <2 x float> [[TMP4]], <4 x i32> <i32 0, i32 3, i32 poison, i32 poison>396; CHECK-NEXT:    ret <4 x float> [[TMP6]]397;398  %1 = extractelement <4 x float> %A, i32 0399  %2 = extractelement <4 x float> %B, i32 0400  %sub2 = fsub float %1, %2401  %3 = extractelement <4 x float> %A, i32 1402  %4 = extractelement <4 x float> %B, i32 1403  %add2 = fadd float %3, %4404  %vecinsert1 = insertelement <4 x float> poison, float %sub2, i32 0405  %vecinsert2 = insertelement <4 x float> %vecinsert1, float %add2, i32 1406  ret <4 x float> %vecinsert2407}408 409define <4 x float> @PR45015(<4 x float> %arg, <4 x float> %arg1) {410; CHECK-LABEL: @PR45015(411; CHECK-NEXT:    [[TMP1:%.*]] = fsub <4 x float> [[ARG:%.*]], [[ARG1:%.*]]412; CHECK-NEXT:    [[TMP2:%.*]] = fadd <4 x float> [[ARG]], [[ARG1]]413; CHECK-NEXT:    [[T16:%.*]] = shufflevector <4 x float> [[TMP1]], <4 x float> [[TMP2]], <4 x i32> <i32 0, i32 5, i32 2, i32 7>414; CHECK-NEXT:    ret <4 x float> [[T16]]415;416  %t = extractelement <4 x float> %arg, i32 0417  %t2 = extractelement <4 x float> %arg1, i32 0418  %t3 = fsub float %t, %t2419  %t4 = insertelement <4 x float> poison, float %t3, i32 0420  %t5 = extractelement <4 x float> %arg, i32 1421  %t6 = extractelement <4 x float> %arg1, i32 1422  %t7 = fadd float %t5, %t6423  %t8 = insertelement <4 x float> %t4, float %t7, i32 1424  %t9 = extractelement <4 x float> %arg, i32 2425  %t10 = extractelement <4 x float> %arg1, i32 2426  %t11 = fsub float %t9, %t10427  %t12 = insertelement <4 x float> %t8, float %t11, i32 2428  %t13 = extractelement <4 x float> %arg, i32 3429  %t14 = extractelement <4 x float> %arg1, i32 3430  %t15 = fadd float %t13, %t14431  %t16 = insertelement <4 x float> %t12, float %t15, i32 3432  ret <4 x float> %t16433}434 435; PR42022 - https://bugs.llvm.org/show_bug.cgi?id=42022436 437%struct.Vector4 = type { float, float, float, float }438 439define { <2 x float>, <2 x float> } @add_aggregate(<2 x float> %a0, <2 x float> %a1, <2 x float> %b0, <2 x float> %b1) {440; CHECK-LABEL: @add_aggregate(441; CHECK-NEXT:    [[TMP1:%.*]] = fadd <2 x float> [[A0:%.*]], [[B0:%.*]]442; CHECK-NEXT:    [[TMP2:%.*]] = fadd <2 x float> [[A1:%.*]], [[B1:%.*]]443; CHECK-NEXT:    [[FCA_0_INSERT:%.*]] = insertvalue { <2 x float>, <2 x float> } undef, <2 x float> [[TMP1]], 0444; CHECK-NEXT:    [[FCA_1_INSERT:%.*]] = insertvalue { <2 x float>, <2 x float> } [[FCA_0_INSERT]], <2 x float> [[TMP2]], 1445; CHECK-NEXT:    ret { <2 x float>, <2 x float> } [[FCA_1_INSERT]]446;447  %a00 = extractelement <2 x float> %a0, i32 0448  %b00 = extractelement <2 x float> %b0, i32 0449  %add = fadd float %a00, %b00450  %retval.0.0.insert = insertelement <2 x float> poison, float %add, i32 0451  %a01 = extractelement <2 x float> %a0, i32 1452  %b01 = extractelement <2 x float> %b0, i32 1453  %add4 = fadd float %a01, %b01454  %retval.0.1.insert = insertelement <2 x float> %retval.0.0.insert, float %add4, i32 1455  %a10 = extractelement <2 x float> %a1, i32 0456  %b10 = extractelement <2 x float> %b1, i32 0457  %add7 = fadd float %a10, %b10458  %retval.1.0.insert = insertelement <2 x float> poison, float %add7, i32 0459  %a11 = extractelement <2 x float> %a1, i32 1460  %b11 = extractelement <2 x float> %b1, i32 1461  %add10 = fadd float %a11, %b11462  %retval.1.1.insert = insertelement <2 x float> %retval.1.0.insert, float %add10, i32 1463  %fca.0.insert = insertvalue { <2 x float>, <2 x float> } undef, <2 x float> %retval.0.1.insert, 0464  %fca.1.insert = insertvalue { <2 x float>, <2 x float> } %fca.0.insert, <2 x float> %retval.1.1.insert, 1465  ret { <2 x float>, <2 x float> } %fca.1.insert466}467 468define 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) {469; CHECK-LABEL: @add_aggregate_store(470; CHECK-NEXT:    [[TMP1:%.*]] = fadd <2 x float> [[A0:%.*]], [[B0:%.*]]471; CHECK-NEXT:    [[TMP2:%.*]] = fadd <2 x float> [[A1:%.*]], [[B1:%.*]]472; CHECK-NEXT:    [[TMP3:%.*]] = shufflevector <2 x float> [[TMP1]], <2 x float> [[TMP2]], <4 x i32> <i32 0, i32 1, i32 2, i32 3>473; CHECK-NEXT:    store <4 x float> [[TMP3]], ptr [[R:%.*]], align 4474; CHECK-NEXT:    ret void475;476  %a00 = extractelement <2 x float> %a0, i32 0477  %b00 = extractelement <2 x float> %b0, i32 0478  %add = fadd float %a00, %b00479  store float %add, ptr %r, align 4480  %a01 = extractelement <2 x float> %a0, i32 1481  %b01 = extractelement <2 x float> %b0, i32 1482  %add4 = fadd float %a01, %b01483  %r1 = getelementptr inbounds %struct.Vector4, ptr %r, i64 0, i32 1484  store float %add4, ptr %r1, align 4485  %a10 = extractelement <2 x float> %a1, i32 0486  %b10 = extractelement <2 x float> %b1, i32 0487  %add7 = fadd float %a10, %b10488  %r2 = getelementptr inbounds %struct.Vector4, ptr %r, i64 0, i32 2489  store float %add7, ptr %r2, align 4490  %a11 = extractelement <2 x float> %a1, i32 1491  %b11 = extractelement <2 x float> %b1, i32 1492  %add10 = fadd float %a11, %b11493  %r3 = getelementptr inbounds %struct.Vector4, ptr %r, i64 0, i32 3494  store float %add10, ptr %r3, align 4495  ret void496}497 498; PR58139499define <2 x double> @_mm_complexmult_pd_naive(<2 x double> %a, <2 x double> %b) {500; SSE-LABEL: @_mm_complexmult_pd_naive(501; SSE-NEXT:    [[TMP2:%.*]] = shufflevector <2 x double> [[A:%.*]], <2 x double> poison, <2 x i32> <i32 1, i32 1>502; SSE-NEXT:    [[TMP3:%.*]] = fneg <2 x double> [[B:%.*]]503; SSE-NEXT:    [[TMP4:%.*]] = shufflevector <2 x double> [[TMP3]], <2 x double> [[B]], <2 x i32> <i32 1, i32 2>504; SSE-NEXT:    [[TMP5:%.*]] = fmul <2 x double> [[TMP2]], [[TMP4]]505; SSE-NEXT:    [[TMP6:%.*]] = shufflevector <2 x double> [[A]], <2 x double> poison, <2 x i32> zeroinitializer506; SSE-NEXT:    [[TMP7:%.*]] = tail call <2 x double> @llvm.fmuladd.v2f64(<2 x double> [[TMP6]], <2 x double> [[B]], <2 x double> [[TMP5]])507; SSE-NEXT:    ret <2 x double> [[TMP7]]508;509; AVX-LABEL: @_mm_complexmult_pd_naive(510; AVX-NEXT:    [[A0:%.*]] = extractelement <2 x double> [[A:%.*]], i64 0511; AVX-NEXT:    [[A1:%.*]] = extractelement <2 x double> [[A]], i64 1512; AVX-NEXT:    [[B0:%.*]] = extractelement <2 x double> [[B:%.*]], i64 0513; AVX-NEXT:    [[B1:%.*]] = extractelement <2 x double> [[B]], i64 1514; AVX-NEXT:    [[MUL10:%.*]] = fmul double [[A1]], [[B0]]515; AVX-NEXT:    [[TMP1:%.*]] = fneg double [[B1]]516; AVX-NEXT:    [[NEG11:%.*]] = fmul double [[A1]], [[TMP1]]517; AVX-NEXT:    [[MADD0:%.*]] = tail call double @llvm.fmuladd.f64(double [[A0]], double [[B0]], double [[NEG11]])518; AVX-NEXT:    [[MADD1:%.*]] = tail call double @llvm.fmuladd.f64(double [[A0]], double [[B1]], double [[MUL10]])519; AVX-NEXT:    [[RES0:%.*]] = insertelement <2 x double> poison, double [[MADD0]], i64 0520; AVX-NEXT:    [[RES1:%.*]] = insertelement <2 x double> [[RES0]], double [[MADD1]], i64 1521; AVX-NEXT:    ret <2 x double> [[RES1]]522;523  %a0 = extractelement <2 x double> %a, i32 0524  %a1 = extractelement <2 x double> %a, i32 1525  %b0 = extractelement <2 x double> %b, i32 0526  %b1 = extractelement <2 x double> %b, i32 1527  %mul10 = fmul double %a1, %b0528  %mul11 = fmul double %a1, %b1529  %neg11 = fneg double %mul11530  %madd0 = call double @llvm.fmuladd.f64(double %a0, double %b0, double %neg11)531  %madd1 = call double @llvm.fmuladd.f64(double %a0, double %b1, double %mul10)532  %res0 = insertelement <2 x double> poison, double %madd0, i32 0533  %res1 = insertelement <2 x double> %res0, double %madd1, i32 1534  ret <2 x double> %res1535}536