1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -instcombine -S | FileCheck %s 3 4; If we have a relational comparison with a constant, and said comparison is 5; used in a select, and there is a constant in select, see if we can make 6; those constants match. 7 8; We can't ever get non-canonical scalar predicates. 9 10; Likewise, while we can get non-canonical vector predicates, there must be an 11; extra use on that `icmp`, which precludes the fold from happening. 12 13;------------------------------------------------------------------------------; 14; Canonical scalar predicates 15;------------------------------------------------------------------------------; 16 17!0 = !{!"branch_weights", i32 2000, i32 1} 18 19define i32 @p0_ult_65536(i32 %x, i32 %y) { 20; CHECK-LABEL: @p0_ult_65536( 21; CHECK-NEXT: [[T_INV:%.*]] = icmp ugt i32 [[X:%.*]], 65535 22; CHECK-NEXT: [[R:%.*]] = select i1 [[T_INV]], i32 65535, i32 [[Y:%.*]], !prof !0 23; CHECK-NEXT: ret i32 [[R]] 24; 25 %t = icmp ult i32 %x, 65536 26 %r = select i1 %t, i32 %y, i32 65535, !prof !0 27 ret i32 %r 28} 29define i32 @p1_ugt(i32 %x, i32 %y) { 30; CHECK-LABEL: @p1_ugt( 31; CHECK-NEXT: [[T_INV:%.*]] = icmp ult i32 [[X:%.*]], 65535 32; CHECK-NEXT: [[R:%.*]] = select i1 [[T_INV]], i32 65535, i32 [[Y:%.*]] 33; CHECK-NEXT: ret i32 [[R]] 34; 35 %t = icmp ugt i32 %x, 65534 36 %r = select i1 %t, i32 %y, i32 65535 37 ret i32 %r 38} 39define i32 @p2_slt_65536(i32 %x, i32 %y) { 40; CHECK-LABEL: @p2_slt_65536( 41; CHECK-NEXT: [[T_INV:%.*]] = icmp sgt i32 [[X:%.*]], 65535 42; CHECK-NEXT: [[R:%.*]] = select i1 [[T_INV]], i32 65535, i32 [[Y:%.*]] 43; CHECK-NEXT: ret i32 [[R]] 44; 45 %t = icmp slt i32 %x, 65536 46 %r = select i1 %t, i32 %y, i32 65535 47 ret i32 %r 48} 49define i32 @p3_sgt(i32 %x, i32 %y) { 50; CHECK-LABEL: @p3_sgt( 51; CHECK-NEXT: [[T_INV:%.*]] = icmp slt i32 [[X:%.*]], 65535 52; CHECK-NEXT: [[R:%.*]] = select i1 [[T_INV]], i32 65535, i32 [[Y:%.*]] 53; CHECK-NEXT: ret i32 [[R]] 54; 55 %t = icmp sgt i32 %x, 65534 56 %r = select i1 %t, i32 %y, i32 65535 57 ret i32 %r 58} 59 60;------------------------------------------------------------------------------; 61; Vectors 62;------------------------------------------------------------------------------; 63 64define <2 x i32> @p4_vec_splat_ult_65536(<2 x i32> %x, <2 x i32> %y) { 65; CHECK-LABEL: @p4_vec_splat_ult_65536( 66; CHECK-NEXT: [[T_INV:%.*]] = icmp ugt <2 x i32> [[X:%.*]], <i32 65535, i32 65535> 67; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[T_INV]], <2 x i32> <i32 65535, i32 65535>, <2 x i32> [[Y:%.*]] 68; CHECK-NEXT: ret <2 x i32> [[R]] 69; 70 %t = icmp ult <2 x i32> %x, <i32 65536, i32 65536> 71 %r = select <2 x i1> %t, <2 x i32> %y, <2 x i32> <i32 65535, i32 65535> 72 ret <2 x i32> %r 73} 74define <2 x i32> @p5_vec_splat_ugt(<2 x i32> %x, <2 x i32> %y) { 75; CHECK-LABEL: @p5_vec_splat_ugt( 76; CHECK-NEXT: [[T_INV:%.*]] = icmp ult <2 x i32> [[X:%.*]], <i32 65535, i32 65535> 77; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[T_INV]], <2 x i32> <i32 65535, i32 65535>, <2 x i32> [[Y:%.*]] 78; CHECK-NEXT: ret <2 x i32> [[R]] 79; 80 %t = icmp ugt <2 x i32> %x, <i32 65534, i32 65534> 81 %r = select <2 x i1> %t, <2 x i32> %y, <2 x i32> <i32 65535, i32 65535> 82 ret <2 x i32> %r 83} 84define <2 x i32> @p6_vec_splat_slt_65536(<2 x i32> %x, <2 x i32> %y) { 85; CHECK-LABEL: @p6_vec_splat_slt_65536( 86; CHECK-NEXT: [[T_INV:%.*]] = icmp sgt <2 x i32> [[X:%.*]], <i32 65535, i32 65535> 87; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[T_INV]], <2 x i32> <i32 65535, i32 65535>, <2 x i32> [[Y:%.*]] 88; CHECK-NEXT: ret <2 x i32> [[R]] 89; 90 %t = icmp slt <2 x i32> %x, <i32 65536, i32 65536> 91 %r = select <2 x i1> %t, <2 x i32> %y, <2 x i32> <i32 65535, i32 65535> 92 ret <2 x i32> %r 93} 94define <2 x i32> @p7_vec_splat_sgt(<2 x i32> %x, <2 x i32> %y) { 95; CHECK-LABEL: @p7_vec_splat_sgt( 96; CHECK-NEXT: [[T_INV:%.*]] = icmp slt <2 x i32> [[X:%.*]], <i32 65535, i32 65535> 97; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[T_INV]], <2 x i32> <i32 65535, i32 65535>, <2 x i32> [[Y:%.*]] 98; CHECK-NEXT: ret <2 x i32> [[R]] 99; 100 %t = icmp sgt <2 x i32> %x, <i32 65534, i32 65534> 101 %r = select <2 x i1> %t, <2 x i32> %y, <2 x i32> <i32 65535, i32 65535> 102 ret <2 x i32> %r 103} 104 105; Vectors with undef 106 107define <2 x i32> @p8_vec_nonsplat_undef0(<2 x i32> %x, <2 x i32> %y) { 108; CHECK-LABEL: @p8_vec_nonsplat_undef0( 109; CHECK-NEXT: [[T_INV:%.*]] = icmp ugt <2 x i32> [[X:%.*]], <i32 65535, i32 65535> 110; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[T_INV]], <2 x i32> <i32 65535, i32 65535>, <2 x i32> [[Y:%.*]] 111; CHECK-NEXT: ret <2 x i32> [[R]] 112; 113 %t = icmp ult <2 x i32> %x, <i32 65536, i32 undef> 114 %r = select <2 x i1> %t, <2 x i32> %y, <2 x i32> <i32 65535, i32 65535> 115 ret <2 x i32> %r 116} 117define <2 x i32> @p9_vec_nonsplat_undef1(<2 x i32> %x, <2 x i32> %y) { 118; CHECK-LABEL: @p9_vec_nonsplat_undef1( 119; CHECK-NEXT: [[T_INV:%.*]] = icmp ugt <2 x i32> [[X:%.*]], <i32 65535, i32 65535> 120; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[T_INV]], <2 x i32> <i32 65535, i32 undef>, <2 x i32> [[Y:%.*]] 121; CHECK-NEXT: ret <2 x i32> [[R]] 122; 123 %t = icmp ult <2 x i32> %x, <i32 65536, i32 65536> 124 %r = select <2 x i1> %t, <2 x i32> %y, <2 x i32> <i32 65535, i32 undef> 125 ret <2 x i32> %r 126} 127define <2 x i32> @p10_vec_nonsplat_undef2(<2 x i32> %x, <2 x i32> %y) { 128; CHECK-LABEL: @p10_vec_nonsplat_undef2( 129; CHECK-NEXT: [[T_INV:%.*]] = icmp ugt <2 x i32> [[X:%.*]], <i32 65535, i32 65535> 130; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[T_INV]], <2 x i32> <i32 65535, i32 undef>, <2 x i32> [[Y:%.*]] 131; CHECK-NEXT: ret <2 x i32> [[R]] 132; 133 %t = icmp ult <2 x i32> %x, <i32 65536, i32 undef> 134 %r = select <2 x i1> %t, <2 x i32> %y, <2 x i32> <i32 65535, i32 undef> 135 ret <2 x i32> %r 136} 137 138; Non-splat vectors 139 140define <2 x i32> @p11_vec_nonsplat(<2 x i32> %x, <2 x i32> %y) { 141; CHECK-LABEL: @p11_vec_nonsplat( 142; CHECK-NEXT: [[T_INV:%.*]] = icmp ugt <2 x i32> [[X:%.*]], <i32 65535, i32 32767> 143; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[T_INV]], <2 x i32> <i32 65535, i32 32767>, <2 x i32> [[Y:%.*]] 144; CHECK-NEXT: ret <2 x i32> [[R]] 145; 146 %t = icmp ult <2 x i32> %x, <i32 65536, i32 32768> 147 %r = select <2 x i1> %t, <2 x i32> %y, <2 x i32> <i32 65535, i32 32767> 148 ret <2 x i32> %r 149} 150 151;------------------------------------------------------------------------------; 152; Extra uses prevent the fold. 153;------------------------------------------------------------------------------; 154 155declare void @use1(i1) 156 157define i32 @n12_extrause(i32 %x, i32 %y) { 158; CHECK-LABEL: @n12_extrause( 159; CHECK-NEXT: [[T:%.*]] = icmp ult i32 [[X:%.*]], 65536 160; CHECK-NEXT: call void @use1(i1 [[T]]) 161; CHECK-NEXT: [[R:%.*]] = select i1 [[T]], i32 [[Y:%.*]], i32 65535 162; CHECK-NEXT: ret i32 [[R]] 163; 164 %t = icmp ult i32 %x, 65536 165 call void @use1(i1 %t) 166 %r = select i1 %t, i32 %y, i32 65535 167 ret i32 %r 168} 169 170;------------------------------------------------------------------------------; 171; Commutativity 172;------------------------------------------------------------------------------; 173 174; We don't care if the constant in select is true value or false value 175define i32 @p13_commutativity0(i32 %x, i32 %y) { 176; CHECK-LABEL: @p13_commutativity0( 177; CHECK-NEXT: [[T_INV:%.*]] = icmp ugt i32 [[X:%.*]], 65535 178; CHECK-NEXT: [[R:%.*]] = select i1 [[T_INV]], i32 [[Y:%.*]], i32 65535 179; CHECK-NEXT: ret i32 [[R]] 180; 181 %t = icmp ult i32 %x, 65536 182 %r = select i1 %t, i32 65535, i32 %y 183 ret i32 %r 184} 185 186; Which means, if both possibilities are constants, we must check both of them. 187define i32 @p14_commutativity1(i32 %x, i32 %y) { 188; CHECK-LABEL: @p14_commutativity1( 189; CHECK-NEXT: [[T_INV:%.*]] = icmp ugt i32 [[X:%.*]], 65535 190; CHECK-NEXT: [[R:%.*]] = select i1 [[T_INV]], i32 42, i32 65535 191; CHECK-NEXT: ret i32 [[R]] 192; 193 %t = icmp ult i32 %x, 65536 194 %r = select i1 %t, i32 65535, i32 42 195 ret i32 %r 196} 197define i32 @p15_commutativity2(i32 %x, i32 %y) { 198; CHECK-LABEL: @p15_commutativity2( 199; CHECK-NEXT: [[T_INV:%.*]] = icmp ugt i32 [[X:%.*]], 65535 200; CHECK-NEXT: [[R:%.*]] = select i1 [[T_INV]], i32 65535, i32 42 201; CHECK-NEXT: ret i32 [[R]] 202; 203 %t = icmp ult i32 %x, 65536 204 %r = select i1 %t, i32 42, i32 65535 205 ret i32 %r 206} 207 208;------------------------------------------------------------------------------; 209; Negative tests 210;------------------------------------------------------------------------------; 211 212; For vectors, make sure we handle edge cases correctly 213define <2 x i32> @n17_ult_zero(<2 x i32> %x, <2 x i32> %y) { 214; CHECK-LABEL: @n17_ult_zero( 215; CHECK-NEXT: [[T:%.*]] = icmp ult <2 x i32> [[X:%.*]], <i32 65536, i32 0> 216; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[T]], <2 x i32> [[Y:%.*]], <2 x i32> <i32 65535, i32 -1> 217; CHECK-NEXT: ret <2 x i32> [[R]] 218; 219 %t = icmp ult <2 x i32> %x, <i32 65536, i32 0> 220 %r = select <2 x i1> %t, <2 x i32> %y, <2 x i32> <i32 65535, i32 -1> 221 ret <2 x i32> %r 222} 223define <2 x i32> @n18_ugt_allones(<2 x i32> %x, <2 x i32> %y) { 224; CHECK-LABEL: @n18_ugt_allones( 225; CHECK-NEXT: [[T:%.*]] = icmp ugt <2 x i32> [[X:%.*]], <i32 65534, i32 -1> 226; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[T]], <2 x i32> [[Y:%.*]], <2 x i32> <i32 65535, i32 0> 227; CHECK-NEXT: ret <2 x i32> [[R]] 228; 229 %t = icmp ugt <2 x i32> %x, <i32 65534, i32 -1> 230 %r = select <2 x i1> %t, <2 x i32> %y, <2 x i32> <i32 65535, i32 0> 231 ret <2 x i32> %r 232} 233define <2 x i32> @n19_slt_int_min(<2 x i32> %x, <2 x i32> %y) { 234; CHECK-LABEL: @n19_slt_int_min( 235; CHECK-NEXT: [[T:%.*]] = icmp slt <2 x i32> [[X:%.*]], <i32 65536, i32 -2147483648> 236; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[T]], <2 x i32> [[Y:%.*]], <2 x i32> <i32 65535, i32 2147483647> 237; CHECK-NEXT: ret <2 x i32> [[R]] 238; 239 %t = icmp slt <2 x i32> %x, <i32 65536, i32 -2147483648> 240 %r = select <2 x i1> %t, <2 x i32> %y, <2 x i32> <i32 65535, i32 2147483647> 241 ret <2 x i32> %r 242} 243define <2 x i32> @n20_sgt_int_max(<2 x i32> %x, <2 x i32> %y) { 244; CHECK-LABEL: @n20_sgt_int_max( 245; CHECK-NEXT: [[T:%.*]] = icmp sgt <2 x i32> [[X:%.*]], <i32 65534, i32 2147483647> 246; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[T]], <2 x i32> [[Y:%.*]], <2 x i32> <i32 65535, i32 -2147483648> 247; CHECK-NEXT: ret <2 x i32> [[R]] 248; 249 %t = icmp sgt <2 x i32> %x, <i32 65534, i32 2147483647> 250 %r = select <2 x i1> %t, <2 x i32> %y, <2 x i32> <i32 65535, i32 -2147483648> 251 ret <2 x i32> %r 252} 253 254; We don't do anything for non-relational comparisons. 255define i32 @n21_equality(i32 %x, i32 %y) { 256; CHECK-LABEL: @n21_equality( 257; CHECK-NEXT: [[T:%.*]] = icmp eq i32 [[X:%.*]], -2147483648 258; CHECK-NEXT: [[R:%.*]] = select i1 [[T]], i32 2147483647, i32 [[Y:%.*]] 259; CHECK-NEXT: ret i32 [[R]] 260; 261 %t = icmp eq i32 %x, -2147483648 262 %r = select i1 %t, i32 2147483647, i32 %y 263 ret i32 %r 264} 265 266; There is nothing special about sign-bit-tests, we can fold them. 267define i32 @t22_sign_check(i32 %x, i32 %y) { 268; CHECK-LABEL: @t22_sign_check( 269; CHECK-NEXT: [[T_INV:%.*]] = icmp sgt i32 [[X:%.*]], -1 270; CHECK-NEXT: [[R:%.*]] = select i1 [[T_INV]], i32 [[Y:%.*]], i32 -1 271; CHECK-NEXT: ret i32 [[R]] 272; 273 %t = icmp slt i32 %x, 0 274 %r = select i1 %t, i32 -1, i32 %y 275 ret i32 %r 276} 277define i32 @t22_sign_check2(i32 %x, i32 %y) { 278; CHECK-LABEL: @t22_sign_check2( 279; CHECK-NEXT: [[T_INV:%.*]] = icmp slt i32 [[X:%.*]], 0 280; CHECK-NEXT: [[R:%.*]] = select i1 [[T_INV]], i32 [[Y:%.*]], i32 0 281; CHECK-NEXT: ret i32 [[R]] 282; 283 %t = icmp sgt i32 %x, -1 284 %r = select i1 %t, i32 0, i32 %y 285 ret i32 %r 286} 287 288; If the types don't match we currently don't do anything. 289define i32 @n23_type_mismatch(i64 %x, i32 %y) { 290; CHECK-LABEL: @n23_type_mismatch( 291; CHECK-NEXT: [[T:%.*]] = icmp ult i64 [[X:%.*]], 65536 292; CHECK-NEXT: [[R:%.*]] = select i1 [[T]], i32 [[Y:%.*]], i32 65535 293; CHECK-NEXT: ret i32 [[R]] 294; 295 %t = icmp ult i64 %x, 65536 296 %r = select i1 %t, i32 %y, i32 65535 297 ret i32 %r 298} 299 300; Don't do wrong tranform 301define i32 @n24_ult_65534(i32 %x, i32 %y) { 302; CHECK-LABEL: @n24_ult_65534( 303; CHECK-NEXT: [[T:%.*]] = icmp ult i32 [[X:%.*]], 65534 304; CHECK-NEXT: [[R:%.*]] = select i1 [[T]], i32 [[Y:%.*]], i32 65535 305; CHECK-NEXT: ret i32 [[R]] 306; 307 %t = icmp ult i32 %x, 65534 308 %r = select i1 %t, i32 %y, i32 65535 309 ret i32 %r 310} 311 312; If we already have a match, it's good enough. 313define i32 @n25_all_good0(i32 %x, i32 %y) { 314; CHECK-LABEL: @n25_all_good0( 315; CHECK-NEXT: [[T:%.*]] = icmp ult i32 [[X:%.*]], 65536 316; CHECK-NEXT: [[R:%.*]] = select i1 [[T]], i32 65535, i32 65536 317; CHECK-NEXT: ret i32 [[R]] 318; 319 %t = icmp ult i32 %x, 65536 320 %r = select i1 %t, i32 65535, i32 65536 321 ret i32 %r 322} 323define i32 @n26_all_good1(i32 %x, i32 %y) { 324; CHECK-LABEL: @n26_all_good1( 325; CHECK-NEXT: [[T:%.*]] = icmp ult i32 [[X:%.*]], 65536 326; CHECK-NEXT: [[R:%.*]] = select i1 [[T]], i32 65536, i32 65535 327; CHECK-NEXT: ret i32 [[R]] 328; 329 %t = icmp ult i32 %x, 65536 330 %r = select i1 %t, i32 65536, i32 65535 331 ret i32 %r 332} 333 334 335 336; CHECK: !0 = !{!"branch_weights", i32 1, i32 2000} 337