brintos

brintos / llvm-project-archived public Read only

0
0
Text · 16.1 KiB · c4adf75 Raw
442 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -passes=instcombine -S < %s | FileCheck %s3 4define i32 @extract_load(ptr %p) {5;6; CHECK-LABEL: @extract_load(7; CHECK-NEXT:    [[X:%.*]] = load <4 x i32>, ptr [[P:%.*]], align 48; CHECK-NEXT:    [[EXT:%.*]] = extractelement <4 x i32> [[X]], i64 19; CHECK-NEXT:    ret i32 [[EXT]]10;11  %x = load <4 x i32>, ptr %p, align 412  %ext = extractelement <4 x i32> %x, i32 113  ret i32 %ext14}15 16define double @extract_load_fp(ptr %p) {17;18; CHECK-LABEL: @extract_load_fp(19; CHECK-NEXT:    [[X:%.*]] = load <4 x double>, ptr [[P:%.*]], align 3220; CHECK-NEXT:    [[EXT:%.*]] = extractelement <4 x double> [[X]], i64 321; CHECK-NEXT:    ret double [[EXT]]22;23  %x = load <4 x double>, ptr %p, align 3224  %ext = extractelement <4 x double> %x, i32 325  ret double %ext26}27 28define double @extract_load_volatile(ptr %p) {29;30; CHECK-LABEL: @extract_load_volatile(31; CHECK-NEXT:    [[X:%.*]] = load volatile <4 x double>, ptr [[P:%.*]], align 3232; CHECK-NEXT:    [[EXT:%.*]] = extractelement <4 x double> [[X]], i64 233; CHECK-NEXT:    ret double [[EXT]]34;35  %x = load volatile <4 x double>, ptr %p36  %ext = extractelement <4 x double> %x, i32 237  ret double %ext38}39 40define double @extract_load_extra_use(ptr %p, ptr %p2) {41;42; CHECK-LABEL: @extract_load_extra_use(43; CHECK-NEXT:    [[X:%.*]] = load <4 x double>, ptr [[P:%.*]], align 844; CHECK-NEXT:    [[EXT:%.*]] = extractelement <4 x double> [[X]], i64 045; CHECK-NEXT:    store <4 x double> [[X]], ptr [[P2:%.*]], align 3246; CHECK-NEXT:    ret double [[EXT]]47;48  %x = load <4 x double>, ptr %p, align 849  %ext = extractelement <4 x double> %x, i32 050  store <4 x double> %x, ptr %p251  ret double %ext52}53 54define double @extract_load_variable_index(ptr %p, i32 %y) {55;56; CHECK-LABEL: @extract_load_variable_index(57; CHECK-NEXT:    [[X:%.*]] = load <4 x double>, ptr [[P:%.*]], align 3258; CHECK-NEXT:    [[EXT:%.*]] = extractelement <4 x double> [[X]], i32 [[Y:%.*]]59; CHECK-NEXT:    ret double [[EXT]]60;61  %x = load <4 x double>, ptr %p62  %ext = extractelement <4 x double> %x, i32 %y63  ret double %ext64}65 66define void @scalarize_phi(ptr %n, ptr %inout) {67;68; CHECK-LABEL: @scalarize_phi(69; CHECK-NEXT:  entry:70; CHECK-NEXT:    [[T0:%.*]] = load volatile float, ptr [[INOUT:%.*]], align 471; CHECK-NEXT:    br label [[FOR_COND:%.*]]72; CHECK:       for.cond:73; CHECK-NEXT:    [[TMP0:%.*]] = phi float [ [[T0]], [[ENTRY:%.*]] ], [ [[TMP1:%.*]], [[FOR_BODY:%.*]] ]74; CHECK-NEXT:    [[I_0:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[INC:%.*]], [[FOR_BODY]] ]75; CHECK-NEXT:    [[T1:%.*]] = load i32, ptr [[N:%.*]], align 476; CHECK-NEXT:    [[CMP_NOT:%.*]] = icmp eq i32 [[I_0]], [[T1]]77; CHECK-NEXT:    br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]78; CHECK:       for.body:79; CHECK-NEXT:    store volatile float [[TMP0]], ptr [[INOUT]], align 480; CHECK-NEXT:    [[TMP1]] = fmul float [[TMP0]], 0x4002A3D70000000081; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[I_0]], 182; CHECK-NEXT:    br label [[FOR_COND]]83; CHECK:       for.end:84; CHECK-NEXT:    ret void85;86entry:87  %t0 = load volatile float, ptr %inout, align 488  %insert = insertelement <4 x float> undef, float %t0, i32 089  %splat = shufflevector <4 x float> %insert, <4 x float> undef, <4 x i32> zeroinitializer90  %insert1 = insertelement <4 x float> undef, float 3.0, i32 091  br label %for.cond92 93for.cond:94  %x.0 = phi <4 x float> [ %splat, %entry ], [ %mul, %for.body ]95  %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.body ]96  %t1 = load i32, ptr %n, align 497  %cmp = icmp ne i32 %i.0, %t198  br i1 %cmp, label %for.body, label %for.end99 100for.body:101  %t2 = extractelement <4 x float> %x.0, i32 1102  store volatile float %t2, ptr %inout, align 4103  %mul = fmul <4 x float> %x.0, <float 0x4002A3D700000000, float 0x4002A3D700000000, float 0x4002A3D700000000, float 0x4002A3D700000000>104  %inc = add nsw i32 %i.0, 1105  br label %for.cond106 107for.end:108  ret void109}110 111define void @scalarize_phi_sub(ptr %n, ptr %inout) {112;113; CHECK-LABEL: @scalarize_phi_sub(114; CHECK-NEXT:  entry:115; CHECK-NEXT:    [[T0:%.*]] = load volatile float, ptr [[INOUT:%.*]], align 4116; CHECK-NEXT:    br label [[FOR_COND:%.*]]117; CHECK:       for.cond:118; CHECK-NEXT:    [[TMP0:%.*]] = phi float [ [[T0]], [[ENTRY:%.*]] ], [ [[TMP1:%.*]], [[FOR_BODY:%.*]] ]119; CHECK-NEXT:    [[I_0:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[INC:%.*]], [[FOR_BODY]] ]120; CHECK-NEXT:    [[T1:%.*]] = load i32, ptr [[N:%.*]], align 4121; CHECK-NEXT:    [[CMP_NOT:%.*]] = icmp eq i32 [[I_0]], [[T1]]122; CHECK-NEXT:    br i1 [[CMP_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]123; CHECK:       for.body:124; CHECK-NEXT:    store volatile float [[TMP0]], ptr [[INOUT]], align 4125; CHECK-NEXT:    [[TMP1]] = fsub float 0.000000e+00, [[TMP0]]126; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[I_0]], 1127; CHECK-NEXT:    br label [[FOR_COND]]128; CHECK:       for.end:129; CHECK-NEXT:    ret void130;131entry:132  %t0 = load volatile float, ptr %inout, align 4133  %insert = insertelement <4 x float> poison, float %t0, i32 0134  %splat = shufflevector <4 x float> %insert, <4 x float> poison, <4 x i32> zeroinitializer135  br label %for.cond136 137for.cond:138  %x.0 = phi <4 x float> [ %splat, %entry ], [ %sub, %for.body ]139  %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.body ]140  %t1 = load i32, ptr %n, align 4141  %cmp = icmp ne i32 %i.0, %t1142  br i1 %cmp, label %for.body, label %for.end143 144for.body:145  %t2 = extractelement <4 x float> %x.0, i32 1146  store volatile float %t2, ptr %inout, align 4147  %sub = fsub <4 x float> zeroinitializer, %x.0148  %inc = add nsw i32 %i.0, 1149  br label %for.cond150 151for.end:152  ret void153}154 155define float @extract_element_binop_splat_constant_index(<4 x float> %x) {156;157; CHECK-LABEL: @extract_element_binop_splat_constant_index(158; CHECK-NEXT:    [[TMP1:%.*]] = extractelement <4 x float> [[X:%.*]], i64 2159; CHECK-NEXT:    [[R:%.*]] = fadd float [[TMP1]], 0x4002A3D700000000160; CHECK-NEXT:    ret float [[R]]161;162  %b = fadd <4 x float> %x, <float 0x4002A3D700000000, float 0x4002A3D700000000, float 0x4002A3D700000000, float 0x4002A3D700000000>163  %r = extractelement <4 x float> %b, i32 2164  ret float %r165}166 167define double @extract_element_binop_splat_with_undef_constant_index(<2 x double> %x) {168;169; CHECK-LABEL: @extract_element_binop_splat_with_undef_constant_index(170; CHECK-NEXT:    [[TMP1:%.*]] = extractelement <2 x double> [[X:%.*]], i64 0171; CHECK-NEXT:    [[R:%.*]] = fdiv double 4.200000e+01, [[TMP1]]172; CHECK-NEXT:    ret double [[R]]173;174  %b = fdiv <2 x double> <double 42.0, double undef>, %x175  %r = extractelement <2 x double> %b, i32 0176  ret double %r177}178 179define float @extract_element_binop_nonsplat_constant_index(<2 x float> %x) {180;181; CHECK-LABEL: @extract_element_binop_nonsplat_constant_index(182; CHECK-NEXT:    [[TMP1:%.*]] = extractelement <2 x float> [[X:%.*]], i64 1183; CHECK-NEXT:    [[R:%.*]] = fmul float [[TMP1]], 4.300000e+01184; CHECK-NEXT:    ret float [[R]]185;186  %b = fmul <2 x float> %x, <float 42.0, float 43.0>187  %r = extractelement <2 x float> %b, i32 1188  ret float %r189}190 191define i8 @extract_element_binop_splat_variable_index(<4 x i8> %x, i32 %y) {192;193; CHECK-LABEL: @extract_element_binop_splat_variable_index(194; CHECK-NEXT:    [[TMP1:%.*]] = extractelement <4 x i8> [[X:%.*]], i32 [[Y:%.*]]195; CHECK-NEXT:    [[R:%.*]] = sdiv i8 [[TMP1]], 42196; CHECK-NEXT:    ret i8 [[R]]197;198  %b = sdiv <4 x i8> %x, <i8 42, i8 42, i8 42, i8 42>199  %r = extractelement <4 x i8> %b, i32 %y200  ret i8 %r201}202 203; We cannot move the extractelement before the sdiv here, because %z may be204; out of range, making the divisor poison and resulting in immediate UB.205define i8 @extract_element_binop_splat_variable_index_may_trap(<4 x i8> %x, <4 x i8> %y, i32 %z) {206;207; CHECK-LABEL: @extract_element_binop_splat_variable_index_may_trap(208; CHECK-NEXT:    [[B:%.*]] = sdiv <4 x i8> splat (i8 42), [[Y:%.*]]209; CHECK-NEXT:    [[R:%.*]] = extractelement <4 x i8> [[B]], i32 [[Z:%.*]]210; CHECK-NEXT:    ret i8 [[R]]211;212  %b = sdiv <4 x i8> splat (i8 42), %y213  %r = extractelement <4 x i8> %b, i32 %z214  ret i8 %r215}216 217; Moving the extractelement first is fine here, because the index is known to218; be valid, so we can't introduce additional poison.219define i8 @extract_element_binop_constant_index_may_trap(<4 x i8> %x, <4 x i8> %y, i32 %z) {220;221; CHECK-LABEL: @extract_element_binop_constant_index_may_trap(222; CHECK-NEXT:    [[TMP1:%.*]] = extractelement <4 x i8> [[Y:%.*]], i64 3223; CHECK-NEXT:    [[R:%.*]] = sdiv i8 42, [[TMP1]]224; CHECK-NEXT:    ret i8 [[R]]225;226  %b = sdiv <4 x i8> splat (i8 42), %y227  %r = extractelement <4 x i8> %b, i32 3228  ret i8 %r229}230 231define i8 @extract_element_binop_splat_with_undef_variable_index(<4 x i8> %x, i32 %y) {232;233; CHECK-LABEL: @extract_element_binop_splat_with_undef_variable_index(234; CHECK-NEXT:    [[B:%.*]] = mul <4 x i8> [[X:%.*]], <i8 42, i8 42, i8 undef, i8 42>235; CHECK-NEXT:    [[R:%.*]] = extractelement <4 x i8> [[B]], i32 [[Y:%.*]]236; CHECK-NEXT:    ret i8 [[R]]237;238  %b = mul <4 x i8> %x, <i8 42, i8 42, i8 undef, i8 42>239  %r = extractelement <4 x i8> %b, i32 %y240  ret i8 %r241}242 243define i8 @extract_element_binop_nonsplat_variable_index(<4 x i8> %x, i32 %y) {244;245; CHECK-LABEL: @extract_element_binop_nonsplat_variable_index(246; CHECK-NEXT:    [[B:%.*]] = lshr <4 x i8> [[X:%.*]], <i8 4, i8 3, i8 undef, i8 2>247; CHECK-NEXT:    [[R:%.*]] = extractelement <4 x i8> [[B]], i32 [[Y:%.*]]248; CHECK-NEXT:    ret i8 [[R]]249;250  %b = lshr <4 x i8> %x, <i8 4, i8 3, i8 undef, i8 2>251  %r = extractelement <4 x i8> %b, i32 %y252  ret i8 %r253}254 255define float @extract_element_load(<4 x float> %x, ptr %ptr) {256;257; CHECK-LABEL: @extract_element_load(258; CHECK-NEXT:    [[LOAD:%.*]] = load <4 x float>, ptr [[PTR:%.*]], align 16259; CHECK-NEXT:    [[TMP1:%.*]] = extractelement <4 x float> [[X:%.*]], i64 2260; CHECK-NEXT:    [[TMP2:%.*]] = extractelement <4 x float> [[LOAD]], i64 2261; CHECK-NEXT:    [[R:%.*]] = fadd float [[TMP1]], [[TMP2]]262; CHECK-NEXT:    ret float [[R]]263;264  %load = load <4 x float>, ptr %ptr265  %add = fadd <4 x float> %x, %load266  %r = extractelement <4 x float> %add, i32 2267  ret float %r268}269 270define float @extract_element_multi_Use_load(<4 x float> %x, ptr %ptr0, ptr %ptr1) {271;272; CHECK-LABEL: @extract_element_multi_Use_load(273; CHECK-NEXT:    [[LOAD:%.*]] = load <4 x float>, ptr [[PTR0:%.*]], align 16274; CHECK-NEXT:    store <4 x float> [[LOAD]], ptr [[PTR1:%.*]], align 16275; CHECK-NEXT:    [[ADD:%.*]] = fadd <4 x float> [[X:%.*]], [[LOAD]]276; CHECK-NEXT:    [[R:%.*]] = extractelement <4 x float> [[ADD]], i64 2277; CHECK-NEXT:    ret float [[R]]278;279  %load = load <4 x float>, ptr %ptr0280  store <4 x float> %load, ptr %ptr1281  %add = fadd <4 x float> %x, %load282  %r = extractelement <4 x float> %add, i32 2283  ret float %r284}285 286define float @extract_element_variable_index(<4 x float> %x, i32 %y) {287;288; CHECK-LABEL: @extract_element_variable_index(289; CHECK-NEXT:    [[TMP1:%.*]] = extractelement <4 x float> [[X:%.*]], i32 [[Y:%.*]]290; CHECK-NEXT:    [[R:%.*]] = fadd float [[TMP1]], 1.000000e+00291; CHECK-NEXT:    ret float [[R]]292;293  %add = fadd <4 x float> %x, <float 1.0, float 1.0, float 1.0, float 1.0>294  %r = extractelement <4 x float> %add, i32 %y295  ret float %r296}297 298define float @extelt_binop_insertelt(<4 x float> %A, <4 x float> %B, float %f) {299;300; CHECK-LABEL: @extelt_binop_insertelt(301; CHECK-NEXT:    [[TMP1:%.*]] = extractelement <4 x float> [[B:%.*]], i64 0302; CHECK-NEXT:    [[E:%.*]] = fmul nnan float [[F:%.*]], [[TMP1]]303; CHECK-NEXT:    ret float [[E]]304;305  %C = insertelement <4 x float> %A, float %f, i32 0306  %D = fmul nnan <4 x float> %C, %B307  %E = extractelement <4 x float> %D, i32 0308  ret float %E309}310 311; We recurse to find a scalarizable operand.312define i32 @extelt_binop_binop_insertelt(<4 x i32> %A, <4 x i32> %B, i32 %f) {313;314; CHECK-LABEL: @extelt_binop_binop_insertelt(315; CHECK-NEXT:    [[TMP1:%.*]] = extractelement <4 x i32> [[B:%.*]], i64 0316; CHECK-NEXT:    [[TMP2:%.*]] = add i32 [[F:%.*]], [[TMP1]]317; CHECK-NEXT:    [[TMP3:%.*]] = extractelement <4 x i32> [[B]], i64 0318; CHECK-NEXT:    [[E:%.*]] = mul nsw i32 [[TMP2]], [[TMP3]]319; CHECK-NEXT:    ret i32 [[E]]320;321  %v = insertelement <4 x i32> %A, i32 %f, i32 0322  %C = add <4 x i32> %v, %B323  %D = mul nsw <4 x i32> %C, %B324  %E = extractelement <4 x i32> %D, i32 0325  ret i32 %E326}327 328define float @extract_element_constant_vector_variable_index(i32 %y) {329;330; CHECK-LABEL: @extract_element_constant_vector_variable_index(331; CHECK-NEXT:    [[R:%.*]] = extractelement <4 x float> <float 1.000000e+00, float 2.000000e+00, float 3.000000e+00, float 4.000000e+00>, i32 [[Y:%.*]]332; CHECK-NEXT:    ret float [[R]]333;334  %r = extractelement <4 x float> <float 1.0, float 2.0, float 3.0, float 4.0>, i32 %y335  ret float %r336}337 338define i1 @cheap_to_extract_icmp(<4 x i32> %x, <4 x i1> %y) {339;340; CHECK-LABEL: @cheap_to_extract_icmp(341; CHECK-NEXT:    [[TMP1:%.*]] = extractelement <4 x i32> [[X:%.*]], i64 2342; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0343; CHECK-NEXT:    [[TMP3:%.*]] = extractelement <4 x i1> [[Y:%.*]], i64 2344; CHECK-NEXT:    [[R:%.*]] = and i1 [[TMP2]], [[TMP3]]345; CHECK-NEXT:    ret i1 [[R]]346;347  %cmp = icmp eq <4 x i32> %x, zeroinitializer348  %and = and <4 x i1> %cmp, %y349  %r = extractelement <4 x i1> %and, i32 2350  ret i1 %r351}352 353define i1 @cheap_to_extract_fcmp(<4 x float> %x, <4 x i1> %y) {354;355; CHECK-LABEL: @cheap_to_extract_fcmp(356; CHECK-NEXT:    [[TMP1:%.*]] = extractelement <4 x float> [[X:%.*]], i64 2357; CHECK-NEXT:    [[TMP2:%.*]] = fcmp oeq float [[TMP1]], 0.000000e+00358; CHECK-NEXT:    [[TMP3:%.*]] = extractelement <4 x i1> [[Y:%.*]], i64 2359; CHECK-NEXT:    [[R:%.*]] = and i1 [[TMP2]], [[TMP3]]360; CHECK-NEXT:    ret i1 [[R]]361;362  %cmp = fcmp oeq <4 x float> %x, zeroinitializer363  %and = and <4 x i1> %cmp, %y364  %r = extractelement <4 x i1> %and, i32 2365  ret i1 %r366}367 368define i1 @extractelt_vector_icmp_constrhs(<2 x i32> %arg) {369;370; CHECK-LABEL: @extractelt_vector_icmp_constrhs(371; CHECK-NEXT:    [[TMP1:%.*]] = extractelement <2 x i32> [[ARG:%.*]], i64 0372; CHECK-NEXT:    [[EXT:%.*]] = icmp eq i32 [[TMP1]], 0373; CHECK-NEXT:    ret i1 [[EXT]]374;375  %cmp = icmp eq <2 x i32> %arg, zeroinitializer376  %ext = extractelement <2 x i1> %cmp, i32 0377  ret i1 %ext378}379 380define i1 @extractelt_vector_fcmp_constrhs(<2 x float> %arg) {381;382; CHECK-LABEL: @extractelt_vector_fcmp_constrhs(383; CHECK-NEXT:    [[TMP1:%.*]] = extractelement <2 x float> [[ARG:%.*]], i64 0384; CHECK-NEXT:    [[EXT:%.*]] = fcmp oeq float [[TMP1]], 0.000000e+00385; CHECK-NEXT:    ret i1 [[EXT]]386;387  %cmp = fcmp oeq <2 x float> %arg, zeroinitializer388  %ext = extractelement <2 x i1> %cmp, i32 0389  ret i1 %ext390}391 392define i1 @extractelt_vector_icmp_constrhs_dynidx(<2 x i32> %arg, i32 %idx) {393;394; CHECK-LABEL: @extractelt_vector_icmp_constrhs_dynidx(395; CHECK-NEXT:    [[TMP1:%.*]] = extractelement <2 x i32> [[ARG:%.*]], i32 [[IDX:%.*]]396; CHECK-NEXT:    [[EXT:%.*]] = icmp eq i32 [[TMP1]], 0397; CHECK-NEXT:    ret i1 [[EXT]]398;399  %cmp = icmp eq <2 x i32> %arg, zeroinitializer400  %ext = extractelement <2 x i1> %cmp, i32 %idx401  ret i1 %ext402}403 404define i1 @extractelt_vector_fcmp_constrhs_dynidx(<2 x float> %arg, i32 %idx) {405;406; CHECK-LABEL: @extractelt_vector_fcmp_constrhs_dynidx(407; CHECK-NEXT:    [[TMP1:%.*]] = extractelement <2 x float> [[ARG:%.*]], i32 [[IDX:%.*]]408; CHECK-NEXT:    [[EXT:%.*]] = fcmp oeq float [[TMP1]], 0.000000e+00409; CHECK-NEXT:    ret i1 [[EXT]]410;411  %cmp = fcmp oeq <2 x float> %arg, zeroinitializer412  %ext = extractelement <2 x i1> %cmp, i32 %idx413  ret i1 %ext414}415 416define i1 @extractelt_vector_fcmp_copy_flags(<4 x float> %x) {417; CHECK-LABEL: @extractelt_vector_fcmp_copy_flags(418; CHECK-NEXT:    [[TMP1:%.*]] = extractelement <4 x float> [[X:%.*]], i64 2419; CHECK-NEXT:    [[R:%.*]] = fcmp nsz arcp oeq float [[TMP1]], 0.000000e+00420; CHECK-NEXT:    ret i1 [[R]]421;422  %cmp = fcmp nsz arcp oeq <4 x float> %x, zeroinitializer423  %r = extractelement <4 x i1> %cmp, i32 2424  ret i1 %r425}426 427define i1 @extractelt_vector_fcmp_not_cheap_to_scalarize_multi_use(<2 x float> %arg0, <2 x float> %arg1, <2 x float> %arg2, i32 %idx) {428;429; CHECK-LABEL: @extractelt_vector_fcmp_not_cheap_to_scalarize_multi_use(430; CHECK-NEXT:    [[ADD:%.*]] = fadd <2 x float> [[ARG1:%.*]], [[ARG2:%.*]]431; CHECK-NEXT:    store volatile <2 x float> [[ADD]], ptr undef, align 8432; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq <2 x float> [[ARG0:%.*]], [[ADD]]433; CHECK-NEXT:    [[EXT:%.*]] = extractelement <2 x i1> [[CMP]], i64 0434; CHECK-NEXT:    ret i1 [[EXT]]435;436  %add = fadd <2 x float> %arg1, %arg2437  store volatile <2 x float> %add, ptr undef438  %cmp = fcmp oeq <2 x float> %arg0, %add439  %ext = extractelement <2 x i1> %cmp, i32 0440  ret i1 %ext441}442