1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -instcombine -S | FileCheck %s 3 4 5define 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 20define 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 35define 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 50define 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 65define 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 89define <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 111define <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 133define <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 155define <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 177define <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 199define <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 221define <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 243define <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 265define <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 290define 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 304define 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 323define 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 340define <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 352define 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 371define <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 384define <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 397define <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 412define <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 430define <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