273 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4declare void @use(<4 x i16>)5 6define void @test(<16 x i8> %w, ptr %o1, ptr %o2) {7; CHECK-LABEL: @test(8; CHECK-NEXT: [[V_BC:%.*]] = bitcast <16 x i8> [[W:%.*]] to <4 x i32>9; CHECK-NEXT: [[V_EXTRACT:%.*]] = extractelement <4 x i32> [[V_BC]], i64 310; CHECK-NEXT: [[V_BC1:%.*]] = bitcast <16 x i8> [[W]] to <4 x float>11; CHECK-NEXT: [[V_EXTRACT2:%.*]] = extractelement <4 x float> [[V_BC1]], i64 312; CHECK-NEXT: store i32 [[V_EXTRACT]], ptr [[O1:%.*]], align 413; CHECK-NEXT: store float [[V_EXTRACT2]], ptr [[O2:%.*]], align 414; CHECK-NEXT: ret void15;16 %v = shufflevector <16 x i8> %w, <16 x i8> undef, <4 x i32> <i32 12, i32 13, i32 14, i32 15>17 %f = bitcast <4 x i8> %v to float18 %i = bitcast <4 x i8> %v to i3219 store i32 %i, ptr %o1, align 420 store float %f, ptr %o2, align 421 ret void22}23 24; Shuffle-of-bitcast-splat --> splat-bitcast25 26define <4 x i16> @splat_bitcast_operand(<8 x i8> %x) {27; CHECK-LABEL: @splat_bitcast_operand(28; CHECK-NEXT: [[S1:%.*]] = shufflevector <8 x i8> [[X:%.*]], <8 x i8> poison, <8 x i32> <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>29; CHECK-NEXT: [[S2:%.*]] = bitcast <8 x i8> [[S1]] to <4 x i16>30; CHECK-NEXT: ret <4 x i16> [[S2]]31;32 %s1 = shufflevector <8 x i8> %x, <8 x i8> undef, <8 x i32> <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>33 %bc = bitcast <8 x i8> %s1 to <4 x i16>34 %s2 = shufflevector <4 x i16> %bc, <4 x i16> undef, <4 x i32> <i32 0, i32 2, i32 1, i32 0>35 ret <4 x i16> %s236}37 38; Shuffle-of-bitcast-splat --> splat-bitcast39 40define <4 x i16> @splat_bitcast_operand_uses(<8 x i8> %x) {41; CHECK-LABEL: @splat_bitcast_operand_uses(42; CHECK-NEXT: [[S1:%.*]] = shufflevector <8 x i8> [[X:%.*]], <8 x i8> poison, <8 x i32> <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>43; CHECK-NEXT: [[BC:%.*]] = bitcast <8 x i8> [[S1]] to <4 x i16>44; CHECK-NEXT: call void @use(<4 x i16> [[BC]])45; CHECK-NEXT: [[S2:%.*]] = bitcast <8 x i8> [[S1]] to <4 x i16>46; CHECK-NEXT: ret <4 x i16> [[S2]]47;48 %s1 = shufflevector <8 x i8> %x, <8 x i8> undef, <8 x i32> <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>49 %bc = bitcast <8 x i8> %s1 to <4 x i16>50 call void @use(<4 x i16> %bc)51 %s2 = shufflevector <4 x i16> %bc, <4 x i16> undef, <4 x i32> <i32 0, i32 2, i32 1, i32 0>52 ret <4 x i16> %s253}54 55; Shuffle-of-bitcast-splat --> splat-bitcast56 57define <4 x i32> @splat_bitcast_operand_same_size_src_elt(<4 x float> %x) {58; CHECK-LABEL: @splat_bitcast_operand_same_size_src_elt(59; CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x float> [[X:%.*]] to <4 x i32>60; CHECK-NEXT: [[BC:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <4 x i32> <i32 2, i32 2, i32 2, i32 2>61; CHECK-NEXT: ret <4 x i32> [[BC]]62;63 %s1 = shufflevector <4 x float> %x, <4 x float> undef, <4 x i32> <i32 2, i32 2, i32 2, i32 2>64 %bc = bitcast <4 x float> %s1 to <4 x i32>65 %s2 = shufflevector <4 x i32> %bc, <4 x i32> undef, <4 x i32> <i32 0, i32 2, i32 1, i32 0>66 ret <4 x i32> %s267}68 69; Scaled mask is inverse of first mask.70 71define <4 x i32> @shuf_bitcast_operand(<16 x i8> %x) {72; CHECK-LABEL: @shuf_bitcast_operand(73; CHECK-NEXT: [[S2:%.*]] = bitcast <16 x i8> [[X:%.*]] to <4 x i32>74; CHECK-NEXT: ret <4 x i32> [[S2]]75;76 %s1 = shufflevector <16 x i8> %x, <16 x i8> undef, <16 x i32> <i32 12, i32 13, i32 14, i32 15, i32 8, i32 9, i32 10, i32 11, i32 4, i32 5, i32 6, i32 7, i32 0, i32 1, i32 2, i32 3>77 %bc = bitcast <16 x i8> %s1 to <4 x i32>78 %s2 = shufflevector <4 x i32> %bc, <4 x i32> undef, <4 x i32> <i32 3, i32 2, i32 1, i32 0>79 ret <4 x i32> %s280}81 82; TODO: Could allow fold for length-changing shuffles.83 84define <5 x i16> @splat_bitcast_operand_change_type(<8 x i8> %x) {85; CHECK-LABEL: @splat_bitcast_operand_change_type(86; CHECK-NEXT: [[S1:%.*]] = shufflevector <8 x i8> [[X:%.*]], <8 x i8> poison, <8 x i32> <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>87; CHECK-NEXT: [[BC:%.*]] = bitcast <8 x i8> [[S1]] to <4 x i16>88; CHECK-NEXT: [[S2:%.*]] = shufflevector <4 x i16> [[BC]], <4 x i16> poison, <5 x i32> <i32 0, i32 2, i32 1, i32 0, i32 3>89; CHECK-NEXT: ret <5 x i16> [[S2]]90;91 %s1 = shufflevector <8 x i8> %x, <8 x i8> undef, <8 x i32> <i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>92 %bc = bitcast <8 x i8> %s1 to <4 x i16>93 %s2 = shufflevector <4 x i16> %bc, <4 x i16> undef, <5 x i32> <i32 0, i32 2, i32 1, i32 0, i32 3>94 ret <5 x i16> %s295}96 97; Shuffle-of-bitcast-splat --> splat-bitcast98 99define <4 x i16> @splat_bitcast_operand_wider_src_elt(<2 x i32> %x) {100; CHECK-LABEL: @splat_bitcast_operand_wider_src_elt(101; CHECK-NEXT: [[S1:%.*]] = shufflevector <2 x i32> [[X:%.*]], <2 x i32> poison, <2 x i32> <i32 1, i32 1>102; CHECK-NEXT: [[S2:%.*]] = bitcast <2 x i32> [[S1]] to <4 x i16>103; CHECK-NEXT: ret <4 x i16> [[S2]]104;105 %s1 = shufflevector <2 x i32> %x, <2 x i32> undef, <2 x i32> <i32 1, i32 1>106 %bc = bitcast <2 x i32> %s1 to <4 x i16>107 %s2 = shufflevector <4 x i16> %bc, <4 x i16> undef, <4 x i32> <i32 0, i32 1, i32 0, i32 1>108 ret <4 x i16> %s2109}110 111; Shuffle-of-bitcast-splat --> splat-bitcast112 113define <4 x i16> @splat_bitcast_operand_wider_src_elt_uses(<2 x i32> %x) {114; CHECK-LABEL: @splat_bitcast_operand_wider_src_elt_uses(115; CHECK-NEXT: [[S1:%.*]] = shufflevector <2 x i32> [[X:%.*]], <2 x i32> poison, <2 x i32> <i32 1, i32 1>116; CHECK-NEXT: [[BC:%.*]] = bitcast <2 x i32> [[S1]] to <4 x i16>117; CHECK-NEXT: call void @use(<4 x i16> [[BC]])118; CHECK-NEXT: [[S2:%.*]] = bitcast <2 x i32> [[S1]] to <4 x i16>119; CHECK-NEXT: ret <4 x i16> [[S2]]120;121 %s1 = shufflevector <2 x i32> %x, <2 x i32> undef, <2 x i32> <i32 1, i32 1>122 %bc = bitcast <2 x i32> %s1 to <4 x i16>123 call void @use(<4 x i16> %bc)124 %s2 = shufflevector <4 x i16> %bc, <4 x i16> undef, <4 x i32> <i32 0, i32 1, i32 0, i32 1>125 ret <4 x i16> %s2126}127 128; Scaled mask is inverse of first mask.129 130define <16 x i8> @shuf_bitcast_operand_wider_src(<4 x i32> %x) {131; CHECK-LABEL: @shuf_bitcast_operand_wider_src(132; CHECK-NEXT: [[S2:%.*]] = bitcast <4 x i32> [[X:%.*]] to <16 x i8>133; CHECK-NEXT: ret <16 x i8> [[S2]]134;135 %s1 = shufflevector <4 x i32> %x, <4 x i32> undef, <4 x i32> <i32 3, i32 2, i32 1, i32 0>136 %bc = bitcast <4 x i32> %s1 to <16 x i8>137 %s2 = shufflevector <16 x i8> %bc, <16 x i8> undef, <16 x i32> <i32 12, i32 13, i32 14, i32 15, i32 8, i32 9, i32 10, i32 11, i32 4, i32 5, i32 6, i32 7, i32 0, i32 1, i32 2, i32 3>138 ret <16 x i8> %s2139}140 141; Negative test - the 2nd mask can't be widened142 143define <16 x i8> @shuf_bitcast_operand_cannot_widen(<4 x i32> %x) {144; CHECK-LABEL: @shuf_bitcast_operand_cannot_widen(145; CHECK-NEXT: [[S1:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> poison, <4 x i32> <i32 3, i32 2, i32 1, i32 0>146; CHECK-NEXT: [[BC:%.*]] = bitcast <4 x i32> [[S1]] to <16 x i8>147; CHECK-NEXT: [[S2:%.*]] = shufflevector <16 x i8> [[BC]], <16 x i8> poison, <16 x i32> <i32 12, i32 13, i32 12, i32 13, i32 8, i32 9, i32 10, i32 11, i32 4, i32 5, i32 6, i32 7, i32 0, i32 1, i32 2, i32 3>148; CHECK-NEXT: ret <16 x i8> [[S2]]149;150 %s1 = shufflevector <4 x i32> %x, <4 x i32> undef, <4 x i32> <i32 3, i32 2, i32 1, i32 0>151 %bc = bitcast <4 x i32> %s1 to <16 x i8>152 %s2 = shufflevector <16 x i8> %bc, <16 x i8> undef, <16 x i32> <i32 12, i32 13, i32 12, i32 13, i32 8, i32 9, i32 10, i32 11, i32 4, i32 5, i32 6, i32 7, i32 0, i32 1, i32 2, i32 3>153 ret <16 x i8> %s2154}155 156; Negative test - the 2nd mask can't be widened157 158define <16 x i8> @shuf_bitcast_operand_cannot_widen_undef(<4 x i32> %x) {159; CHECK-LABEL: @shuf_bitcast_operand_cannot_widen_undef(160; CHECK-NEXT: [[S1:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> poison, <4 x i32> <i32 3, i32 2, i32 1, i32 0>161; CHECK-NEXT: [[BC:%.*]] = bitcast <4 x i32> [[S1]] to <16 x i8>162; CHECK-NEXT: [[S2:%.*]] = shufflevector <16 x i8> [[BC]], <16 x i8> poison, <16 x i32> <i32 12, i32 poison, i32 14, i32 15, i32 8, i32 9, i32 10, i32 11, i32 4, i32 5, i32 6, i32 7, i32 0, i32 1, i32 2, i32 3>163; CHECK-NEXT: ret <16 x i8> [[S2]]164;165 %s1 = shufflevector <4 x i32> %x, <4 x i32> undef, <4 x i32> <i32 3, i32 2, i32 1, i32 0>166 %bc = bitcast <4 x i32> %s1 to <16 x i8>167 %s2 = shufflevector <16 x i8> %bc, <16 x i8> undef, <16 x i32> <i32 12, i32 undef, i32 14, i32 15, i32 8, i32 9, i32 10, i32 11, i32 4, i32 5, i32 6, i32 7, i32 0, i32 1, i32 2, i32 3>168 ret <16 x i8> %s2169}170 171define <2 x i4> @shuf_bitcast_insert(<2 x i8> %v, i8 %x) {172; CHECK-LABEL: @shuf_bitcast_insert(173; CHECK-NEXT: [[R:%.*]] = bitcast i8 [[X:%.*]] to <2 x i4>174; CHECK-NEXT: ret <2 x i4> [[R]]175;176 %i = insertelement <2 x i8> %v, i8 %x, i32 0177 %b = bitcast <2 x i8> %i to <4 x i4>178 %r = shufflevector <4 x i4> %b, <4 x i4> undef, <2 x i32> <i32 0, i32 1>179 ret <2 x i4> %r180}181 182define <2 x i4> @shuf_bitcast_inserti_use1(<2 x i8> %v, i8 %x, ptr %p) {183; CHECK-LABEL: @shuf_bitcast_inserti_use1(184; CHECK-NEXT: [[I:%.*]] = insertelement <2 x i8> [[V:%.*]], i8 [[X:%.*]], i64 0185; CHECK-NEXT: store <2 x i8> [[I]], ptr [[P:%.*]], align 2186; CHECK-NEXT: [[R:%.*]] = bitcast i8 [[X]] to <2 x i4>187; CHECK-NEXT: ret <2 x i4> [[R]]188;189 %i = insertelement <2 x i8> %v, i8 %x, i32 0190 store <2 x i8> %i, ptr %p191 %b = bitcast <2 x i8> %i to <4 x i4>192 %r = shufflevector <4 x i4> %b, <4 x i4> undef, <2 x i32> <i32 0, i32 1>193 ret <2 x i4> %r194}195 196define <2 x i4> @shuf_bitcast_insert_use2(<2 x i8> %v, i8 %x, ptr %p) {197; CHECK-LABEL: @shuf_bitcast_insert_use2(198; CHECK-NEXT: [[I:%.*]] = insertelement <2 x i8> [[V:%.*]], i8 [[X:%.*]], i64 0199; CHECK-NEXT: store <2 x i8> [[I]], ptr [[P:%.*]], align 2200; CHECK-NEXT: [[R:%.*]] = bitcast i8 [[X]] to <2 x i4>201; CHECK-NEXT: ret <2 x i4> [[R]]202;203 %i = insertelement <2 x i8> %v, i8 %x, i32 0204 %b = bitcast <2 x i8> %i to <4 x i4>205 store <4 x i4> %b, ptr %p206 %r = shufflevector <4 x i4> %b, <4 x i4> undef, <2 x i32> <i32 0, i32 1>207 ret <2 x i4> %r208}209 210; negative test - but demanded elements reduces this.211 212define <2 x i4> @shuf_bitcast_insert_wrong_index(<2 x i8> %v, i8 %x) {213; CHECK-LABEL: @shuf_bitcast_insert_wrong_index(214; CHECK-NEXT: [[B:%.*]] = bitcast <2 x i8> [[V:%.*]] to <4 x i4>215; CHECK-NEXT: [[R:%.*]] = shufflevector <4 x i4> [[B]], <4 x i4> poison, <2 x i32> <i32 0, i32 1>216; CHECK-NEXT: ret <2 x i4> [[R]]217;218 %i = insertelement <2 x i8> %v, i8 %x, i32 1219 %b = bitcast <2 x i8> %i to <4 x i4>220 %r = shufflevector <4 x i4> %b, <4 x i4> undef, <2 x i32> <i32 0, i32 1>221 ret <2 x i4> %r222}223 224; negative test225 226define <3 x i4> @shuf_bitcast_wrong_size(<2 x i8> %v, i8 %x) {227; CHECK-LABEL: @shuf_bitcast_wrong_size(228; CHECK-NEXT: [[I:%.*]] = insertelement <2 x i8> [[V:%.*]], i8 [[X:%.*]], i64 0229; CHECK-NEXT: [[B:%.*]] = bitcast <2 x i8> [[I]] to <4 x i4>230; CHECK-NEXT: [[R:%.*]] = shufflevector <4 x i4> [[B]], <4 x i4> poison, <3 x i32> <i32 0, i32 1, i32 2>231; CHECK-NEXT: ret <3 x i4> [[R]]232;233 %i = insertelement <2 x i8> %v, i8 %x, i32 0234 %b = bitcast <2 x i8> %i to <4 x i4>235 %r = shufflevector <4 x i4> %b, <4 x i4> undef, <3 x i32> <i32 0, i32 1, i32 2>236 ret <3 x i4> %r237}238 239; Negative test - chain of bitcasts.240 241define <16 x i8> @shuf_bitcast_chain(<8 x i32> %v) {242; CHECK-LABEL: @shuf_bitcast_chain(243; CHECK-NEXT: [[S:%.*]] = shufflevector <8 x i32> [[V:%.*]], <8 x i32> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>244; CHECK-NEXT: [[C:%.*]] = bitcast <4 x i32> [[S]] to <16 x i8>245; CHECK-NEXT: ret <16 x i8> [[C]]246;247 %s = shufflevector <8 x i32> %v, <8 x i32> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>248 %a = bitcast <4 x i32> %s to <2 x i64>249 %b = bitcast <2 x i64> %a to i128250 %c = bitcast i128 %b to <16 x i8>251 ret <16 x i8> %c252}253 254; Same as above, but showing why it's not feasable to implement the reverse255; fold in VectorCombine (see #136998).256 257define <4 x i32> @shuf_bitcast_chain_2(<8 x i32> %v) {258; CHECK-LABEL: @shuf_bitcast_chain_2(259; CHECK-NEXT: [[S0:%.*]] = shufflevector <8 x i32> [[V:%.*]], <8 x i32> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>260; CHECK-NEXT: [[S1:%.*]] = shufflevector <8 x i32> [[V]], <8 x i32> poison, <4 x i32> <i32 4, i32 5, i32 6, i32 7>261; CHECK-NEXT: [[R:%.*]] = or <4 x i32> [[S0]], [[S1]]262; CHECK-NEXT: ret <4 x i32> [[R]]263;264 %s0 = shufflevector <8 x i32> %v, <8 x i32> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>265 %s1 = shufflevector <8 x i32> %v, <8 x i32> poison, <4 x i32> <i32 4, i32 5, i32 6, i32 7>266 %b0 = bitcast <4 x i32> %s0 to i128267 %b1 = bitcast <4 x i32> %s1 to i128268 %c0 = bitcast i128 %b0 to <4 x i32>269 %c1 = bitcast i128 %b1 to <4 x i32>270 %r = or <4 x i32> %c0, %c1271 ret <4 x i32> %r272}273