1; RUN: opt -S -instcombine < %s | FileCheck %s 2 3declare void @v4float_user(<4 x float>) #0 4 5 6 7define float @extract_one_select(<4 x float> %a, <4 x float> %b, i32 %c) #0 { 8; CHECK-LABEL: @extract_one_select( 9; CHECK-NOT: select i1 {{.*}}, <4 x float> 10 %cmp = icmp ne i32 %c, 0 11 %sel = select i1 %cmp, <4 x float> %a, <4 x float> %b 12 %extract = extractelement <4 x float> %sel, i32 2 13 ret float %extract 14} 15 16; Multiple extractelements 17define <2 x float> @extract_two_select(<4 x float> %a, <4 x float> %b, i32 %c) #0 { 18; CHECK-LABEL: @extract_two_select( 19; CHECK: select i1 {{.*}}, <4 x float> 20 %cmp = icmp ne i32 %c, 0 21 %sel = select i1 %cmp, <4 x float> %a, <4 x float> %b 22 %extract1 = extractelement <4 x float> %sel, i32 1 23 %extract2 = extractelement <4 x float> %sel, i32 2 24 %build1 = insertelement <2 x float> undef, float %extract1, i32 0 25 %build2 = insertelement <2 x float> %build1, float %extract2, i32 1 26 ret <2 x float> %build2 27} 28 29; Select has an extra non-extractelement user, don't change it 30define float @extract_one_select_user(<4 x float> %a, <4 x float> %b, i32 %c) #0 { 31; CHECK-LABEL: @extract_one_select_user( 32; CHECK: select i1 {{.*}}, <4 x float> 33 %cmp = icmp ne i32 %c, 0 34 %sel = select i1 %cmp, <4 x float> %a, <4 x float> %b 35 %extract = extractelement <4 x float> %sel, i32 2 36 call void @v4float_user(<4 x float> %sel) 37 ret float %extract 38} 39 40define float @extract_one_vselect_user(<4 x float> %a, <4 x float> %b, <4 x i32> %c) #0 { 41; CHECK-LABEL: @extract_one_vselect_user( 42; CHECK: select <4 x i1> {{.*}}, <4 x float> 43 %cmp = icmp ne <4 x i32> %c, zeroinitializer 44 %sel = select <4 x i1> %cmp, <4 x float> %a, <4 x float> %b 45 %extract = extractelement <4 x float> %sel, i32 2 46 call void @v4float_user(<4 x float> %sel) 47 ret float %extract 48} 49 50; Extract from a vector select 51define float @extract_one_vselect(<4 x float> %a, <4 x float> %b, <4 x i32> %c) #0 { 52; CHECK-LABEL: @extract_one_vselect( 53; CHECK-NOT: select <4 x i1> 54 %cmp = icmp ne <4 x i32> %c, zeroinitializer 55 %select = select <4 x i1> %cmp, <4 x float> %a, <4 x float> %b 56 %extract = extractelement <4 x float> %select, i32 0 57 ret float %extract 58} 59 60; Multiple extractelements from a vector select 61define <2 x float> @extract_two_vselect(<4 x float> %a, <4 x float> %b, <4 x i32> %c) #0 { 62; CHECK-LABEL: @extract_two_vselect( 63; CHECK-NOT: select i1 {{.*}}, <4 x float> 64 %cmp = icmp ne <4 x i32> %c, zeroinitializer 65 %sel = select <4 x i1> %cmp, <4 x float> %a, <4 x float> %b 66 %extract1 = extractelement <4 x float> %sel, i32 1 67 %extract2 = extractelement <4 x float> %sel, i32 2 68 %build1 = insertelement <2 x float> undef, float %extract1, i32 0 69 %build2 = insertelement <2 x float> %build1, float %extract2, i32 1 70 ret <2 x float> %build2 71} 72 73; All the vector selects should be decomposed into scalar selects 74; Test multiple extractelements 75define <4 x float> @simple_vector_select(<4 x float> %a, <4 x float> %b, <4 x i32> %c) #0 { 76; CHECK-LABEL: @simple_vector_select( 77; CHECK-NOT: select i1 {{.*}}, <4 x float> 78entry: 79 %0 = extractelement <4 x i32> %c, i32 0 80 %tobool = icmp ne i32 %0, 0 81 %a.sink = select i1 %tobool, <4 x float> %a, <4 x float> %b 82 %1 = extractelement <4 x float> %a.sink, i32 0 83 %2 = insertelement <4 x float> undef, float %1, i32 0 84 %3 = extractelement <4 x i32> %c, i32 1 85 %tobool1 = icmp ne i32 %3, 0 86 %a.sink1 = select i1 %tobool1, <4 x float> %a, <4 x float> %b 87 %4 = extractelement <4 x float> %a.sink1, i32 1 88 %5 = insertelement <4 x float> %2, float %4, i32 1 89 %6 = extractelement <4 x i32> %c, i32 2 90 %tobool6 = icmp ne i32 %6, 0 91 %a.sink2 = select i1 %tobool6, <4 x float> %a, <4 x float> %b 92 %7 = extractelement <4 x float> %a.sink2, i32 2 93 %8 = insertelement <4 x float> %5, float %7, i32 2 94 %9 = extractelement <4 x i32> %c, i32 3 95 %tobool11 = icmp ne i32 %9, 0 96 %a.sink3 = select i1 %tobool11, <4 x float> %a, <4 x float> %b 97 %10 = extractelement <4 x float> %a.sink3, i32 3 98 %11 = insertelement <4 x float> %8, float %10, i32 3 99 ret <4 x float> %11 100} 101 102attributes #0 = { nounwind ssp uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } 103