1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -instsimplify -S | FileCheck %s 3 4; This is canonical form for this IR. 5 6define i1 @abs_nsw_is_positive(i32 %x) { 7; CHECK-LABEL: @abs_nsw_is_positive( 8; CHECK-NEXT: ret i1 true 9; 10 %cmp = icmp slt i32 %x, 0 11 %negx = sub nsw i32 0, %x 12 %abs = select i1 %cmp, i32 %negx, i32 %x 13 %r = icmp sgt i32 %abs, -1 14 ret i1 %r 15} 16 17; Test non-canonical predicate and non-canonical form of abs(). 18 19define i1 @abs_nsw_is_positive_sge(i32 %x) { 20; CHECK-LABEL: @abs_nsw_is_positive_sge( 21; CHECK-NEXT: ret i1 true 22; 23 %cmp = icmp slt i32 %x, 1 24 %negx = sub nsw i32 0, %x 25 %abs = select i1 %cmp, i32 %negx, i32 %x 26 %r = icmp sge i32 %abs, 0 27 ret i1 %r 28} 29 30; This is a range-based analysis. Any negative constant works. 31 32define i1 @abs_nsw_is_positive_reduced_range(i32 %x) { 33; CHECK-LABEL: @abs_nsw_is_positive_reduced_range( 34; CHECK-NEXT: ret i1 true 35; 36 %cmp = icmp slt i32 %x, 0 37 %negx = sub nsw i32 0, %x 38 %abs = select i1 %cmp, i32 %negx, i32 %x 39 %r = icmp sgt i32 %abs, -42 40 ret i1 %r 41} 42 43; Negative test - we need 'nsw' in the abs(). 44 45define i1 @abs_is_positive_reduced_range(i32 %x) { 46; CHECK-LABEL: @abs_is_positive_reduced_range( 47; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0 48; CHECK-NEXT: [[NEGX:%.*]] = sub i32 0, [[X]] 49; CHECK-NEXT: [[ABS:%.*]] = select i1 [[CMP]], i32 [[NEGX]], i32 [[X]] 50; CHECK-NEXT: [[R:%.*]] = icmp sgt i32 [[ABS]], 42 51; CHECK-NEXT: ret i1 [[R]] 52; 53 %cmp = icmp slt i32 %x, 0 54 %negx = sub i32 0, %x 55 %abs = select i1 %cmp, i32 %negx, i32 %x 56 %r = icmp sgt i32 %abs, 42 57 ret i1 %r 58} 59 60; Negative test - range intersection is not subset. 61 62define i1 @abs_nsw_is_positive_wrong_range(i32 %x) { 63; CHECK-LABEL: @abs_nsw_is_positive_wrong_range( 64; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0 65; CHECK-NEXT: [[NEGX:%.*]] = sub nsw i32 0, [[X]] 66; CHECK-NEXT: [[ABS:%.*]] = select i1 [[CMP]], i32 [[NEGX]], i32 [[X]] 67; CHECK-NEXT: [[R:%.*]] = icmp sgt i32 [[ABS]], 0 68; CHECK-NEXT: ret i1 [[R]] 69; 70 %cmp = icmp slt i32 %x, 0 71 %negx = sub nsw i32 0, %x 72 %abs = select i1 %cmp, i32 %negx, i32 %x 73 %r = icmp sgt i32 %abs, 0 74 ret i1 %r 75} 76 77; This is canonical form for this IR. 78 79define i1 @abs_nsw_is_not_negative(i32 %x) { 80; CHECK-LABEL: @abs_nsw_is_not_negative( 81; CHECK-NEXT: ret i1 false 82; 83 %cmp = icmp slt i32 %x, 0 84 %negx = sub nsw i32 0, %x 85 %abs = select i1 %cmp, i32 %negx, i32 %x 86 %r = icmp slt i32 %abs, 0 87 ret i1 %r 88} 89 90; Test non-canonical predicate and non-canonical form of abs(). 91 92define i1 @abs_nsw_is_not_negative_sle(i32 %x) { 93; CHECK-LABEL: @abs_nsw_is_not_negative_sle( 94; CHECK-NEXT: ret i1 false 95; 96 %cmp = icmp slt i32 %x, 1 97 %negx = sub nsw i32 0, %x 98 %abs = select i1 %cmp, i32 %negx, i32 %x 99 %r = icmp sle i32 %abs, -1 100 ret i1 %r 101} 102 103; This is a range-based analysis. Any negative constant works. 104 105define i1 @abs_nsw_is_not_negative_reduced_range(i32 %x) { 106; CHECK-LABEL: @abs_nsw_is_not_negative_reduced_range( 107; CHECK-NEXT: ret i1 false 108; 109 %cmp = icmp slt i32 %x, 0 110 %negx = sub nsw i32 0, %x 111 %abs = select i1 %cmp, i32 %negx, i32 %x 112 %r = icmp slt i32 %abs, -24 113 ret i1 %r 114} 115 116; Negative test - we need 'nsw' in the abs(). 117 118define i1 @abs_is_not_negative_reduced_range(i32 %x) { 119; CHECK-LABEL: @abs_is_not_negative_reduced_range( 120; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0 121; CHECK-NEXT: [[NEGX:%.*]] = sub i32 0, [[X]] 122; CHECK-NEXT: [[ABS:%.*]] = select i1 [[CMP]], i32 [[NEGX]], i32 [[X]] 123; CHECK-NEXT: [[R:%.*]] = icmp slt i32 [[ABS]], 42 124; CHECK-NEXT: ret i1 [[R]] 125; 126 %cmp = icmp slt i32 %x, 0 127 %negx = sub i32 0, %x 128 %abs = select i1 %cmp, i32 %negx, i32 %x 129 %r = icmp slt i32 %abs, 42 130 ret i1 %r 131} 132 133; Negative test - range intersection is not empty. 134 135define i1 @abs_nsw_is_not_negative_wrong_range(i32 %x) { 136; CHECK-LABEL: @abs_nsw_is_not_negative_wrong_range( 137; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0 138; CHECK-NEXT: [[NEGX:%.*]] = sub nsw i32 0, [[X]] 139; CHECK-NEXT: [[ABS:%.*]] = select i1 [[CMP]], i32 [[NEGX]], i32 [[X]] 140; CHECK-NEXT: [[R:%.*]] = icmp sle i32 [[ABS]], 0 141; CHECK-NEXT: ret i1 [[R]] 142; 143 %cmp = icmp slt i32 %x, 0 144 %negx = sub nsw i32 0, %x 145 %abs = select i1 %cmp, i32 %negx, i32 %x 146 %r = icmp sle i32 %abs, 0 147 ret i1 %r 148} 149 150; Even if we don't have nsw, the range is still limited in the unsigned domain. 151define i1 @abs_positive_or_signed_min(i32 %x) { 152; CHECK-LABEL: @abs_positive_or_signed_min( 153; CHECK-NEXT: ret i1 true 154; 155 %cmp = icmp slt i32 %x, 0 156 %negx = sub i32 0, %x 157 %abs = select i1 %cmp, i32 %negx, i32 %x 158 %r = icmp ult i32 %abs, 2147483649 159 ret i1 %r 160} 161 162define i1 @abs_positive_or_signed_min_reduced_range(i32 %x) { 163; CHECK-LABEL: @abs_positive_or_signed_min_reduced_range( 164; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0 165; CHECK-NEXT: [[NEGX:%.*]] = sub i32 0, [[X]] 166; CHECK-NEXT: [[ABS:%.*]] = select i1 [[CMP]], i32 [[NEGX]], i32 [[X]] 167; CHECK-NEXT: [[R:%.*]] = icmp ult i32 [[ABS]], -2147483648 168; CHECK-NEXT: ret i1 [[R]] 169; 170 %cmp = icmp slt i32 %x, 0 171 %negx = sub i32 0, %x 172 %abs = select i1 %cmp, i32 %negx, i32 %x 173 %r = icmp ult i32 %abs, 2147483648 174 ret i1 %r 175} 176 177; This is canonical form for this IR. For nabs(), we don't require 'nsw' 178 179define i1 @nabs_is_negative_or_0(i32 %x) { 180; CHECK-LABEL: @nabs_is_negative_or_0( 181; CHECK-NEXT: ret i1 true 182; 183 %cmp = icmp slt i32 %x, 0 184 %negx = sub i32 0, %x 185 %nabs = select i1 %cmp, i32 %x, i32 %negx 186 %r = icmp slt i32 %nabs, 1 187 ret i1 %r 188} 189 190; Test non-canonical predicate and non-canonical form of nabs(). 191 192define i1 @nabs_is_negative_or_0_sle(i32 %x) { 193; CHECK-LABEL: @nabs_is_negative_or_0_sle( 194; CHECK-NEXT: ret i1 true 195; 196 %cmp = icmp slt i32 %x, 1 197 %negx = sub i32 0, %x 198 %nabs = select i1 %cmp, i32 %x, i32 %negx 199 %r = icmp sle i32 %nabs, 0 200 ret i1 %r 201} 202 203; This is a range-based analysis. Any positive constant works. 204 205define i1 @nabs_is_negative_or_0_reduced_range(i32 %x) { 206; CHECK-LABEL: @nabs_is_negative_or_0_reduced_range( 207; CHECK-NEXT: ret i1 true 208; 209 %cmp = icmp slt i32 %x, 1 210 %negx = sub i32 0, %x 211 %nabs = select i1 %cmp, i32 %x, i32 %negx 212 %r = icmp slt i32 %nabs, 421 213 ret i1 %r 214} 215 216; Negative test - range intersection is not subset. 217 218define i1 @nabs_is_negative_or_0_wrong_range(i32 %x) { 219; CHECK-LABEL: @nabs_is_negative_or_0_wrong_range( 220; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 1 221; CHECK-NEXT: [[NEGX:%.*]] = sub i32 0, [[X]] 222; CHECK-NEXT: [[NABS:%.*]] = select i1 [[CMP]], i32 [[X]], i32 [[NEGX]] 223; CHECK-NEXT: [[R:%.*]] = icmp slt i32 [[NABS]], 0 224; CHECK-NEXT: ret i1 [[R]] 225; 226 %cmp = icmp slt i32 %x, 1 227 %negx = sub i32 0, %x 228 %nabs = select i1 %cmp, i32 %x, i32 %negx 229 %r = icmp slt i32 %nabs, 0 230 ret i1 %r 231} 232 233; This is canonical form for this IR. For nabs(), we don't require 'nsw' 234 235define i1 @nabs_is_not_over_0(i32 %x) { 236; CHECK-LABEL: @nabs_is_not_over_0( 237; CHECK-NEXT: ret i1 false 238; 239 %cmp = icmp slt i32 %x, 0 240 %negx = sub i32 0, %x 241 %nabs = select i1 %cmp, i32 %x, i32 %negx 242 %r = icmp sgt i32 %nabs, 0 243 ret i1 %r 244} 245 246; Test non-canonical predicate and non-canonical form of nabs(). 247 248define i1 @nabs_is_not_over_0_sle(i32 %x) { 249; CHECK-LABEL: @nabs_is_not_over_0_sle( 250; CHECK-NEXT: ret i1 false 251; 252 %cmp = icmp slt i32 %x, 1 253 %negx = sub i32 0, %x 254 %nabs = select i1 %cmp, i32 %x, i32 %negx 255 %r = icmp sge i32 %nabs, 1 256 ret i1 %r 257} 258 259; This is a range-based analysis. Any positive constant works. 260 261define i1 @nabs_is_not_over_0_reduced_range(i32 %x) { 262; CHECK-LABEL: @nabs_is_not_over_0_reduced_range( 263; CHECK-NEXT: ret i1 false 264; 265 %cmp = icmp slt i32 %x, 1 266 %negx = sub i32 0, %x 267 %nabs = select i1 %cmp, i32 %x, i32 %negx 268 %r = icmp sgt i32 %nabs, 4223 269 ret i1 %r 270} 271 272; Negative test - range intersection is not subset. 273 274define i1 @nabs_is_not_over_0_wrong_range(i32 %x) { 275; CHECK-LABEL: @nabs_is_not_over_0_wrong_range( 276; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 1 277; CHECK-NEXT: [[NEGX:%.*]] = sub i32 0, [[X]] 278; CHECK-NEXT: [[NABS:%.*]] = select i1 [[CMP]], i32 [[X]], i32 [[NEGX]] 279; CHECK-NEXT: [[R:%.*]] = icmp sgt i32 [[NABS]], -1 280; CHECK-NEXT: ret i1 [[R]] 281; 282 %cmp = icmp slt i32 %x, 1 283 %negx = sub i32 0, %x 284 %nabs = select i1 %cmp, i32 %x, i32 %negx 285 %r = icmp sgt i32 %nabs, -1 286 ret i1 %r 287} 288 289; More miscellaneous tests for predicates/types. 290 291; Equality predicates are ok. 292 293define i1 @abs_nsw_is_positive_eq(i32 %x) { 294; CHECK-LABEL: @abs_nsw_is_positive_eq( 295; CHECK-NEXT: ret i1 false 296; 297 %cmp = icmp slt i32 %x, 1 298 %negx = sub nsw i32 0, %x 299 %abs = select i1 %cmp, i32 %negx, i32 %x 300 %r = icmp eq i32 %abs, -8 301 ret i1 %r 302} 303 304; An unsigned compare may work. 305 306define i1 @abs_nsw_is_positive_ult(i8 %x) { 307; CHECK-LABEL: @abs_nsw_is_positive_ult( 308; CHECK-NEXT: ret i1 true 309; 310 %cmp = icmp slt i8 %x, 0 311 %negx = sub nsw i8 0, %x 312 %abs = select i1 %cmp, i8 %negx, i8 %x 313 %r = icmp ult i8 %abs, 139 314 ret i1 %r 315} 316 317; An unsigned compare may work. 318 319define i1 @abs_nsw_is_not_negative_ugt(i8 %x) { 320; CHECK-LABEL: @abs_nsw_is_not_negative_ugt( 321; CHECK-NEXT: ret i1 false 322; 323 %cmp = icmp slt i8 %x, 0 324 %negx = sub nsw i8 0, %x 325 %abs = select i1 %cmp, i8 %negx, i8 %x 326 %r = icmp ugt i8 %abs, 127 327 ret i1 %r 328} 329 330; Vector types are ok. 331 332define <2 x i1> @abs_nsw_is_not_negative_vec_splat(<2 x i32> %x) { 333; CHECK-LABEL: @abs_nsw_is_not_negative_vec_splat( 334; CHECK-NEXT: ret <2 x i1> zeroinitializer 335; 336 %cmp = icmp slt <2 x i32> %x, zeroinitializer 337 %negx = sub nsw <2 x i32> zeroinitializer, %x 338 %abs = select <2 x i1> %cmp, <2 x i32> %negx, <2 x i32> %x 339 %r = icmp slt <2 x i32> %abs, <i32 -8, i32 -8> 340 ret <2 x i1> %r 341} 342 343; Equality predicates are ok. 344 345define i1 @nabs_is_negative_or_0_ne(i8 %x) { 346; CHECK-LABEL: @nabs_is_negative_or_0_ne( 347; CHECK-NEXT: ret i1 true 348; 349 %cmp = icmp slt i8 %x, 0 350 %negx = sub i8 0, %x 351 %nabs = select i1 %cmp, i8 %x, i8 %negx 352 %r = icmp ne i8 %nabs, 12 353 ret i1 %r 354} 355 356; Vector types are ok. 357 358define <3 x i1> @nabs_is_not_over_0_sle_vec_splat(<3 x i33> %x) { 359; CHECK-LABEL: @nabs_is_not_over_0_sle_vec_splat( 360; CHECK-NEXT: ret <3 x i1> zeroinitializer 361; 362 %cmp = icmp slt <3 x i33> %x, <i33 1, i33 1, i33 1> 363 %negx = sub <3 x i33> zeroinitializer, %x 364 %nabs = select <3 x i1> %cmp, <3 x i33> %x, <3 x i33> %negx 365 %r = icmp sge <3 x i33> %nabs, <i33 1, i33 1, i33 1> 366 ret <3 x i1> %r 367} 368 369; Negative test - intersection does not equal absolute value range. 370; PR39510 - https://bugs.llvm.org/show_bug.cgi?id=39510 371 372define i1 @abs_no_intersection(i32 %a) { 373; CHECK-LABEL: @abs_no_intersection( 374; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A:%.*]], 0 375; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 0, [[A]] 376; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[SUB]], i32 [[A]] 377; CHECK-NEXT: [[R:%.*]] = icmp ne i32 [[COND]], 2 378; CHECK-NEXT: ret i1 [[R]] 379; 380 %cmp = icmp slt i32 %a, 0 381 %sub = sub nsw i32 0, %a 382 %cond = select i1 %cmp, i32 %sub, i32 %a 383 %r = icmp ne i32 %cond, 2 384 ret i1 %r 385} 386 387; Negative test - intersection does not equal absolute value range. 388 389define i1 @nabs_no_intersection(i32 %a) { 390; CHECK-LABEL: @nabs_no_intersection( 391; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], 0 392; CHECK-NEXT: [[SUB:%.*]] = sub i32 0, [[A]] 393; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[SUB]], i32 [[A]] 394; CHECK-NEXT: [[R:%.*]] = icmp ne i32 [[COND]], -2 395; CHECK-NEXT: ret i1 [[R]] 396; 397 %cmp = icmp sgt i32 %a, 0 398 %sub = sub i32 0, %a 399 %cond = select i1 %cmp, i32 %sub, i32 %a 400 %r = icmp ne i32 %cond, -2 401 ret i1 %r 402} 403 404; We can't fold this to false unless both subs have nsw. 405define i1 @abs_sub_sub_missing_nsw(i32 %x, i32 %y) { 406; CHECK-LABEL: @abs_sub_sub_missing_nsw( 407; CHECK-NEXT: [[A:%.*]] = sub i32 [[X:%.*]], [[Y:%.*]] 408; CHECK-NEXT: [[B:%.*]] = sub nsw i32 [[Y]], [[X]] 409; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[A]], -1 410; CHECK-NEXT: [[D:%.*]] = select i1 [[C]], i32 [[A]], i32 [[B]] 411; CHECK-NEXT: [[E:%.*]] = icmp slt i32 [[D]], 0 412; CHECK-NEXT: ret i1 [[E]] 413; 414 %a = sub i32 %x, %y 415 %b = sub nsw i32 %y, %x 416 %c = icmp sgt i32 %a, -1 417 %d = select i1 %c, i32 %a, i32 %b 418 %e = icmp slt i32 %d, 0 419 ret i1 %e 420} 421