1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instsimplify -S | FileCheck %s 3 4; This is a specialization of generic folds for min/max values targeted to the 5; 'null' ptr constant. 6; Related tests for non-pointer types should be included in another file. 7 8; There are 6 basic patterns (or 3 with DeMorganized equivalent) with 9; 2 (commute logic op) * 10; 2 (swap compare operands) * 11; variations for a total of 24 tests. 12 13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 14; 15; (X == null) && (X > Y) --> false 16; 17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 18 19define i1 @ugt_and_min(ptr %x, ptr %y) { 20; CHECK-LABEL: @ugt_and_min( 21; CHECK-NEXT: ret i1 false 22; 23 %cmp = icmp ugt ptr %x, %y 24 %cmpeq = icmp eq ptr %x, null 25 %r = and i1 %cmp, %cmpeq 26 ret i1 %r 27} 28 29define i1 @ugt_and_min_commute(ptr %x, ptr %y) { 30; CHECK-LABEL: @ugt_and_min_commute( 31; CHECK-NEXT: ret i1 false 32; 33 %cmp = icmp ugt ptr %x, %y 34 %cmpeq = icmp eq ptr %x, null 35 %r = and i1 %cmpeq, %cmp 36 ret i1 %r 37} 38 39define i1 @ugt_swap_and_min(ptr %x, ptr %y) { 40; CHECK-LABEL: @ugt_swap_and_min( 41; CHECK-NEXT: ret i1 false 42; 43 %cmp = icmp ult ptr %y, %x 44 %cmpeq = icmp eq ptr %x, null 45 %r = and i1 %cmp, %cmpeq 46 ret i1 %r 47} 48 49define i1 @ugt_swap_and_min_commute(ptr %x, ptr %y) { 50; CHECK-LABEL: @ugt_swap_and_min_commute( 51; CHECK-NEXT: ret i1 false 52; 53 %cmp = icmp ult ptr %y, %x 54 %cmpeq = icmp eq ptr %x, null 55 %r = and i1 %cmpeq, %cmp 56 ret i1 %r 57} 58 59; Negative test - signed compare 60 61define i1 @sgt_and_min(ptr %x, ptr %y) { 62; CHECK-LABEL: @sgt_and_min( 63; CHECK-NEXT: [[CMP:%.*]] = icmp sgt ptr [[X:%.*]], [[Y:%.*]] 64; CHECK-NEXT: [[CMPEQ:%.*]] = icmp eq ptr [[X]], null 65; CHECK-NEXT: [[R:%.*]] = and i1 [[CMP]], [[CMPEQ]] 66; CHECK-NEXT: ret i1 [[R]] 67; 68 %cmp = icmp sgt ptr %x, %y 69 %cmpeq = icmp eq ptr %x, null 70 %r = and i1 %cmp, %cmpeq 71 ret i1 %r 72} 73 74;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 75; 76; (X != null) || (X <= Y) --> true 77; 78;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 79 80define i1 @ule_or_not_min(ptr %x, ptr %y) { 81; CHECK-LABEL: @ule_or_not_min( 82; CHECK-NEXT: ret i1 true 83; 84 %cmp = icmp ule ptr %x, %y 85 %cmpeq = icmp ne ptr %x, null 86 %r = or i1 %cmp, %cmpeq 87 ret i1 %r 88} 89 90define i1 @ule_or_not_min_commute(ptr %x, ptr %y) { 91; CHECK-LABEL: @ule_or_not_min_commute( 92; CHECK-NEXT: ret i1 true 93; 94 %cmp = icmp ule ptr %x, %y 95 %cmpeq = icmp ne ptr %x, null 96 %r = or i1 %cmpeq, %cmp 97 ret i1 %r 98} 99 100define i1 @ule_swap_or_not_min(ptr %x, ptr %y) { 101; CHECK-LABEL: @ule_swap_or_not_min( 102; CHECK-NEXT: ret i1 true 103; 104 %cmp = icmp uge ptr %y, %x 105 %cmpeq = icmp ne ptr %x, null 106 %r = or i1 %cmp, %cmpeq 107 ret i1 %r 108} 109 110define i1 @ule_swap_or_not_min_commute(ptr %x, ptr %y) { 111; CHECK-LABEL: @ule_swap_or_not_min_commute( 112; CHECK-NEXT: ret i1 true 113; 114 %cmp = icmp uge ptr %y, %x 115 %cmpeq = icmp ne ptr %x, null 116 %r = or i1 %cmpeq, %cmp 117 ret i1 %r 118} 119 120; Negative test - signed compare 121 122define i1 @sle_or_not_min(ptr %x, ptr %y) { 123; CHECK-LABEL: @sle_or_not_min( 124; CHECK-NEXT: [[CMP:%.*]] = icmp sle ptr [[X:%.*]], [[Y:%.*]] 125; CHECK-NEXT: [[CMPEQ:%.*]] = icmp ne ptr [[X]], null 126; CHECK-NEXT: [[R:%.*]] = or i1 [[CMP]], [[CMPEQ]] 127; CHECK-NEXT: ret i1 [[R]] 128; 129 %cmp = icmp sle ptr %x, %y 130 %cmpeq = icmp ne ptr %x, null 131 %r = or i1 %cmp, %cmpeq 132 ret i1 %r 133} 134 135;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 136; 137; (X == null) && (X <= Y) --> X == null 138; 139;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 140 141define i1 @ule_and_min(ptr %x, ptr %y) { 142; CHECK-LABEL: @ule_and_min( 143; CHECK-NEXT: [[CMPEQ:%.*]] = icmp eq ptr [[X:%.*]], null 144; CHECK-NEXT: ret i1 [[CMPEQ]] 145; 146 %cmp = icmp ule ptr %x, %y 147 %cmpeq = icmp eq ptr %x, null 148 %r = and i1 %cmp, %cmpeq 149 ret i1 %r 150} 151 152define i1 @ule_and_min_commute(ptr %x, ptr %y) { 153; CHECK-LABEL: @ule_and_min_commute( 154; CHECK-NEXT: [[CMPEQ:%.*]] = icmp eq ptr [[X:%.*]], null 155; CHECK-NEXT: ret i1 [[CMPEQ]] 156; 157 %cmp = icmp ule ptr %x, %y 158 %cmpeq = icmp eq ptr %x, null 159 %r = and i1 %cmpeq, %cmp 160 ret i1 %r 161} 162 163define i1 @ule_swap_and_min(ptr %x, ptr %y) { 164; CHECK-LABEL: @ule_swap_and_min( 165; CHECK-NEXT: [[CMPEQ:%.*]] = icmp eq ptr [[X:%.*]], null 166; CHECK-NEXT: ret i1 [[CMPEQ]] 167; 168 %cmp = icmp uge ptr %y, %x 169 %cmpeq = icmp eq ptr %x, null 170 %r = and i1 %cmp, %cmpeq 171 ret i1 %r 172} 173 174define i1 @ule_swap_and_min_commute(ptr %x, ptr %y) { 175; CHECK-LABEL: @ule_swap_and_min_commute( 176; CHECK-NEXT: [[CMPEQ:%.*]] = icmp eq ptr [[X:%.*]], null 177; CHECK-NEXT: ret i1 [[CMPEQ]] 178; 179 %cmp = icmp uge ptr %y, %x 180 %cmpeq = icmp eq ptr %x, null 181 %r = and i1 %cmpeq, %cmp 182 ret i1 %r 183} 184 185; Negative test - signed compare 186 187define i1 @sle_and_min(ptr %x, ptr %y) { 188; CHECK-LABEL: @sle_and_min( 189; CHECK-NEXT: [[CMP:%.*]] = icmp sle ptr [[X:%.*]], [[Y:%.*]] 190; CHECK-NEXT: [[CMPEQ:%.*]] = icmp eq ptr [[X]], null 191; CHECK-NEXT: [[R:%.*]] = and i1 [[CMP]], [[CMPEQ]] 192; CHECK-NEXT: ret i1 [[R]] 193; 194 %cmp = icmp sle ptr %x, %y 195 %cmpeq = icmp eq ptr %x, null 196 %r = and i1 %cmp, %cmpeq 197 ret i1 %r 198} 199 200;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 201; 202; (X == null) || (X <= Y) --> X <= Y 203; 204;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 205 206define i1 @ule_or_min(ptr %x, ptr %y) { 207; CHECK-LABEL: @ule_or_min( 208; CHECK-NEXT: [[CMP:%.*]] = icmp ule ptr [[X:%.*]], [[Y:%.*]] 209; CHECK-NEXT: ret i1 [[CMP]] 210; 211 %cmp = icmp ule ptr %x, %y 212 %cmpeq = icmp eq ptr %x, null 213 %r = or i1 %cmp, %cmpeq 214 ret i1 %r 215} 216 217define i1 @ule_or_min_commute(ptr %x, ptr %y) { 218; CHECK-LABEL: @ule_or_min_commute( 219; CHECK-NEXT: [[CMP:%.*]] = icmp ule ptr [[X:%.*]], [[Y:%.*]] 220; CHECK-NEXT: ret i1 [[CMP]] 221; 222 %cmp = icmp ule ptr %x, %y 223 %cmpeq = icmp eq ptr %x, null 224 %r = or i1 %cmpeq, %cmp 225 ret i1 %r 226} 227 228define i1 @ule_swap_or_min(ptr %x, ptr %y) { 229; CHECK-LABEL: @ule_swap_or_min( 230; CHECK-NEXT: [[CMP:%.*]] = icmp uge ptr [[Y:%.*]], [[X:%.*]] 231; CHECK-NEXT: ret i1 [[CMP]] 232; 233 %cmp = icmp uge ptr %y, %x 234 %cmpeq = icmp eq ptr %x, null 235 %r = or i1 %cmp, %cmpeq 236 ret i1 %r 237} 238 239define i1 @ule_swap_or_min_commute(ptr %x, ptr %y) { 240; CHECK-LABEL: @ule_swap_or_min_commute( 241; CHECK-NEXT: [[CMP:%.*]] = icmp uge ptr [[Y:%.*]], [[X:%.*]] 242; CHECK-NEXT: ret i1 [[CMP]] 243; 244 %cmp = icmp uge ptr %y, %x 245 %cmpeq = icmp eq ptr %x, null 246 %r = or i1 %cmpeq, %cmp 247 ret i1 %r 248} 249 250; Negative test - signed compare 251 252define i1 @sle_or_min(ptr %x, ptr %y) { 253; CHECK-LABEL: @sle_or_min( 254; CHECK-NEXT: [[CMP:%.*]] = icmp sle ptr [[X:%.*]], [[Y:%.*]] 255; CHECK-NEXT: [[CMPEQ:%.*]] = icmp eq ptr [[X]], null 256; CHECK-NEXT: [[R:%.*]] = or i1 [[CMP]], [[CMPEQ]] 257; CHECK-NEXT: ret i1 [[R]] 258; 259 %cmp = icmp sle ptr %x, %y 260 %cmpeq = icmp eq ptr %x, null 261 %r = or i1 %cmp, %cmpeq 262 ret i1 %r 263} 264 265;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 266; 267; (X != null) && (X > Y) --> X > Y 268; 269;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 270 271define i1 @ugt_and_not_min(ptr %x, ptr %y) { 272; CHECK-LABEL: @ugt_and_not_min( 273; CHECK-NEXT: [[CMP:%.*]] = icmp ugt ptr [[X:%.*]], [[Y:%.*]] 274; CHECK-NEXT: ret i1 [[CMP]] 275; 276 %cmp = icmp ugt ptr %x, %y 277 %cmpeq = icmp ne ptr %x, null 278 %r = and i1 %cmp, %cmpeq 279 ret i1 %r 280} 281 282define i1 @ugt_and_not_min_commute(ptr %x, ptr %y) { 283; CHECK-LABEL: @ugt_and_not_min_commute( 284; CHECK-NEXT: [[CMP:%.*]] = icmp ugt ptr [[X:%.*]], [[Y:%.*]] 285; CHECK-NEXT: ret i1 [[CMP]] 286; 287 %cmp = icmp ugt ptr %x, %y 288 %cmpeq = icmp ne ptr %x, null 289 %r = and i1 %cmpeq, %cmp 290 ret i1 %r 291} 292 293define i1 @ugt_swap_and_not_min(ptr %x, ptr %y) { 294; CHECK-LABEL: @ugt_swap_and_not_min( 295; CHECK-NEXT: [[CMP:%.*]] = icmp ult ptr [[Y:%.*]], [[X:%.*]] 296; CHECK-NEXT: ret i1 [[CMP]] 297; 298 %cmp = icmp ult ptr %y, %x 299 %cmpeq = icmp ne ptr %x, null 300 %r = and i1 %cmp, %cmpeq 301 ret i1 %r 302} 303 304define i1 @ugt_swap_and_not_min_commute(ptr %x, ptr %y) { 305; CHECK-LABEL: @ugt_swap_and_not_min_commute( 306; CHECK-NEXT: [[CMP:%.*]] = icmp ult ptr [[Y:%.*]], [[X:%.*]] 307; CHECK-NEXT: ret i1 [[CMP]] 308; 309 %cmp = icmp ult ptr %y, %x 310 %cmpeq = icmp ne ptr %x, null 311 %r = and i1 %cmpeq, %cmp 312 ret i1 %r 313} 314 315; Negative test - signed compare 316 317define i1 @sgt_and_not_min(ptr %x, ptr %y) { 318; CHECK-LABEL: @sgt_and_not_min( 319; CHECK-NEXT: [[CMP:%.*]] = icmp sgt ptr [[X:%.*]], [[Y:%.*]] 320; CHECK-NEXT: [[CMPEQ:%.*]] = icmp ne ptr [[X]], null 321; CHECK-NEXT: [[R:%.*]] = and i1 [[CMP]], [[CMPEQ]] 322; CHECK-NEXT: ret i1 [[R]] 323; 324 %cmp = icmp sgt ptr %x, %y 325 %cmpeq = icmp ne ptr %x, null 326 %r = and i1 %cmp, %cmpeq 327 ret i1 %r 328} 329 330;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 331; 332; (X != null) || (X > Y) --> X != null 333; 334;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 335 336define i1 @ugt_or_not_min(ptr %x, ptr %y) { 337; CHECK-LABEL: @ugt_or_not_min( 338; CHECK-NEXT: [[CMPEQ:%.*]] = icmp ne ptr [[X:%.*]], null 339; CHECK-NEXT: ret i1 [[CMPEQ]] 340; 341 %cmp = icmp ugt ptr %x, %y 342 %cmpeq = icmp ne ptr %x, null 343 %r = or i1 %cmp, %cmpeq 344 ret i1 %r 345} 346 347define i1 @ugt_or_not_min_commute(ptr %x, ptr %y) { 348; CHECK-LABEL: @ugt_or_not_min_commute( 349; CHECK-NEXT: [[CMPEQ:%.*]] = icmp ne ptr [[X:%.*]], null 350; CHECK-NEXT: ret i1 [[CMPEQ]] 351; 352 %cmp = icmp ugt ptr %x, %y 353 %cmpeq = icmp ne ptr %x, null 354 %r = or i1 %cmpeq, %cmp 355 ret i1 %r 356} 357 358define i1 @ugt_swap_or_not_min(ptr %x, ptr %y) { 359; CHECK-LABEL: @ugt_swap_or_not_min( 360; CHECK-NEXT: [[CMPEQ:%.*]] = icmp ne ptr [[X:%.*]], null 361; CHECK-NEXT: ret i1 [[CMPEQ]] 362; 363 %cmp = icmp ult ptr %y, %x 364 %cmpeq = icmp ne ptr %x, null 365 %r = or i1 %cmp, %cmpeq 366 ret i1 %r 367} 368 369define i1 @ugt_swap_or_not_min_commute(ptr %x, ptr %y) { 370; CHECK-LABEL: @ugt_swap_or_not_min_commute( 371; CHECK-NEXT: [[CMPEQ:%.*]] = icmp ne ptr [[X:%.*]], null 372; CHECK-NEXT: ret i1 [[CMPEQ]] 373; 374 %cmp = icmp ult ptr %y, %x 375 %cmpeq = icmp ne ptr %x, null 376 %r = or i1 %cmpeq, %cmp 377 ret i1 %r 378} 379 380; Negative test - signed compare 381 382define i1 @sgt_or_not_min(ptr %x, ptr %y) { 383; CHECK-LABEL: @sgt_or_not_min( 384; CHECK-NEXT: [[CMP:%.*]] = icmp sgt ptr [[X:%.*]], [[Y:%.*]] 385; CHECK-NEXT: [[CMPEQ:%.*]] = icmp ne ptr [[X]], null 386; CHECK-NEXT: [[R:%.*]] = or i1 [[CMP]], [[CMPEQ]] 387; CHECK-NEXT: ret i1 [[R]] 388; 389 %cmp = icmp sgt ptr %x, %y 390 %cmpeq = icmp ne ptr %x, null 391 %r = or i1 %cmp, %cmpeq 392 ret i1 %r 393} 394