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