brintos

brintos / llvm-project-archived public Read only

0
0
Text · 16.3 KiB · 344014a Raw
396 lines · plain
1; RUN: opt -passes='require<profile-summary>,function(codegenprepare)' -mtriple=thumbv7-apple-ios %s -o - -mattr=+neon -S | FileCheck --check-prefix=IR-BOTH --check-prefix=IR-NORMAL %s2; RUN: opt -passes='require<profile-summary>,function(codegenprepare)' -mtriple=thumbv7-apple-ios %s -o - -mattr=+neon -S -stress-cgp-store-extract | FileCheck --check-prefix=IR-BOTH --check-prefix=IR-STRESS %s3; RUN: llc -mtriple=thumbv7-apple-ios %s -o - -mattr=+neon | FileCheck --check-prefix=ASM %s4 5; IR-BOTH-LABEL: @simpleOneInstructionPromotion6; IR-BOTH: [[LOAD:%[a-zA-Z_0-9-]+]] = load <2 x i32>, ptr %addr17; IR-BOTH-NEXT: [[VECTOR_OR:%[a-zA-Z_0-9-]+]] = or <2 x i32> [[LOAD]], <i32 poison, i32 1>8; IR-BOTH-NEXT: [[EXTRACT:%[a-zA-Z_0-9-]+]] = extractelement <2 x i32> [[VECTOR_OR]], i32 19; IR-BOTH-NEXT: store i32 [[EXTRACT]], ptr %dest10; IR-BOTH-NEXT: ret11;12; Make sure we got rid of any expensive vmov.32 instructions.13; ASM-LABEL: simpleOneInstructionPromotion:14; ASM: vldr [[LOAD:d[0-9]+]], [r0]15; ASM-NEXT: vorr.i32 [[LOAD]], #0x116; ASM-NEXT: vst1.32 {[[LOAD]][1]}, [r1:32]17; ASM-NEXT: bx18define void @simpleOneInstructionPromotion(ptr %addr1, ptr %dest) {19  %in1 = load <2 x i32>, ptr %addr1, align 820  %extract = extractelement <2 x i32> %in1, i32 121  %out = or i32 %extract, 122  store i32 %out, ptr %dest, align 423  ret void24}25 26; IR-BOTH-LABEL: @unsupportedInstructionForPromotion27; IR-BOTH: [[LOAD:%[a-zA-Z_0-9-]+]] = load <2 x i32>, ptr %addr128; IR-BOTH-NEXT: [[EXTRACT:%[a-zA-Z_0-9-]+]] = extractelement <2 x i32> [[LOAD]], i32 029; IR-BOTH-NEXT: [[CMP:%[a-zA-Z_0-9-]+]] = icmp eq i32 [[EXTRACT]], %in230; IR-BOTH-NEXT: store i1 [[CMP]], ptr %dest31; IR-BOTH-NEXT: ret32;33; ASM-LABEL: unsupportedInstructionForPromotion:34; ASM: vldr [[LOAD:d[0-9]+]], [r0]35; ASM: vmov.32 {{r[0-9]+}}, [[LOAD]]36; ASM: bx37define void @unsupportedInstructionForPromotion(ptr %addr1, i32 %in2, ptr %dest) {38  %in1 = load <2 x i32>, ptr %addr1, align 839  %extract = extractelement <2 x i32> %in1, i32 040  %out = icmp eq i32 %extract, %in241  store i1 %out, ptr %dest, align 442  ret void43}44 45 46; IR-BOTH-LABEL: @unsupportedChainInDifferentBBs47; IR-BOTH: [[LOAD:%[a-zA-Z_0-9-]+]] = load <2 x i32>, ptr %addr148; IR-BOTH-NEXT: [[EXTRACT:%[a-zA-Z_0-9-]+]] = extractelement <2 x i32> [[LOAD]], i32 049; IR-BOTH-NEXT: br i1 %bool, label %bb2, label %end50; BB251; IR-BOTH: [[OR:%[a-zA-Z_0-9-]+]] = or i32 [[EXTRACT]], 152; IR-BOTH-NEXT: store i32 [[OR]], ptr %dest, align 453; IR-BOTH: ret54;55; ASM-LABEL: unsupportedChainInDifferentBBs:56; ASM: vldr [[LOAD:d[0-9]+]], [r0]57; ASM: vmov.32 {{r[0-9]+}}, [[LOAD]]58; ASM: bx59define void @unsupportedChainInDifferentBBs(ptr %addr1, ptr %dest, i1 %bool) {60bb1:61  %in1 = load <2 x i32>, ptr %addr1, align 862  %extract = extractelement <2 x i32> %in1, i32 063  br i1 %bool, label %bb2, label %end64bb2: 65  %out = or i32 %extract, 166  store i32 %out, ptr %dest, align 467  br label %end68end:69  ret void70}71 72; IR-LABEL: @chainOfInstructionsToPromote73; IR-BOTH: [[LOAD:%[a-zA-Z_0-9-]+]] = load <2 x i32>, ptr %addr174; IR-BOTH-NEXT: [[VECTOR_OR1:%[a-zA-Z_0-9-]+]] = or <2 x i32> [[LOAD]], <i32 1, i32 poison>75; IR-BOTH-NEXT: [[VECTOR_OR2:%[a-zA-Z_0-9-]+]] = or <2 x i32> [[VECTOR_OR1]], <i32 1, i32 poison>76; IR-BOTH-NEXT: [[VECTOR_OR3:%[a-zA-Z_0-9-]+]] = or <2 x i32> [[VECTOR_OR2]], <i32 1, i32 poison>77; IR-BOTH-NEXT: [[VECTOR_OR4:%[a-zA-Z_0-9-]+]] = or <2 x i32> [[VECTOR_OR3]], <i32 1, i32 poison>78; IR-BOTH-NEXT: [[VECTOR_OR5:%[a-zA-Z_0-9-]+]] = or <2 x i32> [[VECTOR_OR4]], <i32 1, i32 poison>79; IR-BOTH-NEXT: [[VECTOR_OR6:%[a-zA-Z_0-9-]+]] = or <2 x i32> [[VECTOR_OR5]], <i32 1, i32 poison>80; IR-BOTH-NEXT: [[VECTOR_OR7:%[a-zA-Z_0-9-]+]] = or <2 x i32> [[VECTOR_OR6]], <i32 1, i32 poison>81; IR-BOTH-NEXT: [[EXTRACT:%[a-zA-Z_0-9-]+]] = extractelement <2 x i32> [[VECTOR_OR7]], i32 082; IR-BOTH-NEXT: store i32 [[EXTRACT]], ptr %dest83; IR-BOTH-NEXT: ret84;85; ASM-LABEL: chainOfInstructionsToPromote:86; ASM: vldr [[LOAD:d[0-9]+]], [r0]87; ASM-NOT: vmov.32 {{r[0-9]+}}, [[LOAD]]88; ASM: bx89define void @chainOfInstructionsToPromote(ptr %addr1, ptr %dest) {90  %in1 = load <2 x i32>, ptr %addr1, align 891  %extract = extractelement <2 x i32> %in1, i32 092  %out1 = or i32 %extract, 193  %out2 = or i32 %out1, 194  %out3 = or i32 %out2, 195  %out4 = or i32 %out3, 196  %out5 = or i32 %out4, 197  %out6 = or i32 %out5, 198  %out7 = or i32 %out6, 199  store i32 %out7, ptr %dest, align 4100  ret void101}102 103; IR-BOTH-LABEL: @unsupportedMultiUses104; IR-BOTH: [[LOAD:%[a-zA-Z_0-9-]+]] = load <2 x i32>, ptr %addr1105; IR-BOTH-NEXT: [[EXTRACT:%[a-zA-Z_0-9-]+]] = extractelement <2 x i32> [[LOAD]], i32 1106; IR-BOTH-NEXT: [[OR:%[a-zA-Z_0-9-]+]] = or i32 [[EXTRACT]], 1107; IR-BOTH-NEXT: store i32 [[OR]], ptr %dest108; IR-BOTH-NEXT: ret i32 [[OR]]109;110; ASM-LABEL: unsupportedMultiUses:111; ASM: vldr [[LOAD:d[0-9]+]], [r0]112; ASM: vmov.32 {{r[0-9]+}}, [[LOAD]]113; ASM: bx114define i32 @unsupportedMultiUses(ptr %addr1, ptr %dest) {115  %in1 = load <2 x i32>, ptr %addr1, align 8116  %extract = extractelement <2 x i32> %in1, i32 1117  %out = or i32 %extract, 1118  store i32 %out, ptr %dest, align 4119  ret i32 %out120}121 122; Check that we promote we a splat constant when this is a division.123; The NORMAL mode does not promote anything as divisions are not legal.124; IR-BOTH-LABEL: @udivCase125; IR-BOTH: [[LOAD:%[a-zA-Z_0-9-]+]] = load <2 x i32>, ptr %addr1126; Scalar version:127; IR-NORMAL-NEXT: [[EXTRACT:%[a-zA-Z_0-9-]+]] = extractelement <2 x i32> [[LOAD]], i32 1128; IR-NORMAL-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = udiv i32 [[EXTRACT]], 7129; Vector version:130; IR-STRESS-NEXT: [[DIV:%[a-zA-Z_0-9-]+]] = udiv <2 x i32> [[LOAD]], splat (i32 7)131; IR-STRESS-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = extractelement <2 x i32> [[DIV]], i32 1132;133; IR-BOTH-NEXT: store i32 [[RES]], ptr %dest134; IR-BOTH-NEXT: ret135define void @udivCase(ptr %addr1, ptr %dest) {136  %in1 = load <2 x i32>, ptr %addr1, align 8137  %extract = extractelement <2 x i32> %in1, i32 1138  %out = udiv i32 %extract, 7139  store i32 %out, ptr %dest, align 4140  ret void141}142 143; IR-BOTH-LABEL: @uremCase144; IR-BOTH: [[LOAD:%[a-zA-Z_0-9-]+]] = load <2 x i32>, ptr %addr1145; Scalar version:146; IR-NORMAL-NEXT: [[EXTRACT:%[a-zA-Z_0-9-]+]] = extractelement <2 x i32> [[LOAD]], i32 1147; IR-NORMAL-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = urem i32 [[EXTRACT]], 7148; Vector version:149; IR-STRESS-NEXT: [[DIV:%[a-zA-Z_0-9-]+]] = urem <2 x i32> [[LOAD]], splat (i32 7)150; IR-STRESS-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = extractelement <2 x i32> [[DIV]], i32 1151;152; IR-BOTH-NEXT: store i32 [[RES]], ptr %dest153; IR-BOTH-NEXT: ret 154define void @uremCase(ptr %addr1, ptr %dest) {155  %in1 = load <2 x i32>, ptr %addr1, align 8156  %extract = extractelement <2 x i32> %in1, i32 1157  %out = urem i32 %extract, 7158  store i32 %out, ptr %dest, align 4159  ret void160}161 162; IR-BOTH-LABEL: @sdivCase163; IR-BOTH: [[LOAD:%[a-zA-Z_0-9-]+]] = load <2 x i32>, ptr %addr1164; Scalar version:165; IR-NORMAL-NEXT: [[EXTRACT:%[a-zA-Z_0-9-]+]] = extractelement <2 x i32> [[LOAD]], i32 1166; IR-NORMAL-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = sdiv i32 [[EXTRACT]], 7167; Vector version:168; IR-STRESS-NEXT: [[DIV:%[a-zA-Z_0-9-]+]] = sdiv <2 x i32> [[LOAD]], splat (i32 7)169; IR-STRESS-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = extractelement <2 x i32> [[DIV]], i32 1170;171; IR-BOTH-NEXT: store i32 [[RES]], ptr %dest172; IR-BOTH-NEXT: ret 173define void @sdivCase(ptr %addr1, ptr %dest) {174  %in1 = load <2 x i32>, ptr %addr1, align 8175  %extract = extractelement <2 x i32> %in1, i32 1176  %out = sdiv i32 %extract, 7177  store i32 %out, ptr %dest, align 4178  ret void179}180 181; IR-BOTH-LABEL: @sremCase182; IR-BOTH: [[LOAD:%[a-zA-Z_0-9-]+]] = load <2 x i32>, ptr %addr1183; Scalar version:184; IR-NORMAL-NEXT: [[EXTRACT:%[a-zA-Z_0-9-]+]] = extractelement <2 x i32> [[LOAD]], i32 1185; IR-NORMAL-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = srem i32 [[EXTRACT]], 7186; Vector version:187; IR-STRESS-NEXT: [[DIV:%[a-zA-Z_0-9-]+]] = srem <2 x i32> [[LOAD]], splat (i32 7)188; IR-STRESS-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = extractelement <2 x i32> [[DIV]], i32 1189;190; IR-BOTH-NEXT: store i32 [[RES]], ptr %dest191; IR-BOTH-NEXT: ret 192define void @sremCase(ptr %addr1, ptr %dest) {193  %in1 = load <2 x i32>, ptr %addr1, align 8194  %extract = extractelement <2 x i32> %in1, i32 1195  %out = srem i32 %extract, 7196  store i32 %out, ptr %dest, align 4197  ret void198}199 200; IR-BOTH-LABEL: @fdivCase201; IR-BOTH: [[LOAD:%[a-zA-Z_0-9-]+]] = load <2 x float>, ptr %addr1202; Scalar version:  203; IR-NORMAL-NEXT: [[EXTRACT:%[a-zA-Z_0-9-]+]] = extractelement <2 x float> [[LOAD]], i32 1204; IR-NORMAL-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = fdiv float [[EXTRACT]], 7.0205; Vector version:206; IR-STRESS-NEXT: [[DIV:%[a-zA-Z_0-9-]+]] = fdiv <2 x float> [[LOAD]], splat (float 7.000000e+00)207; IR-STRESS-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = extractelement <2 x float> [[DIV]], i32 1208;209; IR-BOTH-NEXT: store float [[RES]], ptr %dest210; IR-BOTH-NEXT: ret211define void @fdivCase(ptr %addr1, ptr %dest) {212  %in1 = load <2 x float>, ptr %addr1, align 8   213  %extract = extractelement <2 x float> %in1, i32 1214  %out = fdiv float %extract, 7.0215  store float %out, ptr %dest, align 4216  ret void217}218 219; IR-BOTH-LABEL: @fremCase220; IR-BOTH: [[LOAD:%[a-zA-Z_0-9-]+]] = load <2 x float>, ptr %addr1221; Scalar version:  222; IR-NORMAL-NEXT: [[EXTRACT:%[a-zA-Z_0-9-]+]] = extractelement <2 x float> [[LOAD]], i32 1223; IR-NORMAL-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = frem float [[EXTRACT]], 7.0224; Vector version:225; IR-STRESS-NEXT: [[DIV:%[a-zA-Z_0-9-]+]] = frem <2 x float> [[LOAD]], splat (float 7.000000e+00)226; IR-STRESS-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = extractelement <2 x float> [[DIV]], i32 1227;228; IR-BOTH-NEXT: store float [[RES]], ptr %dest229; IR-BOTH-NEXT: ret230define void @fremCase(ptr %addr1, ptr %dest) {231  %in1 = load <2 x float>, ptr %addr1, align 8   232  %extract = extractelement <2 x float> %in1, i32 1233  %out = frem float %extract, 7.0234  store float %out, ptr %dest, align 4235  ret void236}237 238; Check that we do not promote when we may introduce undefined behavior239; like division by zero.240; IR-BOTH-LABEL: @undefDivCase241; IR-BOTH: [[LOAD:%[a-zA-Z_0-9-]+]] = load <2 x i32>, ptr %addr1242; IR-BOTH-NEXT: [[EXTRACT:%[a-zA-Z_0-9-]+]] = extractelement <2 x i32> [[LOAD]], i32 1243; IR-BOTH-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = udiv i32 7, [[EXTRACT]]244; IR-BOTH-NEXT: store i32 [[RES]], ptr %dest245; IR-BOTH-NEXT: ret246define void @undefDivCase(ptr %addr1, ptr %dest) {247  %in1 = load <2 x i32>, ptr %addr1, align 8248  %extract = extractelement <2 x i32> %in1, i32 1249  %out = udiv i32 7, %extract250  store i32 %out, ptr %dest, align 4251  ret void252}253 254 255; Check that we do not promote when we may introduce undefined behavior256; like division by zero.257; IR-BOTH-LABEL: @undefRemCase258; IR-BOTH: [[LOAD:%[a-zA-Z_0-9-]+]] = load <2 x i32>, ptr %addr1259; IR-BOTH-NEXT: [[EXTRACT:%[a-zA-Z_0-9-]+]] = extractelement <2 x i32> [[LOAD]], i32 1260; IR-BOTH-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = srem i32 7, [[EXTRACT]]261; IR-BOTH-NEXT: store i32 [[RES]], ptr %dest262; IR-BOTH-NEXT: ret263define void @undefRemCase(ptr %addr1, ptr %dest) {264  %in1 = load <2 x i32>, ptr %addr1, align 8265  %extract = extractelement <2 x i32> %in1, i32 1266  %out = srem i32 7, %extract267  store i32 %out, ptr %dest, align 4268  ret void269}270 271; Check that we use an undef mask for undefined behavior if the fast-math272; flag is set.273; IR-BOTH-LABEL: @undefConstantFRemCaseWithFastMath274; IR-BOTH: [[LOAD:%[a-zA-Z_0-9-]+]] = load <2 x float>, ptr %addr1275; Scalar version:  276; IR-NORMAL-NEXT: [[EXTRACT:%[a-zA-Z_0-9-]+]] = extractelement <2 x float> [[LOAD]], i32 1277; IR-NORMAL-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = frem nnan float [[EXTRACT]], 7.0278; Vector version:279; IR-STRESS-NEXT: [[DIV:%[a-zA-Z_0-9-]+]] = frem nnan <2 x float> [[LOAD]], <float poison, float 7.000000e+00>280; IR-STRESS-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = extractelement <2 x float> [[DIV]], i32 1281;282; IR-BOTH-NEXT: store float [[RES]], ptr %dest283; IR-BOTH-NEXT: ret284define void @undefConstantFRemCaseWithFastMath(ptr %addr1, ptr %dest) {285  %in1 = load <2 x float>, ptr %addr1, align 8   286  %extract = extractelement <2 x float> %in1, i32 1287  %out = frem nnan float %extract, 7.0288  store float %out, ptr %dest, align 4289  ret void290}291 292; Check that we use an undef mask for undefined behavior if the fast-math293; flag is set.294; IR-BOTH-LABEL: @undefVectorFRemCaseWithFastMath295; IR-BOTH: [[LOAD:%[a-zA-Z_0-9-]+]] = load <2 x float>, ptr %addr1296; Scalar version:  297; IR-NORMAL-NEXT: [[EXTRACT:%[a-zA-Z_0-9-]+]] = extractelement <2 x float> [[LOAD]], i32 1298; IR-NORMAL-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = frem nnan float 7.000000e+00, [[EXTRACT]]299; Vector version:300; IR-STRESS-NEXT: [[DIV:%[a-zA-Z_0-9-]+]] = frem nnan <2 x float> <float poison, float 7.000000e+00>, [[LOAD]]301; IR-STRESS-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = extractelement <2 x float> [[DIV]], i32 1302;303; IR-BOTH-NEXT: store float [[RES]], ptr %dest304; IR-BOTH-NEXT: ret305define void @undefVectorFRemCaseWithFastMath(ptr %addr1, ptr %dest) {306  %in1 = load <2 x float>, ptr %addr1, align 8   307  %extract = extractelement <2 x float> %in1, i32 1308  %out = frem nnan float 7.0, %extract309  store float %out, ptr %dest, align 4310  ret void311}312 313; Check that we are able to promote floating point value.314; This requires the STRESS mode, as floating point value are315; not promote on armv7.316; IR-BOTH-LABEL: @simpleOneInstructionPromotionFloat317; IR-BOTH: [[LOAD:%[a-zA-Z_0-9-]+]] = load <2 x float>, ptr %addr1318; Scalar version: 319; IR-NORMAL-NEXT: [[EXTRACT:%[a-zA-Z_0-9-]+]] = extractelement <2 x float> [[LOAD]], i32 1320; IR-NORMAL-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = fadd float [[EXTRACT]], 1.0321; Vector version:322; IR-STRESS-NEXT: [[DIV:%[a-zA-Z_0-9-]+]] = fadd <2 x float> [[LOAD]], <float poison, float 1.000000e+00>323; IR-STRESS-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = extractelement <2 x float> [[DIV]], i32 1324;325; IR-BOTH-NEXT: store float [[RES]], ptr %dest326; IR-BOTH-NEXT: ret327define void @simpleOneInstructionPromotionFloat(ptr %addr1, ptr %dest) {328  %in1 = load <2 x float>, ptr %addr1, align 8329  %extract = extractelement <2 x float> %in1, i32 1330  %out = fadd float %extract, 1.0331  store float %out, ptr %dest, align 4332  ret void333}334 335; Check that we correctly use a splat constant when we cannot336; determine at compile time the index of the extract.337; This requires the STRESS modes, as variable index are expensive338; to lower.339; IR-BOTH-LABEL: @simpleOneInstructionPromotionVariableIdx340; IR-BOTH: [[LOAD:%[a-zA-Z_0-9-]+]] = load <2 x i32>, ptr %addr1341; Scalar version:342; IR-NORMAL-NEXT: [[EXTRACT:%[a-zA-Z_0-9-]+]] = extractelement <2 x i32> [[LOAD]], i32 %idx343; IR-NORMAL-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = or i32 [[EXTRACT]], 1344; Vector version:345; IR-STRESS-NEXT: [[OR:%[a-zA-Z_0-9-]+]] = or <2 x i32> [[LOAD]], splat (i32 1)346; IR-STRESS-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = extractelement <2 x i32> [[OR]], i32 %idx347;348; IR-BOTH-NEXT: store i32 [[RES]], ptr %dest349; IR-BOTH-NEXT: ret350define void @simpleOneInstructionPromotionVariableIdx(ptr %addr1, ptr %dest, i32 %idx) {351  %in1 = load <2 x i32>, ptr %addr1, align 8352  %extract = extractelement <2 x i32> %in1, i32 %idx353  %out = or i32 %extract, 1354  store i32 %out, ptr %dest, align 4355  ret void356}357 358; Check a vector with more than 2 elements.359; IR-BOTH-LABEL: @simpleOneInstructionPromotion8x8360; IR-BOTH: [[LOAD:%[a-zA-Z_0-9-]+]] = load <8 x i8>, ptr %addr1361; IR-BOTH-NEXT: [[OR:%[a-zA-Z_0-9-]+]] = or <8 x i8> [[LOAD]], <i8 poison, i8 1, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison, i8 poison>362; IR-BOTH-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = extractelement <8 x i8> [[OR]], i32 1363; IR-BOTH-NEXT: store i8 [[RES]], ptr %dest364; IR-BOTH-NEXT: ret365define void @simpleOneInstructionPromotion8x8(ptr %addr1, ptr %dest) {366  %in1 = load <8 x i8>, ptr %addr1, align 8367  %extract = extractelement <8 x i8> %in1, i32 1368  %out = or i8 %extract, 1369  store i8 %out, ptr %dest, align 4370  ret void371}372 373; Check that we optimized the sequence correctly when it can be374; lowered on a Q register.375; IR-BOTH-LABEL: @simpleOneInstructionPromotion376; IR-BOTH: [[LOAD:%[a-zA-Z_0-9-]+]] = load <4 x i32>, ptr %addr1377; IR-BOTH-NEXT: [[VECTOR_OR:%[a-zA-Z_0-9-]+]] = or <4 x i32> [[LOAD]], <i32 poison, i32 1, i32 poison, i32 poison>378; IR-BOTH-NEXT: [[EXTRACT:%[a-zA-Z_0-9-]+]] = extractelement <4 x i32> [[VECTOR_OR]], i32 1379; IR-BOTH-NEXT: store i32 [[EXTRACT]], ptr %dest380; IR-BOTH-NEXT: ret381;382; Make sure we got rid of any expensive vmov.32 instructions.383; ASM-LABEL: simpleOneInstructionPromotion4x32:384; ASM: vld1.64 {[[LOAD:d[0-9]+]], d{{[0-9]+}}}, [r0]385; The Q register used here must be [[LOAD]] / 2, but we cannot express that.386; ASM-NEXT: vorr.i32 q{{[[0-9]+}}, #0x1387; ASM-NEXT: vst1.32 {[[LOAD]][1]}, [r1]388; ASM-NEXT: bx389define void @simpleOneInstructionPromotion4x32(ptr %addr1, ptr %dest) {390  %in1 = load <4 x i32>, ptr %addr1, align 8391  %extract = extractelement <4 x i32> %in1, i32 1392  %out = or i32 %extract, 1393  store i32 %out, ptr %dest, align 1394  ret void395}396