1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 3 2; RUN: opt -p constraint-elimination -S %s | FileCheck %s 3 4declare void @llvm.assume(i1) 5 6define i1 @addition_with_extra_facts_and_args_ult_i64(i64 noundef %a, i64 noundef %b, i64 noundef %c) { 7; CHECK-LABEL: define i1 @addition_with_extra_facts_and_args_ult_i64( 8; CHECK-SAME: i64 noundef [[A:%.*]], i64 noundef [[B:%.*]], i64 noundef [[C:%.*]]) { 9; CHECK-NEXT: entry: 10; CHECK-NEXT: [[CMP_A:%.*]] = icmp ule i64 [[A]], 2048 11; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_A]]) 12; CHECK-NEXT: [[CMP_B:%.*]] = icmp ule i64 [[B]], 1024 13; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_B]]) 14; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i64 [[B]], [[A]] 15; CHECK-NEXT: [[CMP_ADD:%.*]] = icmp ult i64 [[ADD]], [[C]] 16; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_ADD]]) 17; CHECK-NEXT: ret i1 true 18; 19entry: 20 %cmp.a = icmp ule i64 %a, 2048 21 call void @llvm.assume(i1 %cmp.a) 22 %cmp.b = icmp ule i64 %b, 1024 23 call void @llvm.assume(i1 %cmp.b) 24 %add = add nuw nsw i64 %b, %a 25 %cmp.add = icmp ult i64 %add, %c 26 call void @llvm.assume(i1 %cmp.add) 27 %t = icmp ult i64 %a, %c 28 ret i1 %t 29} 30 31define i1 @addition_with_extra_facts_and_args_ult_1(i16 noundef %a, i16 noundef %b, i16 noundef %c) { 32; CHECK-LABEL: define i1 @addition_with_extra_facts_and_args_ult_1( 33; CHECK-SAME: i16 noundef [[A:%.*]], i16 noundef [[B:%.*]], i16 noundef [[C:%.*]]) { 34; CHECK-NEXT: entry: 35; CHECK-NEXT: [[CMP_A:%.*]] = icmp ule i16 [[A]], 2048 36; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_A]]) 37; CHECK-NEXT: [[CMP_B:%.*]] = icmp ule i16 [[B]], 1024 38; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_B]]) 39; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i16 [[B]], [[A]] 40; CHECK-NEXT: [[CMP_ADD:%.*]] = icmp ult i16 [[ADD]], [[C]] 41; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_ADD]]) 42; CHECK-NEXT: ret i1 true 43; 44entry: 45 %cmp.a = icmp ule i16 %a, 2048 46 call void @llvm.assume(i1 %cmp.a) 47 %cmp.b = icmp ule i16 %b, 1024 48 call void @llvm.assume(i1 %cmp.b) 49 %add = add nuw nsw i16 %b, %a 50 %cmp.add = icmp ult i16 %add, %c 51 call void @llvm.assume(i1 %cmp.add) 52 %t = icmp ult i16 %a, %c 53 ret i1 %t 54} 55 56define i1 @addition_with_extra_facts_and_args_ult_2(i16 noundef %a, i16 noundef %b, i16 noundef %c) { 57; CHECK-LABEL: define i1 @addition_with_extra_facts_and_args_ult_2( 58; CHECK-SAME: i16 noundef [[A:%.*]], i16 noundef [[B:%.*]], i16 noundef [[C:%.*]]) { 59; CHECK-NEXT: entry: 60; CHECK-NEXT: [[CMP_A:%.*]] = icmp ule i16 [[A]], 2048 61; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_A]]) 62; CHECK-NEXT: [[CMP_B:%.*]] = icmp ule i16 [[B]], 1024 63; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_B]]) 64; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i16 [[B]], [[A]] 65; CHECK-NEXT: [[CMP_ADD:%.*]] = icmp ult i16 [[ADD]], [[C]] 66; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_ADD]]) 67; CHECK-NEXT: ret i1 true 68; 69entry: 70 %cmp.a = icmp ule i16 %a, 2048 71 call void @llvm.assume(i1 %cmp.a) 72 %cmp.b = icmp ule i16 %b, 1024 73 call void @llvm.assume(i1 %cmp.b) 74 %add = add nuw nsw i16 %b, %a 75 %cmp.add = icmp ult i16 %add, %c 76 call void @llvm.assume(i1 %cmp.add) 77 %t = icmp ult i16 %b, %c 78 ret i1 %t 79} 80 81define i1 @addition_with_extra_facts_and_args_ult_3(i16 noundef %a, i16 noundef %b, i16 noundef %c) { 82; CHECK-LABEL: define i1 @addition_with_extra_facts_and_args_ult_3( 83; CHECK-SAME: i16 noundef [[A:%.*]], i16 noundef [[B:%.*]], i16 noundef [[C:%.*]]) { 84; CHECK-NEXT: entry: 85; CHECK-NEXT: [[CMP_A:%.*]] = icmp ule i16 [[A]], 2048 86; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_A]]) 87; CHECK-NEXT: [[CMP_B:%.*]] = icmp ule i16 [[B]], 1024 88; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_B]]) 89; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i16 [[B]], [[A]] 90; CHECK-NEXT: [[CMP_ADD:%.*]] = icmp ult i16 [[ADD]], [[C]] 91; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_ADD]]) 92; CHECK-NEXT: ret i1 false 93; 94entry: 95 %cmp.a = icmp ule i16 %a, 2048 96 call void @llvm.assume(i1 %cmp.a) 97 %cmp.b = icmp ule i16 %b, 1024 98 call void @llvm.assume(i1 %cmp.b) 99 %add = add nuw nsw i16 %b, %a 100 %cmp.add = icmp ult i16 %add, %c 101 call void @llvm.assume(i1 %cmp.add) 102 %f = icmp uge i16 %a, %c 103 ret i1 %f 104} 105 106define i1 @addition_with_extra_facts_and_args_ult_4(i16 noundef %a, i16 noundef %b, i16 noundef %c) { 107; CHECK-LABEL: define i1 @addition_with_extra_facts_and_args_ult_4( 108; CHECK-SAME: i16 noundef [[A:%.*]], i16 noundef [[B:%.*]], i16 noundef [[C:%.*]]) { 109; CHECK-NEXT: entry: 110; CHECK-NEXT: [[CMP_A:%.*]] = icmp ule i16 [[A]], 2048 111; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_A]]) 112; CHECK-NEXT: [[CMP_B:%.*]] = icmp ule i16 [[B]], 1024 113; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_B]]) 114; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i16 [[B]], [[A]] 115; CHECK-NEXT: [[CMP_ADD:%.*]] = icmp ult i16 [[ADD]], [[C]] 116; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_ADD]]) 117; CHECK-NEXT: ret i1 false 118; 119entry: 120 %cmp.a = icmp ule i16 %a, 2048 121 call void @llvm.assume(i1 %cmp.a) 122 %cmp.b = icmp ule i16 %b, 1024 123 call void @llvm.assume(i1 %cmp.b) 124 %add = add nuw nsw i16 %b, %a 125 %cmp.add = icmp ult i16 %add, %c 126 call void @llvm.assume(i1 %cmp.add) 127 %f = icmp uge i16 %b, %c 128 ret i1 %f 129} 130 131define i1 @addition_with_extra_facts_and_args_ult_5(i16 noundef %a, i16 noundef %b, i16 noundef %c) { 132; CHECK-LABEL: define i1 @addition_with_extra_facts_and_args_ult_5( 133; CHECK-SAME: i16 noundef [[A:%.*]], i16 noundef [[B:%.*]], i16 noundef [[C:%.*]]) { 134; CHECK-NEXT: entry: 135; CHECK-NEXT: [[CMP_A:%.*]] = icmp ule i16 [[A]], 2048 136; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_A]]) 137; CHECK-NEXT: [[CMP_B:%.*]] = icmp ule i16 [[B]], 1024 138; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_B]]) 139; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i16 [[B]], [[A]] 140; CHECK-NEXT: [[CMP_ADD:%.*]] = icmp ult i16 [[ADD]], [[C]] 141; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_ADD]]) 142; CHECK-NEXT: [[CMP:%.*]] = icmp uge i16 [[A]], 10 143; CHECK-NEXT: ret i1 [[CMP]] 144; 145entry: 146 %cmp.a = icmp ule i16 %a, 2048 147 call void @llvm.assume(i1 %cmp.a) 148 %cmp.b = icmp ule i16 %b, 1024 149 call void @llvm.assume(i1 %cmp.b) 150 %add = add nuw nsw i16 %b, %a 151 %cmp.add = icmp ult i16 %add, %c 152 call void @llvm.assume(i1 %cmp.add) 153 %cmp = icmp uge i16 %a, 10 154 ret i1 %cmp 155} 156 157define i1 @addition_with_extra_facts_and_args_ult_6(i16 noundef %a, i16 noundef %b, i16 noundef %c) { 158; CHECK-LABEL: define i1 @addition_with_extra_facts_and_args_ult_6( 159; CHECK-SAME: i16 noundef [[A:%.*]], i16 noundef [[B:%.*]], i16 noundef [[C:%.*]]) { 160; CHECK-NEXT: entry: 161; CHECK-NEXT: [[CMP_A:%.*]] = icmp ule i16 [[A]], 2048 162; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_A]]) 163; CHECK-NEXT: [[CMP_B:%.*]] = icmp ule i16 [[B]], 1024 164; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_B]]) 165; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i16 [[B]], [[A]] 166; CHECK-NEXT: [[CMP_ADD:%.*]] = icmp ult i16 [[ADD]], [[C]] 167; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_ADD]]) 168; CHECK-NEXT: [[CMP:%.*]] = icmp ult i16 [[A]], [[B]] 169; CHECK-NEXT: ret i1 [[CMP]] 170; 171entry: 172 %cmp.a = icmp ule i16 %a, 2048 173 call void @llvm.assume(i1 %cmp.a) 174 %cmp.b = icmp ule i16 %b, 1024 175 call void @llvm.assume(i1 %cmp.b) 176 %add = add nuw nsw i16 %b, %a 177 %cmp.add = icmp ult i16 %add, %c 178 call void @llvm.assume(i1 %cmp.add) 179 %cmp = icmp ult i16 %a, %b 180 ret i1 %cmp 181} 182 183 184declare i16 @get() 185 186define i1 @addition_with_extra_facts_and_return_value_ult_1() { 187; CHECK-LABEL: define i1 @addition_with_extra_facts_and_return_value_ult_1() { 188; CHECK-NEXT: entry: 189; CHECK-NEXT: [[A:%.*]] = call i16 @get() 190; CHECK-NEXT: [[B:%.*]] = call i16 @get() 191; CHECK-NEXT: [[C:%.*]] = call i16 @get() 192; CHECK-NEXT: [[CMP_A:%.*]] = icmp ule i16 [[A]], 2048 193; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_A]]) 194; CHECK-NEXT: [[CMP_B:%.*]] = icmp ule i16 [[B]], 1024 195; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_B]]) 196; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i16 [[B]], [[A]] 197; CHECK-NEXT: [[CMP_ADD:%.*]] = icmp ult i16 [[ADD]], [[C]] 198; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_ADD]]) 199; CHECK-NEXT: ret i1 true 200; 201entry: 202 %a = call i16 @get() 203 %b = call i16 @get() 204 %c = call i16 @get() 205 %cmp.a = icmp ule i16 %a, 2048 206 call void @llvm.assume(i1 %cmp.a) 207 %cmp.b = icmp ule i16 %b, 1024 208 call void @llvm.assume(i1 %cmp.b) 209 %add = add nuw nsw i16 %b, %a 210 %cmp.add = icmp ult i16 %add, %c 211 call void @llvm.assume(i1 %cmp.add) 212 %t = icmp ult i16 %a, %c 213 ret i1 %t 214} 215 216define i1 @addition_with_extra_facts_and_return_value_ult_2() { 217; CHECK-LABEL: define i1 @addition_with_extra_facts_and_return_value_ult_2() { 218; CHECK-NEXT: entry: 219; CHECK-NEXT: [[A:%.*]] = call i16 @get() 220; CHECK-NEXT: [[B:%.*]] = call i16 @get() 221; CHECK-NEXT: [[C:%.*]] = call i16 @get() 222; CHECK-NEXT: [[CMP_A:%.*]] = icmp ule i16 [[A]], 2048 223; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_A]]) 224; CHECK-NEXT: [[CMP_B:%.*]] = icmp ule i16 [[B]], 1024 225; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_B]]) 226; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i16 [[B]], [[A]] 227; CHECK-NEXT: [[CMP_ADD:%.*]] = icmp ult i16 [[ADD]], [[C]] 228; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_ADD]]) 229; CHECK-NEXT: ret i1 false 230; 231entry: 232 %a = call i16 @get() 233 %b = call i16 @get() 234 %c = call i16 @get() 235 %cmp.a = icmp ule i16 %a, 2048 236 call void @llvm.assume(i1 %cmp.a) 237 %cmp.b = icmp ule i16 %b, 1024 238 call void @llvm.assume(i1 %cmp.b) 239 %add = add nuw nsw i16 %b, %a 240 %cmp.add = icmp ult i16 %add, %c 241 call void @llvm.assume(i1 %cmp.add) 242 %f = icmp uge i16 %a, %c 243 ret i1 %f 244} 245 246define i1 @addition_no_extra_facts_with_return_value_ult_1() { 247; CHECK-LABEL: define i1 @addition_no_extra_facts_with_return_value_ult_1() { 248; CHECK-NEXT: entry: 249; CHECK-NEXT: [[A:%.*]] = call i16 @get() 250; CHECK-NEXT: [[B:%.*]] = call i16 @get() 251; CHECK-NEXT: [[C:%.*]] = call i16 @get() 252; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i16 [[B]], [[A]] 253; CHECK-NEXT: [[CMP_ADD:%.*]] = icmp ult i16 [[ADD]], [[C]] 254; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_ADD]]) 255; CHECK-NEXT: ret i1 true 256; 257entry: 258 %a = call i16 @get() 259 %b = call i16 @get() 260 %c = call i16 @get() 261 %add = add nuw nsw i16 %b, %a 262 %cmp.add = icmp ult i16 %add, %c 263 call void @llvm.assume(i1 %cmp.add) 264 %t = icmp ult i16 %a, %c 265 ret i1 %t 266} 267 268define i1 @addition_no_extra_facts_with_return_value_ult_2() { 269; CHECK-LABEL: define i1 @addition_no_extra_facts_with_return_value_ult_2() { 270; CHECK-NEXT: entry: 271; CHECK-NEXT: [[A:%.*]] = call i16 @get() 272; CHECK-NEXT: [[B:%.*]] = call i16 @get() 273; CHECK-NEXT: [[C:%.*]] = call i16 @get() 274; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i16 [[B]], [[A]] 275; CHECK-NEXT: [[CMP_ADD:%.*]] = icmp ult i16 [[ADD]], [[C]] 276; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_ADD]]) 277; CHECK-NEXT: ret i1 false 278; 279entry: 280 %a = call i16 @get() 281 %b = call i16 @get() 282 %c = call i16 @get() 283 %add = add nuw nsw i16 %b, %a 284 %cmp.add = icmp ult i16 %add, %c 285 call void @llvm.assume(i1 %cmp.add) 286 %f = icmp uge i16 %a, %c 287 ret i1 %f 288} 289 290define i1 @addition_no_extra_facts_with_return_value_ult_3() { 291; CHECK-LABEL: define i1 @addition_no_extra_facts_with_return_value_ult_3() { 292; CHECK-NEXT: entry: 293; CHECK-NEXT: [[A:%.*]] = call i16 @get() 294; CHECK-NEXT: [[B:%.*]] = call i16 @get() 295; CHECK-NEXT: [[C:%.*]] = call i16 @get() 296; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i16 [[B]], [[A]] 297; CHECK-NEXT: [[CMP_ADD:%.*]] = icmp ult i16 [[ADD]], [[C]] 298; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_ADD]]) 299; CHECK-NEXT: [[CMP:%.*]] = icmp uge i16 [[A]], 9 300; CHECK-NEXT: ret i1 [[CMP]] 301; 302entry: 303 %a = call i16 @get() 304 %b = call i16 @get() 305 %c = call i16 @get() 306 %add = add nuw nsw i16 %b, %a 307 %cmp.add = icmp ult i16 %add, %c 308 call void @llvm.assume(i1 %cmp.add) 309 %cmp = icmp uge i16 %a, 9 310 ret i1 %cmp 311} 312 313; Test for https://github.com/llvm/llvm-project/issues/63490. 314define i1 @assume_x_ugt_y_plus_y_via_shl_eq(i8 %x, i8 %y) { 315; CHECK-LABEL: define i1 @assume_x_ugt_y_plus_y_via_shl_eq( 316; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) { 317; CHECK-NEXT: [[S:%.*]] = shl nuw i8 [[Y]], 1 318; CHECK-NEXT: [[C_1:%.*]] = icmp ugt i8 [[X]], [[S]] 319; CHECK-NEXT: tail call void @llvm.assume(i1 [[C_1]]) 320; CHECK-NEXT: ret i1 false 321; 322 %s = shl nuw i8 %y, 1 323 %c.1 = icmp ugt i8 %x, %s 324 tail call void @llvm.assume(i1 %c.1) 325 %c.2 = icmp eq i8 %x, %y 326 ret i1 %c.2 327} 328 329define i1 @assume_x_ugt_y_plus_y_via_shl_eq_no_nuw(i8 %x, i8 %y) { 330; CHECK-LABEL: define i1 @assume_x_ugt_y_plus_y_via_shl_eq_no_nuw( 331; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) { 332; CHECK-NEXT: [[S:%.*]] = shl i8 [[Y]], 1 333; CHECK-NEXT: [[C_1:%.*]] = icmp ugt i8 [[X]], [[S]] 334; CHECK-NEXT: tail call void @llvm.assume(i1 [[C_1]]) 335; CHECK-NEXT: [[C_2:%.*]] = icmp eq i8 [[X]], [[Y]] 336; CHECK-NEXT: ret i1 [[C_2]] 337; 338 %s = shl i8 %y, 1 339 %c.1 = icmp ugt i8 %x, %s 340 tail call void @llvm.assume(i1 %c.1) 341 %c.2 = icmp eq i8 %x, %y 342 ret i1 %c.2 343} 344 345define i1 @assume_x_ugt_y_plus_y_via_add_eq(i8 %x, i8 %y) { 346; CHECK-LABEL: define i1 @assume_x_ugt_y_plus_y_via_add_eq( 347; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) { 348; CHECK-NEXT: [[S:%.*]] = add nuw i8 [[Y]], [[Y]] 349; CHECK-NEXT: [[C_1:%.*]] = icmp ugt i8 [[X]], [[S]] 350; CHECK-NEXT: tail call void @llvm.assume(i1 [[C_1]]) 351; CHECK-NEXT: ret i1 false 352; 353 %s = add nuw i8 %y, %y 354 %c.1 = icmp ugt i8 %x, %s 355 tail call void @llvm.assume(i1 %c.1) 356 %c.2 = icmp eq i8 %x, %y 357 ret i1 %c.2 358} 359 360define i1 @assume_x_ugt_y_plus_y_via_add_eq_no_nuw(i8 %x, i8 %y) { 361; CHECK-LABEL: define i1 @assume_x_ugt_y_plus_y_via_add_eq_no_nuw( 362; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) { 363; CHECK-NEXT: [[S:%.*]] = add i8 [[Y]], [[Y]] 364; CHECK-NEXT: [[C_1:%.*]] = icmp ugt i8 [[X]], [[S]] 365; CHECK-NEXT: tail call void @llvm.assume(i1 [[C_1]]) 366; CHECK-NEXT: [[C_2:%.*]] = icmp eq i8 [[X]], [[Y]] 367; CHECK-NEXT: ret i1 [[C_2]] 368; 369 %s = add i8 %y, %y 370 %c.1 = icmp ugt i8 %x, %s 371 tail call void @llvm.assume(i1 %c.1) 372 %c.2 = icmp eq i8 %x, %y 373 ret i1 %c.2 374} 375 376define i1 @assume_x_ugt_y_plus_y_via_shl_ne(i8 %x, i8 %y) { 377; CHECK-LABEL: define i1 @assume_x_ugt_y_plus_y_via_shl_ne( 378; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) { 379; CHECK-NEXT: [[S:%.*]] = shl nuw i8 [[Y]], 1 380; CHECK-NEXT: [[C_1:%.*]] = icmp ugt i8 [[X]], [[S]] 381; CHECK-NEXT: tail call void @llvm.assume(i1 [[C_1]]) 382; CHECK-NEXT: ret i1 true 383; 384 %s = shl nuw i8 %y, 1 385 %c.1 = icmp ugt i8 %x, %s 386 tail call void @llvm.assume(i1 %c.1) 387 %c.2 = icmp ne i8 %x, %y 388 ret i1 %c.2 389} 390