1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -instcombine -S | FileCheck %s 3 4; Given a pattern like: 5; %old_cmp1 = icmp slt i32 %x, C2 6; %old_replacement = select i1 %old_cmp1, i32 %target_low, i32 %target_high 7; %old_x_offseted = add i32 %x, C1 8; %old_cmp0 = icmp ult i32 %old_x_offseted, C0 9; %r = select i1 %old_cmp0, i32 %x, i32 %old_replacement 10; it can be rewriten as more canonical pattern: 11; %new_cmp1 = icmp slt i32 %x, -C1 12; %new_cmp2 = icmp sge i32 %x, C0-C1 13; %new_clamped_low = select i1 %new_cmp1, i32 %target_low, i32 %x 14; %r = select i1 %new_cmp2, i32 %target_high, i32 %new_clamped_low 15; Iff -C1 s<= C2 s<= C0-C1 16; Also, ULT predicate can also be UGE; or UGT iff C0 != -1 (+invert result) 17; Also, SLT predicate can also be SGE; or SGT iff C2 != INT_MAX (+invert res.) 18 19;------------------------------------------------------------------------------- 20 21; Basic pattern. There is no 'and', so lower threshold is 0 (inclusive). 22; The upper threshold is 127 (inclusive). 23; There are 2 icmp's so for scalars there are 4 possible combinations. 24; The constant in %t0 has to be between the thresholds, i.e 128 <= Ct0 <= 0. 25 26define i32 @t0_ult_slt_128(i32 %x, i32 %replacement_low, i32 %replacement_high) { 27; CHECK-LABEL: @t0_ult_slt_128( 28; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], -16 29; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[X]], 127 30; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP1]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[X]] 31; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP2]], i32 [[REPLACEMENT_HIGH:%.*]], i32 [[TMP3]] 32; CHECK-NEXT: ret i32 [[R]] 33; 34 %t0 = icmp slt i32 %x, 128 35 %t1 = select i1 %t0, i32 %replacement_low, i32 %replacement_high 36 %t2 = add i32 %x, 16 37 %t3 = icmp ult i32 %t2, 144 38 %r = select i1 %t3, i32 %x, i32 %t1 39 ret i32 %r 40} 41define i32 @t1_ult_slt_0(i32 %x, i32 %replacement_low, i32 %replacement_high) { 42; CHECK-LABEL: @t1_ult_slt_0( 43; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], -16 44; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[X]], 127 45; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP1]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[X]] 46; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP2]], i32 [[REPLACEMENT_HIGH:%.*]], i32 [[TMP3]] 47; CHECK-NEXT: ret i32 [[R]] 48; 49 %t0 = icmp slt i32 %x, -16 50 %t1 = select i1 %t0, i32 %replacement_low, i32 %replacement_high 51 %t2 = add i32 %x, 16 52 %t3 = icmp ult i32 %t2, 144 53 %r = select i1 %t3, i32 %x, i32 %t1 54 ret i32 %r 55} 56 57define i32 @t2_ult_sgt_128(i32 %x, i32 %replacement_low, i32 %replacement_high) { 58; CHECK-LABEL: @t2_ult_sgt_128( 59; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], -16 60; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[X]], 127 61; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP1]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[X]] 62; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP2]], i32 [[REPLACEMENT_HIGH:%.*]], i32 [[TMP3]] 63; CHECK-NEXT: ret i32 [[R]] 64; 65 %t0 = icmp sgt i32 %x, 127 66 %t1 = select i1 %t0, i32 %replacement_high, i32 %replacement_low 67 %t2 = add i32 %x, 16 68 %t3 = icmp ult i32 %t2, 144 69 %r = select i1 %t3, i32 %x, i32 %t1 70 ret i32 %r 71} 72define i32 @t3_ult_sgt_neg1(i32 %x, i32 %replacement_low, i32 %replacement_high) { 73; CHECK-LABEL: @t3_ult_sgt_neg1( 74; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], -16 75; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[X]], 127 76; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP1]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[X]] 77; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP2]], i32 [[REPLACEMENT_HIGH:%.*]], i32 [[TMP3]] 78; CHECK-NEXT: ret i32 [[R]] 79; 80 %t0 = icmp sgt i32 %x, -17 81 %t1 = select i1 %t0, i32 %replacement_high, i32 %replacement_low 82 %t2 = add i32 %x, 16 83 %t3 = icmp ult i32 %t2, 144 84 %r = select i1 %t3, i32 %x, i32 %t1 85 ret i32 %r 86} 87 88define i32 @t4_ugt_slt_128(i32 %x, i32 %replacement_low, i32 %replacement_high) { 89; CHECK-LABEL: @t4_ugt_slt_128( 90; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], -16 91; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[X]], 127 92; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP1]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[X]] 93; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP2]], i32 [[REPLACEMENT_HIGH:%.*]], i32 [[TMP3]] 94; CHECK-NEXT: ret i32 [[R]] 95; 96 %t0 = icmp slt i32 %x, 128 97 %t1 = select i1 %t0, i32 %replacement_low, i32 %replacement_high 98 %t2 = add i32 %x, 16 99 %t3 = icmp ugt i32 %t2, 143 100 %r = select i1 %t3, i32 %t1, i32 %x 101 ret i32 %r 102} 103define i32 @t5_ugt_slt_0(i32 %x, i32 %replacement_low, i32 %replacement_high) { 104; CHECK-LABEL: @t5_ugt_slt_0( 105; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], -16 106; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[X]], 127 107; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP1]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[X]] 108; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP2]], i32 [[REPLACEMENT_HIGH:%.*]], i32 [[TMP3]] 109; CHECK-NEXT: ret i32 [[R]] 110; 111 %t0 = icmp slt i32 %x, -16 112 %t1 = select i1 %t0, i32 %replacement_low, i32 %replacement_high 113 %t2 = add i32 %x, 16 114 %t3 = icmp ugt i32 %t2, 143 115 %r = select i1 %t3, i32 %t1, i32 %x 116 ret i32 %r 117} 118 119define i32 @t6_ugt_sgt_128(i32 %x, i32 %replacement_low, i32 %replacement_high) { 120; CHECK-LABEL: @t6_ugt_sgt_128( 121; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], -16 122; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[X]], 127 123; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP1]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[X]] 124; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP2]], i32 [[REPLACEMENT_HIGH:%.*]], i32 [[TMP3]] 125; CHECK-NEXT: ret i32 [[R]] 126; 127 %t0 = icmp sgt i32 %x, 127 128 %t1 = select i1 %t0, i32 %replacement_high, i32 %replacement_low 129 %t2 = add i32 %x, 16 130 %t3 = icmp ugt i32 %t2, 143 131 %r = select i1 %t3, i32 %t1, i32 %x 132 ret i32 %r 133} 134define i32 @t7_ugt_sgt_neg1(i32 %x, i32 %replacement_low, i32 %replacement_high) { 135; CHECK-LABEL: @t7_ugt_sgt_neg1( 136; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], -16 137; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[X]], 127 138; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP1]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[X]] 139; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP2]], i32 [[REPLACEMENT_HIGH:%.*]], i32 [[TMP3]] 140; CHECK-NEXT: ret i32 [[R]] 141; 142 %t0 = icmp sgt i32 %x, -17 143 %t1 = select i1 %t0, i32 %replacement_high, i32 %replacement_low 144 %t2 = add i32 %x, 16 145 %t3 = icmp ugt i32 %t2, 143 146 %r = select i1 %t3, i32 %t1, i32 %x 147 ret i32 %r 148} 149 150;------------------------------------------------------------------------------- 151 152; So Ct0 can not be s> 128, or s< -16 153 154define i32 @n8_ult_slt_129(i32 %x, i32 %replacement_low, i32 %replacement_high) { 155; CHECK-LABEL: @n8_ult_slt_129( 156; CHECK-NEXT: [[T0:%.*]] = icmp slt i32 [[X:%.*]], 129 157; CHECK-NEXT: [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[REPLACEMENT_HIGH:%.*]] 158; CHECK-NEXT: [[T2:%.*]] = add i32 [[X]], 16 159; CHECK-NEXT: [[T3:%.*]] = icmp ult i32 [[T2]], 144 160; CHECK-NEXT: [[R:%.*]] = select i1 [[T3]], i32 [[X]], i32 [[T1]] 161; CHECK-NEXT: ret i32 [[R]] 162; 163 %t0 = icmp slt i32 %x, 129 164 %t1 = select i1 %t0, i32 %replacement_low, i32 %replacement_high 165 %t2 = add i32 %x, 16 166 %t3 = icmp ult i32 %t2, 144 167 %r = select i1 %t3, i32 %x, i32 %t1 168 ret i32 %r 169} 170define i32 @n9_ult_slt_neg17(i32 %x, i32 %replacement_low, i32 %replacement_high) { 171; CHECK-LABEL: @n9_ult_slt_neg17( 172; CHECK-NEXT: [[T0:%.*]] = icmp slt i32 [[X:%.*]], -17 173; CHECK-NEXT: [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[REPLACEMENT_HIGH:%.*]] 174; CHECK-NEXT: [[T2:%.*]] = add i32 [[X]], 16 175; CHECK-NEXT: [[T3:%.*]] = icmp ult i32 [[T2]], 144 176; CHECK-NEXT: [[R:%.*]] = select i1 [[T3]], i32 [[X]], i32 [[T1]] 177; CHECK-NEXT: ret i32 [[R]] 178; 179 %t0 = icmp slt i32 %x, -17 180 %t1 = select i1 %t0, i32 %replacement_low, i32 %replacement_high 181 %t2 = add i32 %x, 16 182 %t3 = icmp ult i32 %t2, 144 183 %r = select i1 %t3, i32 %x, i32 %t1 184 ret i32 %r 185} 186 187;------------------------------------------------------------------------------- 188 189declare void @use32(i32) 190declare void @use1(i1) 191 192; One-use restrictions: here the entire pattern needs to be one-use. 193; FIXME: if %t0 could be reused then it's less restrictive. 194 195; This one is ok. 196define i32 @t10_oneuse0(i32 %x, i32 %replacement_low, i32 %replacement_high) { 197; CHECK-LABEL: @t10_oneuse0( 198; CHECK-NEXT: [[T0:%.*]] = icmp slt i32 [[X:%.*]], 64 199; CHECK-NEXT: call void @use1(i1 [[T0]]) 200; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[X]], -16 201; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[X]], 127 202; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP1]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[X]] 203; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP2]], i32 [[REPLACEMENT_HIGH:%.*]], i32 [[TMP3]] 204; CHECK-NEXT: ret i32 [[R]] 205; 206 %t0 = icmp slt i32 %x, 64 207 call void @use1(i1 %t0) 208 %t1 = select i1 %t0, i32 %replacement_low, i32 %replacement_high 209 %t2 = add i32 %x, 16 210 %t3 = icmp ult i32 %t2, 144 211 %r = select i1 %t3, i32 %x, i32 %t1 212 ret i32 %r 213} 214define i32 @n11_oneuse1(i32 %x, i32 %replacement_low, i32 %replacement_high) { 215; CHECK-LABEL: @n11_oneuse1( 216; CHECK-NEXT: [[T0:%.*]] = icmp slt i32 [[X:%.*]], 64 217; CHECK-NEXT: [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[REPLACEMENT_HIGH:%.*]] 218; CHECK-NEXT: call void @use32(i32 [[T1]]) 219; CHECK-NEXT: [[T2:%.*]] = add i32 [[X]], 16 220; CHECK-NEXT: [[T3:%.*]] = icmp ult i32 [[T2]], 144 221; CHECK-NEXT: [[R:%.*]] = select i1 [[T3]], i32 [[X]], i32 [[T1]] 222; CHECK-NEXT: ret i32 [[R]] 223; 224 %t0 = icmp slt i32 %x, 64 225 %t1 = select i1 %t0, i32 %replacement_low, i32 %replacement_high 226 call void @use32(i32 %t1) 227 %t2 = add i32 %x, 16 228 %t3 = icmp ult i32 %t2, 144 229 %r = select i1 %t3, i32 %x, i32 %t1 230 ret i32 %r 231} 232 233; This one is ok. 234define i32 @t12_oneuse2(i32 %x, i32 %replacement_low, i32 %replacement_high) { 235; CHECK-LABEL: @t12_oneuse2( 236; CHECK-NEXT: [[T2:%.*]] = add i32 [[X:%.*]], 16 237; CHECK-NEXT: call void @use32(i32 [[T2]]) 238; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[X]], -16 239; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[X]], 127 240; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP1]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[X]] 241; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP2]], i32 [[REPLACEMENT_HIGH:%.*]], i32 [[TMP3]] 242; CHECK-NEXT: ret i32 [[R]] 243; 244 %t0 = icmp slt i32 %x, 64 245 %t1 = select i1 %t0, i32 %replacement_low, i32 %replacement_high 246 %t2 = add i32 %x, 16 247 call void @use32(i32 %t2) 248 %t3 = icmp ult i32 %t2, 144 249 %r = select i1 %t3, i32 %x, i32 %t1 250 ret i32 %r 251} 252 253define i32 @n13_oneuse3(i32 %x, i32 %replacement_low, i32 %replacement_high) { 254; CHECK-LABEL: @n13_oneuse3( 255; CHECK-NEXT: [[T0:%.*]] = icmp slt i32 [[X:%.*]], 64 256; CHECK-NEXT: [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[REPLACEMENT_HIGH:%.*]] 257; CHECK-NEXT: [[T2:%.*]] = add i32 [[X]], 16 258; CHECK-NEXT: [[T3:%.*]] = icmp ult i32 [[T2]], 144 259; CHECK-NEXT: call void @use1(i1 [[T3]]) 260; CHECK-NEXT: [[R:%.*]] = select i1 [[T3]], i32 [[X]], i32 [[T1]] 261; CHECK-NEXT: ret i32 [[R]] 262; 263 %t0 = icmp slt i32 %x, 64 264 %t1 = select i1 %t0, i32 %replacement_low, i32 %replacement_high 265 %t2 = add i32 %x, 16 266 %t3 = icmp ult i32 %t2, 144 267 call void @use1(i1 %t3) 268 %r = select i1 %t3, i32 %x, i32 %t1 269 ret i32 %r 270} 271 272define i32 @n14_oneuse4(i32 %x, i32 %replacement_low, i32 %replacement_high) { 273; CHECK-LABEL: @n14_oneuse4( 274; CHECK-NEXT: [[T0:%.*]] = icmp slt i32 [[X:%.*]], 64 275; CHECK-NEXT: call void @use1(i1 [[T0]]) 276; CHECK-NEXT: [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[REPLACEMENT_HIGH:%.*]] 277; CHECK-NEXT: call void @use32(i32 [[T1]]) 278; CHECK-NEXT: [[T2:%.*]] = add i32 [[X]], 16 279; CHECK-NEXT: [[T3:%.*]] = icmp ult i32 [[T2]], 144 280; CHECK-NEXT: [[R:%.*]] = select i1 [[T3]], i32 [[X]], i32 [[T1]] 281; CHECK-NEXT: ret i32 [[R]] 282; 283 %t0 = icmp slt i32 %x, 64 284 call void @use1(i1 %t0) 285 %t1 = select i1 %t0, i32 %replacement_low, i32 %replacement_high 286 call void @use32(i32 %t1) 287 %t2 = add i32 %x, 16 288 %t3 = icmp ult i32 %t2, 144 289 %r = select i1 %t3, i32 %x, i32 %t1 290 ret i32 %r 291} 292define i32 @n15_oneuse5(i32 %x, i32 %replacement_low, i32 %replacement_high) { 293; CHECK-LABEL: @n15_oneuse5( 294; CHECK-NEXT: [[T0:%.*]] = icmp slt i32 [[X:%.*]], 64 295; CHECK-NEXT: call void @use1(i1 [[T0]]) 296; CHECK-NEXT: [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[REPLACEMENT_HIGH:%.*]] 297; CHECK-NEXT: [[T2:%.*]] = add i32 [[X]], 16 298; CHECK-NEXT: call void @use32(i32 [[T2]]) 299; CHECK-NEXT: [[T3:%.*]] = icmp ult i32 [[T2]], 144 300; CHECK-NEXT: [[R:%.*]] = select i1 [[T3]], i32 [[X]], i32 [[T1]] 301; CHECK-NEXT: ret i32 [[R]] 302; 303 %t0 = icmp slt i32 %x, 64 304 call void @use1(i1 %t0) 305 %t1 = select i1 %t0, i32 %replacement_low, i32 %replacement_high 306 %t2 = add i32 %x, 16 307 call void @use32(i32 %t2) 308 %t3 = icmp ult i32 %t2, 144 309 %r = select i1 %t3, i32 %x, i32 %t1 310 ret i32 %r 311} 312define i32 @n16_oneuse6(i32 %x, i32 %replacement_low, i32 %replacement_high) { 313; CHECK-LABEL: @n16_oneuse6( 314; CHECK-NEXT: [[T0:%.*]] = icmp slt i32 [[X:%.*]], 64 315; CHECK-NEXT: call void @use1(i1 [[T0]]) 316; CHECK-NEXT: [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[REPLACEMENT_HIGH:%.*]] 317; CHECK-NEXT: [[T2:%.*]] = add i32 [[X]], 16 318; CHECK-NEXT: [[T3:%.*]] = icmp ult i32 [[T2]], 144 319; CHECK-NEXT: call void @use1(i1 [[T3]]) 320; CHECK-NEXT: [[R:%.*]] = select i1 [[T3]], i32 [[X]], i32 [[T1]] 321; CHECK-NEXT: ret i32 [[R]] 322; 323 %t0 = icmp slt i32 %x, 64 324 call void @use1(i1 %t0) 325 %t1 = select i1 %t0, i32 %replacement_low, i32 %replacement_high 326 %t2 = add i32 %x, 16 327 %t3 = icmp ult i32 %t2, 144 328 call void @use1(i1 %t3) 329 %r = select i1 %t3, i32 %x, i32 %t1 330 ret i32 %r 331} 332 333define i32 @n17_oneuse7(i32 %x, i32 %replacement_low, i32 %replacement_high) { 334; CHECK-LABEL: @n17_oneuse7( 335; CHECK-NEXT: [[T0:%.*]] = icmp slt i32 [[X:%.*]], 64 336; CHECK-NEXT: call void @use1(i1 [[T0]]) 337; CHECK-NEXT: [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[REPLACEMENT_HIGH:%.*]] 338; CHECK-NEXT: call void @use32(i32 [[T1]]) 339; CHECK-NEXT: [[T2:%.*]] = add i32 [[X]], 16 340; CHECK-NEXT: call void @use32(i32 [[T2]]) 341; CHECK-NEXT: [[T3:%.*]] = icmp ult i32 [[T2]], 144 342; CHECK-NEXT: [[R:%.*]] = select i1 [[T3]], i32 [[X]], i32 [[T1]] 343; CHECK-NEXT: ret i32 [[R]] 344; 345 %t0 = icmp slt i32 %x, 64 346 call void @use1(i1 %t0) 347 %t1 = select i1 %t0, i32 %replacement_low, i32 %replacement_high 348 call void @use32(i32 %t1) 349 %t2 = add i32 %x, 16 350 call void @use32(i32 %t2) 351 %t3 = icmp ult i32 %t2, 144 352 %r = select i1 %t3, i32 %x, i32 %t1 353 ret i32 %r 354} 355define i32 @n18_oneuse8(i32 %x, i32 %replacement_low, i32 %replacement_high) { 356; CHECK-LABEL: @n18_oneuse8( 357; CHECK-NEXT: [[T0:%.*]] = icmp slt i32 [[X:%.*]], 64 358; CHECK-NEXT: call void @use1(i1 [[T0]]) 359; CHECK-NEXT: [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[REPLACEMENT_HIGH:%.*]] 360; CHECK-NEXT: call void @use32(i32 [[T1]]) 361; CHECK-NEXT: [[T2:%.*]] = add i32 [[X]], 16 362; CHECK-NEXT: [[T3:%.*]] = icmp ult i32 [[T2]], 144 363; CHECK-NEXT: call void @use1(i1 [[T3]]) 364; CHECK-NEXT: [[R:%.*]] = select i1 [[T3]], i32 [[X]], i32 [[T1]] 365; CHECK-NEXT: ret i32 [[R]] 366; 367 %t0 = icmp slt i32 %x, 64 368 call void @use1(i1 %t0) 369 %t1 = select i1 %t0, i32 %replacement_low, i32 %replacement_high 370 call void @use32(i32 %t1) 371 %t2 = add i32 %x, 16 372 %t3 = icmp ult i32 %t2, 144 373 call void @use1(i1 %t3) 374 %r = select i1 %t3, i32 %x, i32 %t1 375 ret i32 %r 376} 377 378define i32 @n19_oneuse9(i32 %x, i32 %replacement_low, i32 %replacement_high) { 379; CHECK-LABEL: @n19_oneuse9( 380; CHECK-NEXT: [[T0:%.*]] = icmp slt i32 [[X:%.*]], 64 381; CHECK-NEXT: call void @use1(i1 [[T0]]) 382; CHECK-NEXT: [[T1:%.*]] = select i1 [[T0]], i32 [[REPLACEMENT_LOW:%.*]], i32 [[REPLACEMENT_HIGH:%.*]] 383; CHECK-NEXT: call void @use32(i32 [[T1]]) 384; CHECK-NEXT: [[T2:%.*]] = add i32 [[X]], 16 385; CHECK-NEXT: call void @use32(i32 [[T2]]) 386; CHECK-NEXT: [[T3:%.*]] = icmp ult i32 [[T2]], 144 387; CHECK-NEXT: call void @use1(i1 [[T3]]) 388; CHECK-NEXT: [[R:%.*]] = select i1 [[T3]], i32 [[X]], i32 [[T1]] 389; CHECK-NEXT: ret i32 [[R]] 390; 391 %t0 = icmp slt i32 %x, 64 392 call void @use1(i1 %t0) 393 %t1 = select i1 %t0, i32 %replacement_low, i32 %replacement_high 394 call void @use32(i32 %t1) 395 %t2 = add i32 %x, 16 396 call void @use32(i32 %t2) 397 %t3 = icmp ult i32 %t2, 144 398 call void @use1(i1 %t3) 399 %r = select i1 %t3, i32 %x, i32 %t1 400 ret i32 %r 401} 402 403;------------------------------------------------------------------------------- 404 405; Vectors 406 407define <2 x i32> @t20_ult_slt_vec_splat(<2 x i32> %x, <2 x i32> %replacement_low, <2 x i32> %replacement_high) { 408; CHECK-LABEL: @t20_ult_slt_vec_splat( 409; CHECK-NEXT: [[TMP1:%.*]] = icmp slt <2 x i32> [[X:%.*]], <i32 -16, i32 -16> 410; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt <2 x i32> [[X]], <i32 127, i32 127> 411; CHECK-NEXT: [[TMP3:%.*]] = select <2 x i1> [[TMP1]], <2 x i32> [[REPLACEMENT_LOW:%.*]], <2 x i32> [[X]] 412; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[TMP2]], <2 x i32> [[REPLACEMENT_HIGH:%.*]], <2 x i32> [[TMP3]] 413; CHECK-NEXT: ret <2 x i32> [[R]] 414; 415 %t0 = icmp slt <2 x i32> %x, <i32 128, i32 128> 416 %t1 = select <2 x i1> %t0, <2 x i32> %replacement_low, <2 x i32> %replacement_high 417 %t2 = add <2 x i32> %x, <i32 16, i32 16> 418 %t3 = icmp ult <2 x i32> %t2, <i32 144, i32 144> 419 %r = select <2 x i1> %t3, <2 x i32> %x, <2 x i32> %t1 420 ret <2 x i32> %r 421} 422define <2 x i32> @t21_ult_slt_vec_nonsplat(<2 x i32> %x, <2 x i32> %replacement_low, <2 x i32> %replacement_high) { 423; CHECK-LABEL: @t21_ult_slt_vec_nonsplat( 424; CHECK-NEXT: [[TMP1:%.*]] = icmp slt <2 x i32> [[X:%.*]], <i32 -16, i32 -8> 425; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt <2 x i32> [[X]], <i32 127, i32 255> 426; CHECK-NEXT: [[TMP3:%.*]] = select <2 x i1> [[TMP1]], <2 x i32> [[REPLACEMENT_LOW:%.*]], <2 x i32> [[X]] 427; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[TMP2]], <2 x i32> [[REPLACEMENT_HIGH:%.*]], <2 x i32> [[TMP3]] 428; CHECK-NEXT: ret <2 x i32> [[R]] 429; 430 %t0 = icmp slt <2 x i32> %x, <i32 128, i32 64> 431 %t1 = select <2 x i1> %t0, <2 x i32> %replacement_low, <2 x i32> %replacement_high 432 %t2 = add <2 x i32> %x, <i32 16, i32 8> 433 %t3 = icmp ult <2 x i32> %t2, <i32 144, i32 264> 434 %r = select <2 x i1> %t3, <2 x i32> %x, <2 x i32> %t1 435 ret <2 x i32> %r 436} 437 438; Non-canonical predicates 439 440declare void @use2xi1(<2 x i1>) 441 442declare void @use(<2 x i1>) 443define <2 x i32> @t22_uge_slt(<2 x i32> %x, <2 x i32> %replacement_low, <2 x i32> %replacement_high) { 444; CHECK-LABEL: @t22_uge_slt( 445; CHECK-NEXT: [[T0:%.*]] = icmp slt <2 x i32> [[X:%.*]], <i32 128, i32 128> 446; CHECK-NEXT: [[T1:%.*]] = select <2 x i1> [[T0]], <2 x i32> [[REPLACEMENT_LOW:%.*]], <2 x i32> [[REPLACEMENT_HIGH:%.*]] 447; CHECK-NEXT: [[T2:%.*]] = add <2 x i32> [[X]], <i32 16, i32 16> 448; CHECK-NEXT: [[T3:%.*]] = icmp uge <2 x i32> [[T2]], <i32 144, i32 0> 449; CHECK-NEXT: call void @use2xi1(<2 x i1> [[T3]]) 450; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[T3]], <2 x i32> [[T1]], <2 x i32> [[X]] 451; CHECK-NEXT: ret <2 x i32> [[R]] 452; 453 %t0 = icmp slt <2 x i32> %x, <i32 128, i32 128> 454 %t1 = select <2 x i1> %t0, <2 x i32> %replacement_low, <2 x i32> %replacement_high 455 %t2 = add <2 x i32> %x, <i32 16, i32 16> 456 %t3 = icmp uge <2 x i32> %t2, <i32 144, i32 0> 457 call void @use2xi1(<2 x i1> %t3) 458 %r = select <2 x i1> %t3, <2 x i32> %t1, <2 x i32> %x 459 ret <2 x i32> %r 460} 461 462define <2 x i32> @t23_ult_sge(<2 x i32> %x, <2 x i32> %replacement_low, <2 x i32> %replacement_high) { 463; CHECK-LABEL: @t23_ult_sge( 464; CHECK-NEXT: [[T0:%.*]] = icmp sge <2 x i32> [[X:%.*]], <i32 128, i32 -2147483648> 465; CHECK-NEXT: call void @use2xi1(<2 x i1> [[T0]]) 466; CHECK-NEXT: [[TMP1:%.*]] = icmp slt <2 x i32> [[X]], <i32 -16, i32 -2147483648> 467; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt <2 x i32> [[X]], <i32 127, i32 2147483646> 468; CHECK-NEXT: [[TMP3:%.*]] = select <2 x i1> [[TMP1]], <2 x i32> [[REPLACEMENT_LOW:%.*]], <2 x i32> [[X]] 469; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[TMP2]], <2 x i32> [[REPLACEMENT_HIGH:%.*]], <2 x i32> [[TMP3]] 470; CHECK-NEXT: ret <2 x i32> [[R]] 471; 472 %t0 = icmp sge <2 x i32> %x, <i32 128, i32 -2147483648> 473 call void @use2xi1(<2 x i1> %t0) 474 %t1 = select <2 x i1> %t0, <2 x i32> %replacement_high, <2 x i32> %replacement_low 475 %t2 = add <2 x i32> %x, <i32 16, i32 -2147483648> 476 %t3 = icmp ult <2 x i32> %t2, <i32 144, i32 -1> 477 %r = select <2 x i1> %t3, <2 x i32> %x, <2 x i32> %t1 478 ret <2 x i32> %r 479} 480