1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2 ; RUN: opt < %s -instcombine -S | FileCheck %s 3 4 5 define i32 @foo(i32 %a, i32 %b, i32 %c, i32 %d) { 6 ; CHECK-LABEL: @foo( 7 ; CHECK-NEXT: [[E:%.*]] = icmp slt i32 %a, %b 8 ; CHECK-NEXT: [[J:%.*]] = select i1 [[E]], i32 %c, i32 %d 9 ; CHECK-NEXT: ret i32 [[J]] 10 ; 11 %e = icmp slt i32 %a, %b 12 %f = sext i1 %e to i32 13 %g = and i32 %c, %f 14 %h = xor i32 %f, -1 15 %i = and i32 %d, %h 16 %j = or i32 %g, %i 17 ret i32 %j 18 } 19 20 define i32 @bar(i32 %a, i32 %b, i32 %c, i32 %d) { 21 ; CHECK-LABEL: @bar( 22 ; CHECK-NEXT: [[E:%.*]] = icmp slt i32 %a, %b 23 ; CHECK-NEXT: [[J:%.*]] = select i1 [[E]], i32 %c, i32 %d 24 ; CHECK-NEXT: ret i32 [[J]] 25 ; 26 %e = icmp slt i32 %a, %b 27 %f = sext i1 %e to i32 28 %g = and i32 %c, %f 29 %h = xor i32 %f, -1 30 %i = and i32 %d, %h 31 %j = or i32 %i, %g 32 ret i32 %j 33 } 34 35 define i32 @goo(i32 %a, i32 %b, i32 %c, i32 %d) { 36 ; CHECK-LABEL: @goo( 37 ; CHECK-NEXT: [[T0:%.*]] = icmp slt i32 %a, %b 38 ; CHECK-NEXT: [[T3:%.*]] = select i1 [[T0]], i32 %c, i32 %d 39 ; CHECK-NEXT: ret i32 [[T3]] 40 ; 41 %t0 = icmp slt i32 %a, %b 42 %iftmp.0.0 = select i1 %t0, i32 -1, i32 0 43 %t1 = and i32 %iftmp.0.0, %c 44 %not = xor i32 %iftmp.0.0, -1 45 %t2 = and i32 %not, %d 46 %t3 = or i32 %t1, %t2 47 ret i32 %t3 48 } 49 50 define i32 @poo(i32 %a, i32 %b, i32 %c, i32 %d) { 51 ; CHECK-LABEL: @poo( 52 ; CHECK-NEXT: [[T0:%.*]] = icmp slt i32 %a, %b 53 ; CHECK-NEXT: [[T3:%.*]] = select i1 [[T0]], i32 %c, i32 %d 54 ; CHECK-NEXT: ret i32 [[T3]] 55 ; 56 %t0 = icmp slt i32 %a, %b 57 %iftmp.0.0 = select i1 %t0, i32 -1, i32 0 58 %t1 = and i32 %iftmp.0.0, %c 59 %iftmp = select i1 %t0, i32 0, i32 -1 60 %t2 = and i32 %iftmp, %d 61 %t3 = or i32 %t1, %t2 62 ret i32 %t3 63 } 64 65 define i32 @par(i32 %a, i32 %b, i32 %c, i32 %d) { 66 ; CHECK-LABEL: @par( 67 ; CHECK-NEXT: [[T0:%.*]] = icmp slt i32 %a, %b 68 ; CHECK-NEXT: [[T3:%.*]] = select i1 [[T0]], i32 %c, i32 %d 69 ; CHECK-NEXT: ret i32 [[T3]] 70 ; 71 %t0 = icmp slt i32 %a, %b 72 %iftmp.1.0 = select i1 %t0, i32 -1, i32 0 73 %t1 = and i32 %iftmp.1.0, %c 74 %not = xor i32 %iftmp.1.0, -1 75 %t2 = and i32 %not, %d 76 %t3 = or i32 %t1, %t2 77 ret i32 %t3 78 } 79 80 ; In the following tests (8 commutation variants), verify that a bitcast doesn't get 81 ; in the way of a select transform. These bitcasts are common in SSE/AVX and possibly 82 ; other vector code because of canonicalization to i64 elements for vectors. 83 84 ; The fptosi instructions are included to avoid commutation canonicalization based on 85 ; operator weight. Using another cast operator ensures that both operands of all logic 86 ; ops are equally weighted, and this ensures that we're testing all commutation 87 ; possibilities. 88 89 define <2 x i64> @bitcast_select_swap0(<4 x i1> %cmp, <2 x double> %a, <2 x double> %b) { 90 ; CHECK-LABEL: @bitcast_select_swap0( 91 ; CHECK-NEXT: [[SIA:%.*]] = fptosi <2 x double> %a to <2 x i64> 92 ; CHECK-NEXT: [[SIB:%.*]] = fptosi <2 x double> %b to <2 x i64> 93 ; CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i64> [[SIA]] to <4 x i32> 94 ; CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[SIB]] to <4 x i32> 95 ; CHECK-NEXT: [[TMP3:%.*]] = select <4 x i1> %cmp, <4 x i32> [[TMP1]], <4 x i32> [[TMP2]] 96 ; CHECK-NEXT: [[OR:%.*]] = bitcast <4 x i32> [[TMP3]] to <2 x i64> 97 ; CHECK-NEXT: ret <2 x i64> [[OR]] 98 ; 99 %sia = fptosi <2 x double> %a to <2 x i64> 100 %sib = fptosi <2 x double> %b to <2 x i64> 101 %sext = sext <4 x i1> %cmp to <4 x i32> 102 %bc1 = bitcast <4 x i32> %sext to <2 x i64> 103 %and1 = and <2 x i64> %bc1, %sia 104 %neg = xor <4 x i32> %sext, <i32 -1, i32 -1, i32 -1, i32 -1> 105 %bc2 = bitcast <4 x i32> %neg to <2 x i64> 106 %and2 = and <2 x i64> %bc2, %sib 107 %or = or <2 x i64> %and1, %and2 108 ret <2 x i64> %or 109 } 110 111 define <2 x i64> @bitcast_select_swap1(<4 x i1> %cmp, <2 x double> %a, <2 x double> %b) { 112 ; CHECK-LABEL: @bitcast_select_swap1( 113 ; CHECK-NEXT: [[SIA:%.*]] = fptosi <2 x double> %a to <2 x i64> 114 ; CHECK-NEXT: [[SIB:%.*]] = fptosi <2 x double> %b to <2 x i64> 115 ; CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i64> [[SIA]] to <4 x i32> 116 ; CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[SIB]] to <4 x i32> 117 ; CHECK-NEXT: [[TMP3:%.*]] = select <4 x i1> %cmp, <4 x i32> [[TMP1]], <4 x i32> [[TMP2]] 118 ; CHECK-NEXT: [[OR:%.*]] = bitcast <4 x i32> [[TMP3]] to <2 x i64> 119 ; CHECK-NEXT: ret <2 x i64> [[OR]] 120 ; 121 %sia = fptosi <2 x double> %a to <2 x i64> 122 %sib = fptosi <2 x double> %b to <2 x i64> 123 %sext = sext <4 x i1> %cmp to <4 x i32> 124 %bc1 = bitcast <4 x i32> %sext to <2 x i64> 125 %and1 = and <2 x i64> %bc1, %sia 126 %neg = xor <4 x i32> %sext, <i32 -1, i32 -1, i32 -1, i32 -1> 127 %bc2 = bitcast <4 x i32> %neg to <2 x i64> 128 %and2 = and <2 x i64> %bc2, %sib 129 %or = or <2 x i64> %and2, %and1 130 ret <2 x i64> %or 131 } 132 133 define <2 x i64> @bitcast_select_swap2(<4 x i1> %cmp, <2 x double> %a, <2 x double> %b) { 134 ; CHECK-LABEL: @bitcast_select_swap2( 135 ; CHECK-NEXT: [[SIA:%.*]] = fptosi <2 x double> %a to <2 x i64> 136 ; CHECK-NEXT: [[SIB:%.*]] = fptosi <2 x double> %b to <2 x i64> 137 ; CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i64> [[SIA]] to <4 x i32> 138 ; CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[SIB]] to <4 x i32> 139 ; CHECK-NEXT: [[TMP3:%.*]] = select <4 x i1> %cmp, <4 x i32> [[TMP1]], <4 x i32> [[TMP2]] 140 ; CHECK-NEXT: [[OR:%.*]] = bitcast <4 x i32> [[TMP3]] to <2 x i64> 141 ; CHECK-NEXT: ret <2 x i64> [[OR]] 142 ; 143 %sia = fptosi <2 x double> %a to <2 x i64> 144 %sib = fptosi <2 x double> %b to <2 x i64> 145 %sext = sext <4 x i1> %cmp to <4 x i32> 146 %bc1 = bitcast <4 x i32> %sext to <2 x i64> 147 %and1 = and <2 x i64> %bc1, %sia 148 %neg = xor <4 x i32> %sext, <i32 -1, i32 -1, i32 -1, i32 -1> 149 %bc2 = bitcast <4 x i32> %neg to <2 x i64> 150 %and2 = and <2 x i64> %sib, %bc2 151 %or = or <2 x i64> %and1, %and2 152 ret <2 x i64> %or 153 } 154 155 define <2 x i64> @bitcast_select_swap3(<4 x i1> %cmp, <2 x double> %a, <2 x double> %b) { 156 ; CHECK-LABEL: @bitcast_select_swap3( 157 ; CHECK-NEXT: [[SIA:%.*]] = fptosi <2 x double> %a to <2 x i64> 158 ; CHECK-NEXT: [[SIB:%.*]] = fptosi <2 x double> %b to <2 x i64> 159 ; CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i64> [[SIA]] to <4 x i32> 160 ; CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[SIB]] to <4 x i32> 161 ; CHECK-NEXT: [[TMP3:%.*]] = select <4 x i1> %cmp, <4 x i32> [[TMP1]], <4 x i32> [[TMP2]] 162 ; CHECK-NEXT: [[OR:%.*]] = bitcast <4 x i32> [[TMP3]] to <2 x i64> 163 ; CHECK-NEXT: ret <2 x i64> [[OR]] 164 ; 165 %sia = fptosi <2 x double> %a to <2 x i64> 166 %sib = fptosi <2 x double> %b to <2 x i64> 167 %sext = sext <4 x i1> %cmp to <4 x i32> 168 %bc1 = bitcast <4 x i32> %sext to <2 x i64> 169 %and1 = and <2 x i64> %bc1, %sia 170 %neg = xor <4 x i32> %sext, <i32 -1, i32 -1, i32 -1, i32 -1> 171 %bc2 = bitcast <4 x i32> %neg to <2 x i64> 172 %and2 = and <2 x i64> %sib, %bc2 173 %or = or <2 x i64> %and2, %and1 174 ret <2 x i64> %or 175 } 176 177 define <2 x i64> @bitcast_select_swap4(<4 x i1> %cmp, <2 x double> %a, <2 x double> %b) { 178 ; CHECK-LABEL: @bitcast_select_swap4( 179 ; CHECK-NEXT: [[SIA:%.*]] = fptosi <2 x double> %a to <2 x i64> 180 ; CHECK-NEXT: [[SIB:%.*]] = fptosi <2 x double> %b to <2 x i64> 181 ; CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i64> [[SIA]] to <4 x i32> 182 ; CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[SIB]] to <4 x i32> 183 ; CHECK-NEXT: [[TMP3:%.*]] = select <4 x i1> %cmp, <4 x i32> [[TMP1]], <4 x i32> [[TMP2]] 184 ; CHECK-NEXT: [[OR:%.*]] = bitcast <4 x i32> [[TMP3]] to <2 x i64> 185 ; CHECK-NEXT: ret <2 x i64> [[OR]] 186 ; 187 %sia = fptosi <2 x double> %a to <2 x i64> 188 %sib = fptosi <2 x double> %b to <2 x i64> 189 %sext = sext <4 x i1> %cmp to <4 x i32> 190 %bc1 = bitcast <4 x i32> %sext to <2 x i64> 191 %and1 = and <2 x i64> %sia, %bc1 192 %neg = xor <4 x i32> %sext, <i32 -1, i32 -1, i32 -1, i32 -1> 193 %bc2 = bitcast <4 x i32> %neg to <2 x i64> 194 %and2 = and <2 x i64> %bc2, %sib 195 %or = or <2 x i64> %and1, %and2 196 ret <2 x i64> %or 197 } 198 199 define <2 x i64> @bitcast_select_swap5(<4 x i1> %cmp, <2 x double> %a, <2 x double> %b) { 200 ; CHECK-LABEL: @bitcast_select_swap5( 201 ; CHECK-NEXT: [[SIA:%.*]] = fptosi <2 x double> %a to <2 x i64> 202 ; CHECK-NEXT: [[SIB:%.*]] = fptosi <2 x double> %b to <2 x i64> 203 ; CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i64> [[SIA]] to <4 x i32> 204 ; CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[SIB]] to <4 x i32> 205 ; CHECK-NEXT: [[TMP3:%.*]] = select <4 x i1> %cmp, <4 x i32> [[TMP1]], <4 x i32> [[TMP2]] 206 ; CHECK-NEXT: [[OR:%.*]] = bitcast <4 x i32> [[TMP3]] to <2 x i64> 207 ; CHECK-NEXT: ret <2 x i64> [[OR]] 208 ; 209 %sia = fptosi <2 x double> %a to <2 x i64> 210 %sib = fptosi <2 x double> %b to <2 x i64> 211 %sext = sext <4 x i1> %cmp to <4 x i32> 212 %bc1 = bitcast <4 x i32> %sext to <2 x i64> 213 %and1 = and <2 x i64> %sia, %bc1 214 %neg = xor <4 x i32> %sext, <i32 -1, i32 -1, i32 -1, i32 -1> 215 %bc2 = bitcast <4 x i32> %neg to <2 x i64> 216 %and2 = and <2 x i64> %bc2, %sib 217 %or = or <2 x i64> %and2, %and1 218 ret <2 x i64> %or 219 } 220 221 define <2 x i64> @bitcast_select_swap6(<4 x i1> %cmp, <2 x double> %a, <2 x double> %b) { 222 ; CHECK-LABEL: @bitcast_select_swap6( 223 ; CHECK-NEXT: [[SIA:%.*]] = fptosi <2 x double> %a to <2 x i64> 224 ; CHECK-NEXT: [[SIB:%.*]] = fptosi <2 x double> %b to <2 x i64> 225 ; CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i64> [[SIA]] to <4 x i32> 226 ; CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[SIB]] to <4 x i32> 227 ; CHECK-NEXT: [[TMP3:%.*]] = select <4 x i1> %cmp, <4 x i32> [[TMP1]], <4 x i32> [[TMP2]] 228 ; CHECK-NEXT: [[OR:%.*]] = bitcast <4 x i32> [[TMP3]] to <2 x i64> 229 ; CHECK-NEXT: ret <2 x i64> [[OR]] 230 ; 231 %sia = fptosi <2 x double> %a to <2 x i64> 232 %sib = fptosi <2 x double> %b to <2 x i64> 233 %sext = sext <4 x i1> %cmp to <4 x i32> 234 %bc1 = bitcast <4 x i32> %sext to <2 x i64> 235 %and1 = and <2 x i64> %sia, %bc1 236 %neg = xor <4 x i32> %sext, <i32 -1, i32 -1, i32 -1, i32 -1> 237 %bc2 = bitcast <4 x i32> %neg to <2 x i64> 238 %and2 = and <2 x i64> %sib, %bc2 239 %or = or <2 x i64> %and1, %and2 240 ret <2 x i64> %or 241 } 242 243 define <2 x i64> @bitcast_select_swap7(<4 x i1> %cmp, <2 x double> %a, <2 x double> %b) { 244 ; CHECK-LABEL: @bitcast_select_swap7( 245 ; CHECK-NEXT: [[SIA:%.*]] = fptosi <2 x double> %a to <2 x i64> 246 ; CHECK-NEXT: [[SIB:%.*]] = fptosi <2 x double> %b to <2 x i64> 247 ; CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i64> [[SIA]] to <4 x i32> 248 ; CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[SIB]] to <4 x i32> 249 ; CHECK-NEXT: [[TMP3:%.*]] = select <4 x i1> %cmp, <4 x i32> [[TMP1]], <4 x i32> [[TMP2]] 250 ; CHECK-NEXT: [[OR:%.*]] = bitcast <4 x i32> [[TMP3]] to <2 x i64> 251 ; CHECK-NEXT: ret <2 x i64> [[OR]] 252 ; 253 %sia = fptosi <2 x double> %a to <2 x i64> 254 %sib = fptosi <2 x double> %b to <2 x i64> 255 %sext = sext <4 x i1> %cmp to <4 x i32> 256 %bc1 = bitcast <4 x i32> %sext to <2 x i64> 257 %and1 = and <2 x i64> %sia, %bc1 258 %neg = xor <4 x i32> %sext, <i32 -1, i32 -1, i32 -1, i32 -1> 259 %bc2 = bitcast <4 x i32> %neg to <2 x i64> 260 %and2 = and <2 x i64> %sib, %bc2 261 %or = or <2 x i64> %and2, %and1 262 ret <2 x i64> %or 263 } 264 265 define <2 x i64> @bitcast_select_multi_uses(<4 x i1> %cmp, <2 x i64> %a, <2 x i64> %b) { 266 ; CHECK-LABEL: @bitcast_select_multi_uses( 267 ; CHECK-NEXT: [[SEXT:%.*]] = sext <4 x i1> %cmp to <4 x i32> 268 ; CHECK-NEXT: [[BC1:%.*]] = bitcast <4 x i32> [[SEXT]] to <2 x i64> 269 ; CHECK-NEXT: [[AND1:%.*]] = and <2 x i64> [[BC1]], %a 270 ; CHECK-NEXT: [[NEG:%.*]] = xor <4 x i32> [[SEXT]], <i32 -1, i32 -1, i32 -1, i32 -1> 271 ; CHECK-NEXT: [[BC2:%.*]] = bitcast <4 x i32> [[NEG]] to <2 x i64> 272 ; CHECK-NEXT: [[AND2:%.*]] = and <2 x i64> [[BC2]], %b 273 ; CHECK-NEXT: [[OR:%.*]] = or <2 x i64> [[AND2]], [[AND1]] 274 ; CHECK-NEXT: [[ADD:%.*]] = add <2 x i64> [[AND2]], [[BC2]] 275 ; CHECK-NEXT: [[SUB:%.*]] = sub <2 x i64> [[OR]], [[ADD]] 276 ; CHECK-NEXT: ret <2 x i64> [[SUB]] 277 ; 278 %sext = sext <4 x i1> %cmp to <4 x i32> 279 %bc1 = bitcast <4 x i32> %sext to <2 x i64> 280 %and1 = and <2 x i64> %a, %bc1 281 %neg = xor <4 x i32> %sext, <i32 -1, i32 -1, i32 -1, i32 -1> 282 %bc2 = bitcast <4 x i32> %neg to <2 x i64> 283 %and2 = and <2 x i64> %b, %bc2 284 %or = or <2 x i64> %and2, %and1 285 %add = add <2 x i64> %and2, %bc2 286 %sub = sub <2 x i64> %or, %add 287 ret <2 x i64> %sub 288 } 289 290 define i1 @bools(i1 %a, i1 %b, i1 %c) { 291 ; CHECK-LABEL: @bools( 292 ; CHECK-NEXT: [[TMP1:%.*]] = select i1 %c, i1 %b, i1 %a 293 ; CHECK-NEXT: ret i1 [[TMP1]] 294 ; 295 %not = xor i1 %c, -1 296 %and1 = and i1 %not, %a 297 %and2 = and i1 %c, %b 298 %or = or i1 %and1, %and2 299 ret i1 %or 300 } 301 302 ; Form a select if we know we can get replace 2 simple logic ops. 303 304 define i1 @bools_multi_uses1(i1 %a, i1 %b, i1 %c) { 305 ; CHECK-LABEL: @bools_multi_uses1( 306 ; CHECK-NEXT: [[NOT:%.*]] = xor i1 %c, true 307 ; CHECK-NEXT: [[AND1:%.*]] = and i1 [[NOT]], %a 308 ; CHECK-NEXT: [[TMP1:%.*]] = select i1 %c, i1 %b, i1 %a 309 ; CHECK-NEXT: [[XOR:%.*]] = xor i1 [[TMP1]], [[AND1]] 310 ; CHECK-NEXT: ret i1 [[XOR]] 311 ; 312 %not = xor i1 %c, -1 313 %and1 = and i1 %not, %a 314 %and2 = and i1 %c, %b 315 %or = or i1 %and1, %and2 316 %xor = xor i1 %or, %and1 317 ret i1 %xor 318 } 319 320 ; Don't replace a cheap logic op with a potentially expensive select 321 ; unless we can also eliminate one of the other original ops. 322 323 define i1 @bools_multi_uses2(i1 %a, i1 %b, i1 %c) { 324 ; CHECK-LABEL: @bools_multi_uses2( 325 ; CHECK-NEXT: [[NOT:%.*]] = xor i1 %c, true 326 ; CHECK-NEXT: [[AND1:%.*]] = and i1 [[NOT]], %a 327 ; CHECK-NEXT: [[AND2:%.*]] = and i1 %c, %b 328 ; CHECK-NEXT: [[ADD:%.*]] = xor i1 [[AND1]], [[AND2]] 329 ; CHECK-NEXT: ret i1 [[ADD]] 330 ; 331 %not = xor i1 %c, -1 332 %and1 = and i1 %not, %a 333 %and2 = and i1 %c, %b 334 %or = or i1 %and1, %and2 335 %add = add i1 %and1, %and2 336 %and3 = and i1 %or, %add 337 ret i1 %and3 338 } 339 340 define <4 x i1> @vec_of_bools(<4 x i1> %a, <4 x i1> %b, <4 x i1> %c) { 341 ; CHECK-LABEL: @vec_of_bools( 342 ; CHECK-NEXT: [[TMP1:%.*]] = select <4 x i1> %c, <4 x i1> %b, <4 x i1> %a 343 ; CHECK-NEXT: ret <4 x i1> [[TMP1]] 344 ; 345 %not = xor <4 x i1> %c, <i1 true, i1 true, i1 true, i1 true> 346 %and1 = and <4 x i1> %not, %a 347 %and2 = and <4 x i1> %b, %c 348 %or = or <4 x i1> %and2, %and1 349 ret <4 x i1> %or 350 } 351 352 define i4 @vec_of_casted_bools(i4 %a, i4 %b, <4 x i1> %c) { 353 ; CHECK-LABEL: @vec_of_casted_bools( 354 ; CHECK-NEXT: [[TMP1:%.*]] = bitcast i4 %a to <4 x i1> 355 ; CHECK-NEXT: [[TMP2:%.*]] = bitcast i4 %b to <4 x i1> 356 ; CHECK-NEXT: [[TMP3:%.*]] = select <4 x i1> %c, <4 x i1> [[TMP2]], <4 x i1> [[TMP1]] 357 ; CHECK-NEXT: [[TMP4:%.*]] = bitcast <4 x i1> [[TMP3]] to i4 358 ; CHECK-NEXT: ret i4 [[TMP4]] 359 ; 360 %not = xor <4 x i1> %c, <i1 true, i1 true, i1 true, i1 true> 361 %bc1 = bitcast <4 x i1> %not to i4 362 %bc2 = bitcast <4 x i1> %c to i4 363 %and1 = and i4 %a, %bc1 364 %and2 = and i4 %bc2, %b 365 %or = or i4 %and1, %and2 366 ret i4 %or 367 } 368 369 ; Inverted 'and' constants mean this is a select. 370 371 define <4 x i32> @vec_sel_consts(<4 x i32> %a, <4 x i32> %b) { 372 ; CHECK-LABEL: @vec_sel_consts( 373 ; CHECK-NEXT: [[TMP1:%.*]] = select <4 x i1> <i1 true, i1 false, i1 false, i1 true>, <4 x i32> %a, <4 x i32> %b 374 ; CHECK-NEXT: ret <4 x i32> [[TMP1]] 375 ; 376 %and1 = and <4 x i32> %a, <i32 -1, i32 0, i32 0, i32 -1> 377 %and2 = and <4 x i32> %b, <i32 0, i32 -1, i32 -1, i32 0> 378 %or = or <4 x i32> %and1, %and2 379 ret <4 x i32> %or 380 } 381 382 ; The select condition constant is always derived from the first operand of the 'or'. 383 384 define <3 x i129> @vec_sel_consts_weird(<3 x i129> %a, <3 x i129> %b) { 385 ; CHECK-LABEL: @vec_sel_consts_weird( 386 ; CHECK-NEXT: [[TMP1:%.*]] = select <3 x i1> <i1 false, i1 true, i1 false>, <3 x i129> %b, <3 x i129> %a 387 ; CHECK-NEXT: ret <3 x i129> [[TMP1]] 388 ; 389 %and1 = and <3 x i129> %a, <i129 -1, i129 0, i129 -1> 390 %and2 = and <3 x i129> %b, <i129 0, i129 -1, i129 0> 391 %or = or <3 x i129> %and2, %and1 392 ret <3 x i129> %or 393 } 394 395 ; The mask elements must be inverted for this to be a select. 396 397 define <4 x i32> @vec_not_sel_consts(<4 x i32> %a, <4 x i32> %b) { 398 ; CHECK-LABEL: @vec_not_sel_consts( 399 ; CHECK-NEXT: [[AND1:%.*]] = and <4 x i32> %a, <i32 -1, i32 0, i32 0, i32 0> 400 ; CHECK-NEXT: [[AND2:%.*]] = and <4 x i32> %b, <i32 0, i32 -1, i32 0, i32 -1> 401 ; CHECK-NEXT: [[OR:%.*]] = or <4 x i32> [[AND1]], [[AND2]] 402 ; CHECK-NEXT: ret <4 x i32> [[OR]] 403 ; 404 %and1 = and <4 x i32> %a, <i32 -1, i32 0, i32 0, i32 0> 405 %and2 = and <4 x i32> %b, <i32 0, i32 -1, i32 0, i32 -1> 406 %or = or <4 x i32> %and1, %and2 407 ret <4 x i32> %or 408 } 409 410 ; The inverted constants may be operands of xor instructions. 411 412 define <4 x i32> @vec_sel_xor(<4 x i32> %a, <4 x i32> %b, <4 x i1> %c) { 413 ; CHECK-LABEL: @vec_sel_xor( 414 ; CHECK-NEXT: [[TMP1:%.*]] = xor <4 x i1> %c, <i1 false, i1 true, i1 true, i1 true> 415 ; CHECK-NEXT: [[TMP2:%.*]] = select <4 x i1> [[TMP1]], <4 x i32> %a, <4 x i32> %b 416 ; CHECK-NEXT: ret <4 x i32> [[TMP2]] 417 ; 418 %mask = sext <4 x i1> %c to <4 x i32> 419 %mask_flip1 = xor <4 x i32> %mask, <i32 -1, i32 0, i32 0, i32 0> 420 %not_mask_flip1 = xor <4 x i32> %mask, <i32 0, i32 -1, i32 -1, i32 -1> 421 %and1 = and <4 x i32> %not_mask_flip1, %a 422 %and2 = and <4 x i32> %mask_flip1, %b 423 %or = or <4 x i32> %and1, %and2 424 ret <4 x i32> %or 425 } 426 427 ; Allow the transform even if the mask values have multiple uses because 428 ; there's still a net reduction of instructions from removing the and/and/or. 429 430 define <4 x i32> @vec_sel_xor_multi_use(<4 x i32> %a, <4 x i32> %b, <4 x i1> %c) { 431 ; CHECK-LABEL: @vec_sel_xor_multi_use( 432 ; CHECK-NEXT: [[MASK:%.*]] = sext <4 x i1> %c to <4 x i32> 433 ; CHECK-NEXT: [[MASK_FLIP1:%.*]] = xor <4 x i32> [[MASK]], <i32 -1, i32 0, i32 0, i32 0> 434 ; CHECK-NEXT: [[TMP1:%.*]] = xor <4 x i1> %c, <i1 false, i1 true, i1 true, i1 true> 435 ; CHECK-NEXT: [[TMP2:%.*]] = select <4 x i1> [[TMP1]], <4 x i32> %a, <4 x i32> %b 436 ; CHECK-NEXT: [[ADD:%.*]] = add <4 x i32> [[TMP2]], [[MASK_FLIP1]] 437 ; CHECK-NEXT: ret <4 x i32> [[ADD]] 438 ; 439 %mask = sext <4 x i1> %c to <4 x i32> 440 %mask_flip1 = xor <4 x i32> %mask, <i32 -1, i32 0, i32 0, i32 0> 441 %not_mask_flip1 = xor <4 x i32> %mask, <i32 0, i32 -1, i32 -1, i32 -1> 442 %and1 = and <4 x i32> %not_mask_flip1, %a 443 %and2 = and <4 x i32> %mask_flip1, %b 444 %or = or <4 x i32> %and1, %and2 445 %add = add <4 x i32> %or, %mask_flip1 446 ret <4 x i32> %add 447 } 448 449