1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -passes=instcombine -S < %s | FileCheck %s 3 4define float @foo1(float %a) { 5; CHECK-LABEL: @foo1( 6; CHECK-NEXT: [[B:%.*]] = fcmp ogt float [[A:%.*]], 0.000000e+00 7; CHECK-NEXT: [[C:%.*]] = select i1 [[B]], float [[A]], float 0.000000e+00 8; CHECK-NEXT: [[D:%.*]] = fcmp olt float [[C]], 1.000000e+00 9; CHECK-NEXT: [[F:%.*]] = select i1 [[D]], float [[C]], float 1.000000e+00 10; CHECK-NEXT: ret float [[F]] 11; 12 %b = fcmp ogt float %a, 0.0 13 %c = select i1 %b, float %a, float 0.0 14 %d = fcmp olt float %c, 1.0 15 %f = select i1 %d, float %c, float 1.0 16 ret float %f 17} 18 19define float @foo2(float %a) { 20; CHECK-LABEL: @foo2( 21; CHECK-NEXT: [[B:%.*]] = fcmp ule float [[A:%.*]], 0.000000e+00 22; CHECK-NEXT: [[TMP1:%.*]] = fcmp olt float [[A]], 1.000000e+00 23; CHECK-NEXT: [[E:%.*]] = select i1 [[TMP1]], float [[A]], float 1.000000e+00 24; CHECK-NEXT: [[F:%.*]] = select i1 [[B]], float 0.000000e+00, float [[E]] 25; CHECK-NEXT: ret float [[F]] 26; 27 %b = fcmp ogt float %a, 0.0 28 %c = select i1 %b, float %a, float 0.0 29 %d = fcmp olt float %c, 1.0 30 %e = select i1 %b, float %a, float 0.0 31 %f = select i1 %d, float %e, float 1.0 32 ret float %f 33} 34 35define <2 x i32> @foo3(<2 x i1> %vec_bool, i1 %bool, <2 x i32> %V) { 36; CHECK-LABEL: @foo3( 37; CHECK-NEXT: [[SEL0:%.*]] = select <2 x i1> [[VEC_BOOL:%.*]], <2 x i32> zeroinitializer, <2 x i32> [[V:%.*]] 38; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[BOOL:%.*]], <2 x i32> [[SEL0]], <2 x i32> [[V]] 39; CHECK-NEXT: ret <2 x i32> [[SEL1]] 40; 41 %sel0 = select <2 x i1> %vec_bool, <2 x i32> zeroinitializer, <2 x i32> %V 42 %sel1 = select i1 %bool, <2 x i32> %sel0, <2 x i32> %V 43 ret <2 x i32> %sel1 44} 45 46; Four variations of (select (select-shuffle)) with a common operand. 47 48define <4 x i8> @sel_shuf_commute0(<4 x i8> %x, <4 x i8> %y, <4 x i1> %cmp) { 49; CHECK-LABEL: @sel_shuf_commute0( 50; CHECK-NEXT: [[SEL:%.*]] = select <4 x i1> [[CMP:%.*]], <4 x i8> [[Y:%.*]], <4 x i8> [[X:%.*]] 51; CHECK-NEXT: [[R:%.*]] = shufflevector <4 x i8> [[X]], <4 x i8> [[SEL]], <4 x i32> <i32 0, i32 5, i32 2, i32 7> 52; CHECK-NEXT: ret <4 x i8> [[R]] 53; 54 %blend = shufflevector <4 x i8> %x, <4 x i8> %y, <4 x i32> <i32 0, i32 5, i32 2, i32 7> 55 %r = select <4 x i1> %cmp, <4 x i8> %blend, <4 x i8> %x 56 ret <4 x i8> %r 57} 58 59; Weird types are ok. 60 61define <5 x i9> @sel_shuf_commute1(<5 x i9> %x, <5 x i9> %y, <5 x i1> %cmp) { 62; CHECK-LABEL: @sel_shuf_commute1( 63; CHECK-NEXT: [[SEL:%.*]] = select <5 x i1> [[CMP:%.*]], <5 x i9> [[X:%.*]], <5 x i9> [[Y:%.*]] 64; CHECK-NEXT: [[R:%.*]] = shufflevector <5 x i9> [[SEL]], <5 x i9> [[Y]], <5 x i32> <i32 0, i32 6, i32 2, i32 8, i32 9> 65; CHECK-NEXT: ret <5 x i9> [[R]] 66; 67 %blend = shufflevector <5 x i9> %x, <5 x i9> %y, <5 x i32> <i32 0, i32 6, i32 2, i32 8, i32 9> 68 %r = select <5 x i1> %cmp, <5 x i9> %blend, <5 x i9> %y 69 ret <5 x i9> %r 70} 71 72define <4 x float> @sel_shuf_commute2(<4 x float> %x, <4 x float> %y, <4 x i1> %cmp) { 73; CHECK-LABEL: @sel_shuf_commute2( 74; CHECK-NEXT: [[SEL:%.*]] = select <4 x i1> [[CMP:%.*]], <4 x float> [[X:%.*]], <4 x float> [[Y:%.*]] 75; CHECK-NEXT: [[R:%.*]] = shufflevector <4 x float> [[X]], <4 x float> [[SEL]], <4 x i32> <i32 0, i32 1, i32 2, i32 7> 76; CHECK-NEXT: ret <4 x float> [[R]] 77; 78 %blend = shufflevector <4 x float> %x, <4 x float> %y, <4 x i32> <i32 0, i32 1, i32 2, i32 7> 79 %r = select <4 x i1> %cmp, <4 x float> %x, <4 x float> %blend 80 ret <4 x float> %r 81} 82 83; Scalar condition is ok. 84 85define <4 x i8> @sel_shuf_commute3(<4 x i8> %x, <4 x i8> %y, i1 %cmp) { 86; CHECK-LABEL: @sel_shuf_commute3( 87; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP:%.*]], <4 x i8> [[Y:%.*]], <4 x i8> [[X:%.*]] 88; CHECK-NEXT: [[R:%.*]] = shufflevector <4 x i8> [[SEL]], <4 x i8> [[Y]], <4 x i32> <i32 0, i32 5, i32 2, i32 3> 89; CHECK-NEXT: ret <4 x i8> [[R]] 90; 91 %blend = shufflevector <4 x i8> %x, <4 x i8> %y, <4 x i32> <i32 0, i32 5, i32 2, i32 3> 92 %r = select i1 %cmp, <4 x i8> %y, <4 x i8> %blend 93 ret <4 x i8> %r 94} 95 96declare void @use(<4 x i8>) 97 98; Negative test - extra use would require another instruction. 99 100define <4 x i8> @sel_shuf_use(<4 x i8> %x, <4 x i8> %y, <4 x i1> %cmp) { 101; CHECK-LABEL: @sel_shuf_use( 102; CHECK-NEXT: [[BLEND:%.*]] = shufflevector <4 x i8> [[X:%.*]], <4 x i8> [[Y:%.*]], <4 x i32> <i32 0, i32 5, i32 2, i32 7> 103; CHECK-NEXT: call void @use(<4 x i8> [[BLEND]]) 104; CHECK-NEXT: [[R:%.*]] = select <4 x i1> [[CMP:%.*]], <4 x i8> [[BLEND]], <4 x i8> [[X]] 105; CHECK-NEXT: ret <4 x i8> [[R]] 106; 107 %blend = shufflevector <4 x i8> %x, <4 x i8> %y, <4 x i32> <i32 0, i32 5, i32 2, i32 7> 108 call void @use(<4 x i8> %blend) 109 %r = select <4 x i1> %cmp, <4 x i8> %blend, <4 x i8> %x 110 ret <4 x i8> %r 111} 112 113; Negative test - undef in shuffle mask prevents transform. 114 115define <4 x i8> @sel_shuf_undef(<4 x i8> %x, <4 x i8> %y, <4 x i1> %cmp) { 116; CHECK-LABEL: @sel_shuf_undef( 117; CHECK-NEXT: [[BLEND:%.*]] = shufflevector <4 x i8> [[X:%.*]], <4 x i8> [[Y:%.*]], <4 x i32> <i32 0, i32 5, i32 2, i32 poison> 118; CHECK-NEXT: [[R:%.*]] = select <4 x i1> [[CMP:%.*]], <4 x i8> [[BLEND]], <4 x i8> [[Y]] 119; CHECK-NEXT: ret <4 x i8> [[R]] 120; 121 %blend = shufflevector <4 x i8> %x, <4 x i8> %y, <4 x i32> <i32 0, i32 5, i32 2, i32 undef> 122 %r = select <4 x i1> %cmp, <4 x i8> %blend, <4 x i8> %y 123 ret <4 x i8> %r 124} 125 126; Negative test - not a "select shuffle" 127 128define <4 x i8> @sel_shuf_not(<4 x i8> %x, <4 x i8> %y, <4 x i1> %cmp) { 129; CHECK-LABEL: @sel_shuf_not( 130; CHECK-NEXT: [[NOTBLEND:%.*]] = shufflevector <4 x i8> [[X:%.*]], <4 x i8> [[Y:%.*]], <4 x i32> <i32 0, i32 5, i32 2, i32 6> 131; CHECK-NEXT: [[R:%.*]] = select <4 x i1> [[CMP:%.*]], <4 x i8> [[NOTBLEND]], <4 x i8> [[Y]] 132; CHECK-NEXT: ret <4 x i8> [[R]] 133; 134 %notblend = shufflevector <4 x i8> %x, <4 x i8> %y, <4 x i32> <i32 0, i32 5, i32 2, i32 6> 135 %r = select <4 x i1> %cmp, <4 x i8> %notblend, <4 x i8> %y 136 ret <4 x i8> %r 137} 138 139; Negative test - must shuffle one of the select operands 140 141define <4 x i8> @sel_shuf_no_common_operand(<4 x i8> %x, <4 x i8> %y, <4 x i1> %cmp, <4 x i8> %z) { 142; CHECK-LABEL: @sel_shuf_no_common_operand( 143; CHECK-NEXT: [[BLEND:%.*]] = shufflevector <4 x i8> [[X:%.*]], <4 x i8> [[Y:%.*]], <4 x i32> <i32 0, i32 5, i32 2, i32 3> 144; CHECK-NEXT: [[R:%.*]] = select <4 x i1> [[CMP:%.*]], <4 x i8> [[Z:%.*]], <4 x i8> [[BLEND]] 145; CHECK-NEXT: ret <4 x i8> [[R]] 146; 147 %blend = shufflevector <4 x i8> %x, <4 x i8> %y, <4 x i32> <i32 0, i32 5, i32 2, i32 3> 148 %r = select <4 x i1> %cmp, <4 x i8> %z, <4 x i8> %blend 149 ret <4 x i8> %r 150} 151 152; Negative test - don't crash (this is not a select shuffle because it changes vector length) 153 154define <2 x i8> @sel_shuf_narrowing_commute1(<4 x i8> %x, <4 x i8> %y, <2 x i8> %x2, <2 x i1> %cmp) { 155; CHECK-LABEL: @sel_shuf_narrowing_commute1( 156; CHECK-NEXT: [[BLEND:%.*]] = shufflevector <4 x i8> [[X:%.*]], <4 x i8> [[Y:%.*]], <2 x i32> <i32 0, i32 5> 157; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[CMP:%.*]], <2 x i8> [[BLEND]], <2 x i8> [[X2:%.*]] 158; CHECK-NEXT: ret <2 x i8> [[R]] 159; 160 %blend = shufflevector <4 x i8> %x, <4 x i8> %y, <2 x i32> <i32 0, i32 5> 161 %r = select <2 x i1> %cmp, <2 x i8> %blend, <2 x i8> %x2 162 ret <2 x i8> %r 163} 164 165; Negative test - don't crash (this is not a select shuffle because it changes vector length) 166 167define <2 x i8> @sel_shuf_narrowing_commute2(<4 x i8> %x, <4 x i8> %y, <2 x i8> %x2, <2 x i1> %cmp) { 168; CHECK-LABEL: @sel_shuf_narrowing_commute2( 169; CHECK-NEXT: [[BLEND:%.*]] = shufflevector <4 x i8> [[X:%.*]], <4 x i8> [[Y:%.*]], <2 x i32> <i32 0, i32 5> 170; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[CMP:%.*]], <2 x i8> [[X2:%.*]], <2 x i8> [[BLEND]] 171; CHECK-NEXT: ret <2 x i8> [[R]] 172; 173 %blend = shufflevector <4 x i8> %x, <4 x i8> %y, <2 x i32> <i32 0, i32 5> 174 %r = select <2 x i1> %cmp, <2 x i8> %x2, <2 x i8> %blend 175 ret <2 x i8> %r 176} 177 178define i8 @strong_order_cmp_slt_eq(i32 %a, i32 %b) { 179; CHECK-LABEL: @strong_order_cmp_slt_eq( 180; CHECK-NEXT: [[SEL_EQ:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[A:%.*]], i32 [[B:%.*]]) 181; CHECK-NEXT: ret i8 [[SEL_EQ]] 182; 183 %cmp.lt = icmp slt i32 %a, %b 184 %sel.lt = select i1 %cmp.lt, i8 -1, i8 1 185 %cmp.eq = icmp eq i32 %a, %b 186 %sel.eq = select i1 %cmp.eq, i8 0, i8 %sel.lt 187 ret i8 %sel.eq 188} 189 190define i8 @strong_order_cmp_ult_eq(i32 %a, i32 %b) { 191; CHECK-LABEL: @strong_order_cmp_ult_eq( 192; CHECK-NEXT: [[SEL_EQ:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[A:%.*]], i32 [[B:%.*]]) 193; CHECK-NEXT: ret i8 [[SEL_EQ]] 194; 195 %cmp.lt = icmp ult i32 %a, %b 196 %sel.lt = select i1 %cmp.lt, i8 -1, i8 1 197 %cmp.eq = icmp eq i32 %a, %b 198 %sel.eq = select i1 %cmp.eq, i8 0, i8 %sel.lt 199 ret i8 %sel.eq 200} 201 202define i8 @strong_order_cmp_slt_eq_wrong_const(i32 %a, i32 %b) { 203; CHECK-LABEL: @strong_order_cmp_slt_eq_wrong_const( 204; CHECK-NEXT: [[CMP_LT:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]] 205; CHECK-NEXT: [[SEL_LT:%.*]] = select i1 [[CMP_LT]], i8 -2, i8 1 206; CHECK-NEXT: [[CMP_EQ:%.*]] = icmp eq i32 [[A]], [[B]] 207; CHECK-NEXT: [[SEL_EQ:%.*]] = select i1 [[CMP_EQ]], i8 0, i8 [[SEL_LT]] 208; CHECK-NEXT: ret i8 [[SEL_EQ]] 209; 210 %cmp.lt = icmp slt i32 %a, %b 211 %sel.lt = select i1 %cmp.lt, i8 -2, i8 1 212 %cmp.eq = icmp eq i32 %a, %b 213 %sel.eq = select i1 %cmp.eq, i8 0, i8 %sel.lt 214 ret i8 %sel.eq 215} 216 217define i8 @strong_order_cmp_ult_eq_wrong_const(i32 %a, i32 %b) { 218; CHECK-LABEL: @strong_order_cmp_ult_eq_wrong_const( 219; CHECK-NEXT: [[CMP_LT:%.*]] = icmp ult i32 [[A:%.*]], [[B:%.*]] 220; CHECK-NEXT: [[SEL_LT:%.*]] = select i1 [[CMP_LT]], i8 -1, i8 3 221; CHECK-NEXT: [[CMP_EQ:%.*]] = icmp eq i32 [[A]], [[B]] 222; CHECK-NEXT: [[SEL_EQ:%.*]] = select i1 [[CMP_EQ]], i8 0, i8 [[SEL_LT]] 223; CHECK-NEXT: ret i8 [[SEL_EQ]] 224; 225 %cmp.lt = icmp ult i32 %a, %b 226 %sel.lt = select i1 %cmp.lt, i8 -1, i8 3 227 %cmp.eq = icmp eq i32 %a, %b 228 %sel.eq = select i1 %cmp.eq, i8 0, i8 %sel.lt 229 ret i8 %sel.eq 230} 231 232define i8 @strong_order_cmp_slt_ult_wrong_pred(i32 %a, i32 %b) { 233; CHECK-LABEL: @strong_order_cmp_slt_ult_wrong_pred( 234; CHECK-NEXT: [[CMP_LT:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]] 235; CHECK-NEXT: [[SEL_LT:%.*]] = select i1 [[CMP_LT]], i8 -1, i8 1 236; CHECK-NEXT: [[CMP_EQ:%.*]] = icmp ult i32 [[A]], [[B]] 237; CHECK-NEXT: [[SEL_EQ:%.*]] = select i1 [[CMP_EQ]], i8 0, i8 [[SEL_LT]] 238; CHECK-NEXT: ret i8 [[SEL_EQ]] 239; 240 %cmp.lt = icmp slt i32 %a, %b 241 %sel.lt = select i1 %cmp.lt, i8 -1, i8 1 242 %cmp.eq = icmp ult i32 %a, %b 243 %sel.eq = select i1 %cmp.eq, i8 0, i8 %sel.lt 244 ret i8 %sel.eq 245} 246 247define i8 @strong_order_cmp_sgt_eq(i32 %a, i32 %b) { 248; CHECK-LABEL: @strong_order_cmp_sgt_eq( 249; CHECK-NEXT: [[SEL_EQ:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[A:%.*]], i32 [[B:%.*]]) 250; CHECK-NEXT: ret i8 [[SEL_EQ]] 251; 252 %cmp.gt = icmp sgt i32 %a, %b 253 %sel.gt = select i1 %cmp.gt, i8 1, i8 -1 254 %cmp.eq = icmp eq i32 %a, %b 255 %sel.eq = select i1 %cmp.eq, i8 0, i8 %sel.gt 256 ret i8 %sel.eq 257} 258 259define i8 @strong_order_cmp_ugt_eq(i32 %a, i32 %b) { 260; CHECK-LABEL: @strong_order_cmp_ugt_eq( 261; CHECK-NEXT: [[SEL_EQ:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[A:%.*]], i32 [[B:%.*]]) 262; CHECK-NEXT: ret i8 [[SEL_EQ]] 263; 264 %cmp.gt = icmp ugt i32 %a, %b 265 %sel.gt = select i1 %cmp.gt, i8 1, i8 -1 266 %cmp.eq = icmp eq i32 %a, %b 267 %sel.eq = select i1 %cmp.eq, i8 0, i8 %sel.gt 268 ret i8 %sel.eq 269} 270 271define i8 @strong_order_cmp_eq_slt(i32 %a, i32 %b) { 272; CHECK-LABEL: @strong_order_cmp_eq_slt( 273; CHECK-NEXT: [[SEL_LT:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[A:%.*]], i32 [[B:%.*]]) 274; CHECK-NEXT: ret i8 [[SEL_LT]] 275; 276 %cmp.eq = icmp eq i32 %a, %b 277 %sel.eq = select i1 %cmp.eq, i8 0, i8 1 278 %cmp.lt = icmp slt i32 %a, %b 279 %sel.lt = select i1 %cmp.lt, i8 -1, i8 %sel.eq 280 ret i8 %sel.lt 281} 282 283define i8 @strong_order_cmp_eq_sgt(i32 %a, i32 %b) { 284; CHECK-LABEL: @strong_order_cmp_eq_sgt( 285; CHECK-NEXT: [[SEL_GT:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[A:%.*]], i32 [[B:%.*]]) 286; CHECK-NEXT: ret i8 [[SEL_GT]] 287; 288 %cmp.eq = icmp eq i32 %a, %b 289 %sel.eq = select i1 %cmp.eq, i8 0, i8 -1 290 %cmp.gt = icmp sgt i32 %a, %b 291 %sel.gt = select i1 %cmp.gt, i8 1, i8 %sel.eq 292 ret i8 %sel.gt 293} 294 295define i8 @strong_order_cmp_eq_ult(i32 %a, i32 %b) { 296; CHECK-LABEL: @strong_order_cmp_eq_ult( 297; CHECK-NEXT: [[SEL_LT:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[A:%.*]], i32 [[B:%.*]]) 298; CHECK-NEXT: ret i8 [[SEL_LT]] 299; 300 %cmp.eq = icmp eq i32 %a, %b 301 %sel.eq = select i1 %cmp.eq, i8 0, i8 1 302 %cmp.lt = icmp ult i32 %a, %b 303 %sel.lt = select i1 %cmp.lt, i8 -1, i8 %sel.eq 304 ret i8 %sel.lt 305} 306 307define i8 @strong_order_cmp_eq_ugt(i32 %a, i32 %b) { 308; CHECK-LABEL: @strong_order_cmp_eq_ugt( 309; CHECK-NEXT: [[SEL_GT:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[A:%.*]], i32 [[B:%.*]]) 310; CHECK-NEXT: ret i8 [[SEL_GT]] 311; 312 %cmp.eq = icmp eq i32 %a, %b 313 %sel.eq = select i1 %cmp.eq, i8 0, i8 -1 314 %cmp.gt = icmp ugt i32 %a, %b 315 %sel.gt = select i1 %cmp.gt, i8 1, i8 %sel.eq 316 ret i8 %sel.gt 317} 318 319define i8 @strong_order_cmp_slt_sgt(i32 %a, i32 %b) { 320; CHECK-LABEL: @strong_order_cmp_slt_sgt( 321; CHECK-NEXT: [[SEL_GT:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[A:%.*]], i32 [[B:%.*]]) 322; CHECK-NEXT: ret i8 [[SEL_GT]] 323; 324 %cmp.lt = icmp slt i32 %a, %b 325 %sext = sext i1 %cmp.lt to i8 326 %cmp.gt = icmp sgt i32 %a, %b 327 %sel.gt = select i1 %cmp.gt, i8 1, i8 %sext 328 ret i8 %sel.gt 329} 330 331define i8 @strong_order_cmp_ult_ugt(i32 %a, i32 %b) { 332; CHECK-LABEL: @strong_order_cmp_ult_ugt( 333; CHECK-NEXT: [[SEL_GT:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[A:%.*]], i32 [[B:%.*]]) 334; CHECK-NEXT: ret i8 [[SEL_GT]] 335; 336 %cmp.lt = icmp ult i32 %a, %b 337 %sext = sext i1 %cmp.lt to i8 338 %cmp.gt = icmp ugt i32 %a, %b 339 %sel.gt = select i1 %cmp.gt, i8 1, i8 %sext 340 ret i8 %sel.gt 341} 342 343define i8 @strong_order_cmp_sgt_slt(i32 %a, i32 %b) { 344; CHECK-LABEL: @strong_order_cmp_sgt_slt( 345; CHECK-NEXT: [[SEL_LT:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[A:%.*]], i32 [[B:%.*]]) 346; CHECK-NEXT: ret i8 [[SEL_LT]] 347; 348 %cmp.gt = icmp sgt i32 %a, %b 349 %zext = zext i1 %cmp.gt to i8 350 %cmp.lt = icmp slt i32 %a, %b 351 %sel.lt = select i1 %cmp.lt, i8 -1, i8 %zext 352 ret i8 %sel.lt 353} 354 355define i8 @strong_order_cmp_ugt_ult(i32 %a, i32 %b) { 356; CHECK-LABEL: @strong_order_cmp_ugt_ult( 357; CHECK-NEXT: [[SEL_LT:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[A:%.*]], i32 [[B:%.*]]) 358; CHECK-NEXT: ret i8 [[SEL_LT]] 359; 360 %cmp.gt = icmp ugt i32 %a, %b 361 %zext = zext i1 %cmp.gt to i8 362 %cmp.lt = icmp ult i32 %a, %b 363 %sel.lt = select i1 %cmp.lt, i8 -1, i8 %zext 364 ret i8 %sel.lt 365} 366 367define i8 @strong_order_cmp_ne_ugt_ne_not_one_use(i32 %a, i32 %b) { 368; CHECK-LABEL: @strong_order_cmp_ne_ugt_ne_not_one_use( 369; CHECK-NEXT: [[CMP_NE:%.*]] = icmp ne i32 [[A:%.*]], [[B:%.*]] 370; CHECK-NEXT: call void @use1(i1 [[CMP_NE]]) 371; CHECK-NEXT: [[SEL_GT:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[A]], i32 [[B]]) 372; CHECK-NEXT: ret i8 [[SEL_GT]] 373; 374 %cmp.ne = icmp ne i32 %a, %b 375 call void @use1(i1 %cmp.ne) 376 %sel.eq = sext i1 %cmp.ne to i8 377 %cmp.gt = icmp ugt i32 %a, %b 378 %sel.gt = select i1 %cmp.gt, i8 1, i8 %sel.eq 379 ret i8 %sel.gt 380} 381 382define i8 @strong_order_cmp_slt_eq_slt_not_oneuse(i32 %a, i32 %b) { 383; CHECK-LABEL: @strong_order_cmp_slt_eq_slt_not_oneuse( 384; CHECK-NEXT: [[CMP_LT:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]] 385; CHECK-NEXT: call void @use1(i1 [[CMP_LT]]) 386; CHECK-NEXT: [[SEL_EQ:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[A]], i32 [[B]]) 387; CHECK-NEXT: ret i8 [[SEL_EQ]] 388; 389 %cmp.lt = icmp slt i32 %a, %b 390 call void @use1(i1 %cmp.lt) 391 %sel.lt = select i1 %cmp.lt, i8 -1, i8 1 392 %cmp.eq = icmp eq i32 %a, %b 393 %sel.eq = select i1 %cmp.eq, i8 0, i8 %sel.lt 394 ret i8 %sel.eq 395} 396 397define i8 @strong_order_cmp_sgt_eq_eq_not_oneuse(i32 %a, i32 %b) { 398; CHECK-LABEL: @strong_order_cmp_sgt_eq_eq_not_oneuse( 399; CHECK-NEXT: [[CMP_EQ:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]] 400; CHECK-NEXT: call void @use1(i1 [[CMP_EQ]]) 401; CHECK-NEXT: [[SEL_EQ:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[A]], i32 [[B]]) 402; CHECK-NEXT: ret i8 [[SEL_EQ]] 403; 404 %cmp.gt = icmp sgt i32 %a, %b 405 %sel.gt = select i1 %cmp.gt, i8 1, i8 -1 406 %cmp.eq = icmp eq i32 %a, %b 407 call void @use1(i1 %cmp.eq) 408 %sel.eq = select i1 %cmp.eq, i8 0, i8 %sel.gt 409 ret i8 %sel.eq 410} 411 412define i8 @strong_order_cmp_eq_ugt_eq_not_oneuse(i32 %a, i32 %b) { 413; CHECK-LABEL: @strong_order_cmp_eq_ugt_eq_not_oneuse( 414; CHECK-NEXT: [[CMP_EQ:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]] 415; CHECK-NEXT: call void @use1(i1 [[CMP_EQ]]) 416; CHECK-NEXT: [[NOT_CMP_EQ:%.*]] = xor i1 [[CMP_EQ]], true 417; CHECK-NEXT: [[SEL_EQ:%.*]] = sext i1 [[NOT_CMP_EQ]] to i8 418; CHECK-NEXT: [[CMP_GT:%.*]] = icmp ugt i32 [[A]], [[B]] 419; CHECK-NEXT: [[SEL_GT:%.*]] = select i1 [[CMP_GT]], i8 1, i8 [[SEL_EQ]] 420; CHECK-NEXT: ret i8 [[SEL_GT]] 421; 422 %cmp.eq = icmp eq i32 %a, %b 423 call void @use1(i1 %cmp.eq) 424 %sel.eq = select i1 %cmp.eq, i8 0, i8 -1 425 %cmp.gt = icmp ugt i32 %a, %b 426 %sel.gt = select i1 %cmp.gt, i8 1, i8 %sel.eq 427 ret i8 %sel.gt 428} 429 430define i8 @strong_order_cmp_ugt_ult_zext_not_oneuse(i32 %a, i32 %b) { 431; CHECK-LABEL: @strong_order_cmp_ugt_ult_zext_not_oneuse( 432; CHECK-NEXT: [[CMP_GT:%.*]] = icmp ugt i32 [[A:%.*]], [[B:%.*]] 433; CHECK-NEXT: [[ZEXT:%.*]] = zext i1 [[CMP_GT]] to i8 434; CHECK-NEXT: call void @use8(i8 [[ZEXT]]) 435; CHECK-NEXT: [[SEL_LT:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[A]], i32 [[B]]) 436; CHECK-NEXT: ret i8 [[SEL_LT]] 437; 438 %cmp.gt = icmp ugt i32 %a, %b 439 %zext = zext i1 %cmp.gt to i8 440 call void @use8(i8 %zext) 441 %cmp.lt = icmp ult i32 %a, %b 442 %sel.lt = select i1 %cmp.lt, i8 -1, i8 %zext 443 ret i8 %sel.lt 444} 445 446define i8 @strong_order_cmp_slt_sgt_sext_not_oneuse(i32 %a, i32 %b) { 447; CHECK-LABEL: @strong_order_cmp_slt_sgt_sext_not_oneuse( 448; CHECK-NEXT: [[CMP_LT:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]] 449; CHECK-NEXT: [[SEXT:%.*]] = sext i1 [[CMP_LT]] to i8 450; CHECK-NEXT: call void @use8(i8 [[SEXT]]) 451; CHECK-NEXT: [[SEL_GT:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[A]], i32 [[B]]) 452; CHECK-NEXT: ret i8 [[SEL_GT]] 453; 454 %cmp.lt = icmp slt i32 %a, %b 455 %sext = sext i1 %cmp.lt to i8 456 call void @use8(i8 %sext) 457 %cmp.gt = icmp sgt i32 %a, %b 458 %sel.gt = select i1 %cmp.gt, i8 1, i8 %sext 459 ret i8 %sel.gt 460} 461 462define <2 x i8> @strong_order_cmp_ugt_ult_vector(<2 x i32> %a, <2 x i32> %b) { 463; CHECK-LABEL: @strong_order_cmp_ugt_ult_vector( 464; CHECK-NEXT: [[SEL_LT:%.*]] = call <2 x i8> @llvm.ucmp.v2i8.v2i32(<2 x i32> [[A:%.*]], <2 x i32> [[B:%.*]]) 465; CHECK-NEXT: ret <2 x i8> [[SEL_LT]] 466; 467 %cmp.gt = icmp ugt <2 x i32> %a, %b 468 %zext = zext <2 x i1> %cmp.gt to <2 x i8> 469 %cmp.lt = icmp ult <2 x i32> %a, %b 470 %sel.lt = select <2 x i1> %cmp.lt, <2 x i8> <i8 -1, i8 -1>, <2 x i8> %zext 471 ret <2 x i8> %sel.lt 472} 473 474define <2 x i8> @strong_order_cmp_ugt_ult_vector_poison(<2 x i32> %a, <2 x i32> %b) { 475; CHECK-LABEL: @strong_order_cmp_ugt_ult_vector_poison( 476; CHECK-NEXT: [[SEL_LT:%.*]] = call <2 x i8> @llvm.ucmp.v2i8.v2i32(<2 x i32> [[A:%.*]], <2 x i32> [[B:%.*]]) 477; CHECK-NEXT: ret <2 x i8> [[SEL_LT]] 478; 479 %cmp.gt = icmp ugt <2 x i32> %a, %b 480 %zext = zext <2 x i1> %cmp.gt to <2 x i8> 481 %cmp.lt = icmp ult <2 x i32> %a, %b 482 %sel.lt = select <2 x i1> %cmp.lt, <2 x i8> <i8 poison, i8 -1>, <2 x i8> %zext 483 ret <2 x i8> %sel.lt 484} 485 486define <2 x i8> @strong_order_cmp_eq_ugt_vector(<2 x i32> %a, <2 x i32> %b) { 487; CHECK-LABEL: @strong_order_cmp_eq_ugt_vector( 488; CHECK-NEXT: [[SEL_GT:%.*]] = call <2 x i8> @llvm.ucmp.v2i8.v2i32(<2 x i32> [[A:%.*]], <2 x i32> [[B:%.*]]) 489; CHECK-NEXT: ret <2 x i8> [[SEL_GT]] 490; 491 %cmp.eq = icmp eq <2 x i32> %a, %b 492 %sel.eq = select <2 x i1> %cmp.eq, <2 x i8> <i8 0, i8 0>, <2 x i8> <i8 -1, i8 -1> 493 %cmp.gt = icmp ugt <2 x i32> %a, %b 494 %sel.gt = select <2 x i1> %cmp.gt, <2 x i8> <i8 1, i8 1>, <2 x i8> %sel.eq 495 ret <2 x i8> %sel.gt 496} 497 498define <2 x i8> @strong_order_cmp_eq_ugt_vector_poison1(<2 x i32> %a, <2 x i32> %b) { 499; CHECK-LABEL: @strong_order_cmp_eq_ugt_vector_poison1( 500; CHECK-NEXT: [[SEL_GT:%.*]] = call <2 x i8> @llvm.ucmp.v2i8.v2i32(<2 x i32> [[A:%.*]], <2 x i32> [[B:%.*]]) 501; CHECK-NEXT: ret <2 x i8> [[SEL_GT]] 502; 503 %cmp.eq = icmp eq <2 x i32> %a, %b 504 %sel.eq = select <2 x i1> %cmp.eq, <2 x i8> <i8 0, i8 poison>, <2 x i8> <i8 -1, i8 -1> 505 %cmp.gt = icmp ugt <2 x i32> %a, %b 506 %sel.gt = select <2 x i1> %cmp.gt, <2 x i8> <i8 1, i8 1>, <2 x i8> %sel.eq 507 ret <2 x i8> %sel.gt 508} 509 510define <2 x i8> @strong_order_cmp_eq_ugt_vector_poison2(<2 x i32> %a, <2 x i32> %b) { 511; CHECK-LABEL: @strong_order_cmp_eq_ugt_vector_poison2( 512; CHECK-NEXT: [[SEL_GT:%.*]] = call <2 x i8> @llvm.ucmp.v2i8.v2i32(<2 x i32> [[A:%.*]], <2 x i32> [[B:%.*]]) 513; CHECK-NEXT: ret <2 x i8> [[SEL_GT]] 514; 515 %cmp.eq = icmp eq <2 x i32> %a, %b 516 %sel.eq = select <2 x i1> %cmp.eq, <2 x i8> <i8 0, i8 0>, <2 x i8> <i8 poison, i8 -1> 517 %cmp.gt = icmp ugt <2 x i32> %a, %b 518 %sel.gt = select <2 x i1> %cmp.gt, <2 x i8> <i8 1, i8 1>, <2 x i8> %sel.eq 519 ret <2 x i8> %sel.gt 520} 521 522define <2 x i8> @strong_order_cmp_eq_ugt_vector_poison3(<2 x i32> %a, <2 x i32> %b) { 523; CHECK-LABEL: @strong_order_cmp_eq_ugt_vector_poison3( 524; CHECK-NEXT: [[SEL_GT:%.*]] = call <2 x i8> @llvm.ucmp.v2i8.v2i32(<2 x i32> [[A:%.*]], <2 x i32> [[B:%.*]]) 525; CHECK-NEXT: ret <2 x i8> [[SEL_GT]] 526; 527 %cmp.eq = icmp eq <2 x i32> %a, %b 528 %sel.eq = select <2 x i1> %cmp.eq, <2 x i8> <i8 0, i8 0>, <2 x i8> <i8 -1, i8 -1> 529 %cmp.gt = icmp ugt <2 x i32> %a, %b 530 %sel.gt = select <2 x i1> %cmp.gt, <2 x i8> <i8 1, i8 poison>, <2 x i8> %sel.eq 531 ret <2 x i8> %sel.gt 532} 533 534 535 536declare void @use1(i1) 537declare void @use8(i8) 538