1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s 3 4declare void @use(i1) 5 6define void @test_unsigned_too_large(i128 %x) { 7; CHECK-LABEL: @test_unsigned_too_large( 8; CHECK-NEXT: entry: 9; CHECK-NEXT: [[C_1:%.*]] = icmp ule i128 [[X:%.*]], 12345678901234123123123 10; CHECK-NEXT: br i1 [[C_1]], label [[BB1:%.*]], label [[BB2:%.*]] 11; CHECK: bb1: 12; CHECK-NEXT: [[C_2:%.*]] = icmp ult i128 [[X]], -12345678901234123123123 13; CHECK-NEXT: call void @use(i1 [[C_2]]) 14; CHECK-NEXT: [[C_3:%.*]] = icmp uge i128 [[X]], -12345678901234123123123 15; CHECK-NEXT: call void @use(i1 [[C_3]]) 16; CHECK-NEXT: [[C_4:%.*]] = icmp uge i128 [[X]], -12345678901234123123123 17; CHECK-NEXT: call void @use(i1 [[C_4]]) 18; CHECK-NEXT: ret void 19; CHECK: bb2: 20; CHECK-NEXT: ret void 21; 22entry: 23 %c.1 = icmp ule i128 %x, 12345678901234123123123 24 br i1 %c.1, label %bb1, label %bb2 25 26bb1: 27 %c.2 = icmp ult i128 %x, -12345678901234123123123 28 call void @use(i1 %c.2) 29 %c.3 = icmp uge i128 %x, -12345678901234123123123 30 call void @use(i1 %c.3) 31 %c.4 = icmp uge i128 %x, -12345678901234123123123 32 call void @use(i1 %c.4) 33 ret void 34 35bb2: 36 ret void 37} 38 39define void @test_signed_too_large(i128 %x) { 40; CHECK-LABEL: @test_signed_too_large( 41; CHECK-NEXT: entry: 42; CHECK-NEXT: [[C_1:%.*]] = icmp sle i128 [[X:%.*]], 12345678901234123123123 43; CHECK-NEXT: br i1 [[C_1]], label [[BB1:%.*]], label [[BB2:%.*]] 44; CHECK: bb1: 45; CHECK-NEXT: [[C_2:%.*]] = icmp slt i128 [[X]], -12345678901234123123123 46; CHECK-NEXT: call void @use(i1 [[C_2]]) 47; CHECK-NEXT: [[C_3:%.*]] = icmp sge i128 [[X]], -12345678901234123123123 48; CHECK-NEXT: call void @use(i1 [[C_3]]) 49; CHECK-NEXT: [[C_4:%.*]] = icmp sge i128 [[X]], -12345678901234123123123 50; CHECK-NEXT: call void @use(i1 [[C_4]]) 51; CHECK-NEXT: ret void 52; CHECK: bb2: 53; CHECK-NEXT: ret void 54; 55entry: 56 %c.1 = icmp sle i128 %x, 12345678901234123123123 57 br i1 %c.1, label %bb1, label %bb2 58 59bb1: 60 %c.2 = icmp slt i128 %x, -12345678901234123123123 61 call void @use(i1 %c.2) 62 %c.3 = icmp sge i128 %x, -12345678901234123123123 63 call void @use(i1 %c.3) 64 %c.4 = icmp sge i128 %x, -12345678901234123123123 65 call void @use(i1 %c.4) 66 ret void 67 68bb2: 69 ret void 70} 71 72define i1 @add_decomp_i80(i80 %a) { 73; CHECK-LABEL: @add_decomp_i80( 74; CHECK-NEXT: entry: 75; CHECK-NEXT: [[ADD:%.*]] = add nsw i80 [[A:%.*]], -1973801615886922022913 76; CHECK-NEXT: [[C:%.*]] = icmp ult i80 [[ADD]], 1346612317380797267967 77; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[ELSE:%.*]] 78; CHECK: then: 79; CHECK-NEXT: [[ADD_1:%.*]] = add nsw i80 [[A]], -1973801615886922022913 80; CHECK-NEXT: [[C_1:%.*]] = icmp ult i80 [[ADD_1]], 1346612317380797267967 81; CHECK-NEXT: ret i1 [[C_1]] 82; CHECK: else: 83; CHECK-NEXT: ret i1 false 84; 85entry: 86 %add = add nsw i80 %a, -1973801615886922022913 87 %c = icmp ult i80 %add, 1346612317380797267967 88 br i1 %c, label %then, label %else 89 90then: 91 %add.1 = add nsw i80 %a, -1973801615886922022913 92 %c.1 = icmp ult i80 %add.1, 1346612317380797267967 93 ret i1 %c.1 94 95else: 96 ret i1 false 97} 98 99; TODO: This could be folded. 100define i1 @sub_decomp_i80(i80 %a) { 101; CHECK-LABEL: @sub_decomp_i80( 102; CHECK-NEXT: entry: 103; CHECK-NEXT: [[SUB:%.*]] = sub nuw i80 [[A:%.*]], 1973801615886922022913 104; CHECK-NEXT: [[C:%.*]] = icmp ult i80 [[SUB]], 1346612317380797267967 105; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[ELSE:%.*]] 106; CHECK: then: 107; CHECK-NEXT: [[SUB_1:%.*]] = sub nuw i80 [[A]], 1973801615886922022913 108; CHECK-NEXT: [[C_1:%.*]] = icmp ult i80 [[SUB_1]], 1346612317380797267967 109; CHECK-NEXT: ret i1 [[C_1]] 110; CHECK: else: 111; CHECK-NEXT: ret i1 false 112; 113entry: 114 %sub = sub nuw i80 %a, 1973801615886922022913 115 %c = icmp ult i80 %sub, 1346612317380797267967 116 br i1 %c, label %then, label %else 117 118then: 119 %sub.1 = sub nuw i80 %a, 1973801615886922022913 120 %c.1 = icmp ult i80 %sub.1, 1346612317380797267967 121 ret i1 %c.1 122 123else: 124 ret i1 false 125} 126 127define i1 @gep_decomp_i80(ptr %a) { 128; CHECK-LABEL: @gep_decomp_i80( 129; CHECK-NEXT: entry: 130; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i8, ptr [[A:%.*]], i80 1973801615886922022913 131; CHECK-NEXT: br i1 false, label [[THEN:%.*]], label [[ELSE:%.*]] 132; CHECK: then: 133; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds i8, ptr [[A]], i80 1973801615886922022913 134; CHECK-NEXT: ret i1 true 135; CHECK: else: 136; CHECK-NEXT: ret i1 false 137; 138entry: 139 %gep = getelementptr inbounds i8, ptr %a, i80 1973801615886922022913 140 %c = icmp eq ptr %gep, null 141 br i1 %c, label %then, label %else 142 143then: 144 %gep.1 = getelementptr inbounds i8, ptr %a, i80 1973801615886922022913 145 %c.1 = icmp eq ptr %gep.1, null 146 ret i1 %c.1 147 148else: 149 ret i1 false 150} 151 152define i1 @gep_zext_shl_decomp_i80(ptr %a, i80 %v) { 153; CHECK-LABEL: @gep_zext_shl_decomp_i80( 154; CHECK-NEXT: entry: 155; CHECK-NEXT: [[SHL:%.*]] = shl nuw i80 [[V:%.*]], 1973801615886922022913 156; CHECK-NEXT: [[EXT:%.*]] = zext i80 [[SHL]] to i128 157; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i8, ptr [[A:%.*]], i128 [[EXT]] 158; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[GEP]], null 159; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[ELSE:%.*]] 160; CHECK: then: 161; CHECK-NEXT: [[SHL_1:%.*]] = shl nuw i80 [[V]], 1973801615886922022913 162; CHECK-NEXT: [[EXT_1:%.*]] = zext i80 [[SHL_1]] to i128 163; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds i8, ptr [[A]], i128 [[EXT_1]] 164; CHECK-NEXT: [[C_1:%.*]] = icmp eq ptr [[GEP_1]], null 165; CHECK-NEXT: ret i1 [[C_1]] 166; CHECK: else: 167; CHECK-NEXT: ret i1 false 168; 169entry: 170 %shl = shl nuw i80 %v, 1973801615886922022913 171 %ext = zext i80 %shl to i128 172 %gep = getelementptr inbounds i8, ptr %a, i128 %ext 173 %c = icmp eq ptr %gep, null 174 br i1 %c, label %then, label %else 175 176then: 177 %shl.1 = shl nuw i80 %v, 1973801615886922022913 178 %ext.1 = zext i80 %shl.1 to i128 179 %gep.1 = getelementptr inbounds i8, ptr %a, i128 %ext.1 180 %c.1 = icmp eq ptr %gep.1, null 181 ret i1 %c.1 182 183else: 184 ret i1 false 185} 186 187define i1 @gep_zext_add_decomp_i80(ptr %a, i80 %v) { 188; CHECK-LABEL: @gep_zext_add_decomp_i80( 189; CHECK-NEXT: entry: 190; CHECK-NEXT: [[ADD:%.*]] = add nsw i80 [[V:%.*]], 1973801615886922022913 191; CHECK-NEXT: [[EXT:%.*]] = zext i80 [[ADD]] to i128 192; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i8, ptr [[A:%.*]], i128 [[EXT]] 193; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[GEP]], null 194; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[ELSE:%.*]] 195; CHECK: then: 196; CHECK-NEXT: [[ADD_1:%.*]] = add nsw i80 [[V]], 1973801615886922022913 197; CHECK-NEXT: [[EXT_1:%.*]] = zext i80 [[ADD_1]] to i128 198; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds i8, ptr [[A]], i128 [[EXT_1]] 199; CHECK-NEXT: [[C_1:%.*]] = icmp eq ptr [[GEP_1]], null 200; CHECK-NEXT: ret i1 [[C_1]] 201; CHECK: else: 202; CHECK-NEXT: ret i1 false 203; 204entry: 205 %add = add nsw i80 %v, 1973801615886922022913 206 %ext = zext i80 %add to i128 207 %gep = getelementptr inbounds i8, ptr %a, i128 %ext 208 %c = icmp eq ptr %gep, null 209 br i1 %c, label %then, label %else 210 211then: 212 %add.1 = add nsw i80 %v, 1973801615886922022913 213 %ext.1 = zext i80 %add.1 to i128 214 %gep.1 = getelementptr inbounds i8, ptr %a, i128 %ext.1 215 %c.1 = icmp eq ptr %gep.1, null 216 ret i1 %c.1 217 218else: 219 ret i1 false 220} 221 222define i1 @gep_shl_decomp_i80(ptr %a, i80 %v) { 223; CHECK-LABEL: @gep_shl_decomp_i80( 224; CHECK-NEXT: entry: 225; CHECK-NEXT: [[SHL:%.*]] = shl nuw i80 [[V:%.*]], 1973801615886922022913 226; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i8, ptr [[A:%.*]], i80 [[SHL]] 227; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[GEP]], null 228; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[ELSE:%.*]] 229; CHECK: then: 230; CHECK-NEXT: [[SHL_1:%.*]] = shl nuw i80 [[V]], 1973801615886922022913 231; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds i8, ptr [[A]], i80 [[SHL_1]] 232; CHECK-NEXT: [[C_1:%.*]] = icmp eq ptr [[GEP_1]], null 233; CHECK-NEXT: ret i1 [[C_1]] 234; CHECK: else: 235; CHECK-NEXT: ret i1 false 236; 237entry: 238 %shl = shl nuw i80 %v, 1973801615886922022913 239 %gep = getelementptr inbounds i8, ptr %a, i80 %shl 240 %c = icmp eq ptr %gep, null 241 br i1 %c, label %then, label %else 242 243then: 244 %shl.1 = shl nuw i80 %v, 1973801615886922022913 245 %gep.1 = getelementptr inbounds i8, ptr %a, i80 %shl.1 246 %c.1 = icmp eq ptr %gep.1, null 247 ret i1 %c.1 248 249else: 250 ret i1 false 251} 252 253define i1 @gep_add_decomp_i80(ptr %a, i80 %v) { 254; CHECK-LABEL: @gep_add_decomp_i80( 255; CHECK-NEXT: entry: 256; CHECK-NEXT: [[ADD:%.*]] = add nsw i80 [[V:%.*]], 1973801615886922022913 257; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i8, ptr [[A:%.*]], i80 [[ADD]] 258; CHECK-NEXT: [[C:%.*]] = icmp eq ptr [[GEP]], null 259; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[ELSE:%.*]] 260; CHECK: then: 261; CHECK-NEXT: [[ADD_1:%.*]] = add nsw i80 [[V]], 1973801615886922022913 262; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds i8, ptr [[A]], i80 [[ADD_1]] 263; CHECK-NEXT: [[C_1:%.*]] = icmp eq ptr [[GEP_1]], null 264; CHECK-NEXT: ret i1 [[C_1]] 265; CHECK: else: 266; CHECK-NEXT: ret i1 false 267; 268entry: 269 %add = add nsw i80 %v, 1973801615886922022913 270 %gep = getelementptr inbounds i8, ptr %a, i80 %add 271 %c = icmp eq ptr %gep, null 272 br i1 %c, label %then, label %else 273 274then: 275 %add.1 = add nsw i80 %v, 1973801615886922022913 276 %gep.1 = getelementptr inbounds i8, ptr %a, i80 %add.1 277 %c.1 = icmp eq ptr %gep.1, null 278 ret i1 %c.1 279 280else: 281 ret i1 false 282} 283 284define i1 @mul_nsw_decomp(i128 %x) { 285; CHECK-LABEL: @mul_nsw_decomp( 286; CHECK-NEXT: [[VAL:%.*]] = mul nsw i128 [[X:%.*]], 9223372036854775808 287; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i128 [[X]], [[VAL]] 288; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]] 289; CHECK: then: 290; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i128 [[X]], 0 291; CHECK-NEXT: ret i1 [[CMP2]] 292; CHECK: else: 293; CHECK-NEXT: ret i1 false 294; 295 %val = mul nsw i128 %x, 9223372036854775808 296 %cmp = icmp sgt i128 %x, %val 297 br i1 %cmp, label %then, label %else 298 299then: 300 %cmp2 = icmp sgt i128 %x, 0 301 ret i1 %cmp2 302 303else: 304 ret i1 false 305} 306 307define i1 @add_nuw_decomp_recursive() { 308; CHECK-LABEL: @add_nuw_decomp_recursive( 309; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i64 -9223372036854775808, 10 310; CHECK-NEXT: [[CMP:%.*]] = icmp uge i64 [[ADD]], 10 311; CHECK-NEXT: ret i1 [[CMP]] 312; 313 %add = add nuw nsw i64 -9223372036854775808, 10 314 %cmp = icmp uge i64 %add, 10 315 ret i1 %cmp 316} 317 318define i1 @add_minus_one_decomp_recursive() { 319; CHECK-LABEL: @add_minus_one_decomp_recursive( 320; CHECK-NEXT: [[ADD:%.*]] = add i64 -9223372036854775808, -1 321; CHECK-NEXT: [[CMP:%.*]] = icmp uge i64 [[ADD]], 10 322; CHECK-NEXT: ret i1 [[CMP]] 323; 324 %add = add i64 -9223372036854775808, -1 325 %cmp = icmp uge i64 %add, 10 326 ret i1 %cmp 327} 328 329define i1 @gep_decomp_large_index_31_bits(ptr %a) { 330; CHECK-LABEL: @gep_decomp_large_index_31_bits( 331; CHECK-NEXT: entry: 332; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds i64, ptr [[A:%.*]], i64 2147483646 333; CHECK-NEXT: [[GEP_2:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 2147483647 334; CHECK-NEXT: [[NE:%.*]] = icmp ne ptr [[GEP_1]], [[GEP_2]] 335; CHECK-NEXT: call void @llvm.assume(i1 [[NE]]) 336; CHECK-NEXT: [[CMP_ULE:%.*]] = icmp ule ptr [[GEP_1]], [[GEP_2]] 337; CHECK-NEXT: [[CMP_UGE:%.*]] = icmp uge ptr [[GEP_1]], [[GEP_2]] 338; CHECK-NEXT: [[RES:%.*]] = xor i1 true, false 339; CHECK-NEXT: ret i1 [[RES]] 340; 341entry: 342 %gep.1 = getelementptr inbounds i64, ptr %a, i64 2147483646 343 %gep.2 = getelementptr inbounds i64, ptr %a, i64 2147483647 344 %ne = icmp ne ptr %gep.1, %gep.2 345 call void @llvm.assume(i1 %ne) 346 %cmp.ule = icmp ule ptr %gep.1, %gep.2 347 %cmp.uge = icmp uge ptr %gep.1, %gep.2 348 %res = xor i1 true, false 349 ret i1 %res 350} 351 352define i1 @gep_decomp_large_index_63_bits(ptr %a) { 353; CHECK-LABEL: @gep_decomp_large_index_63_bits( 354; CHECK-NEXT: entry: 355; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds i64, ptr [[A:%.*]], i64 9223372036854775804 356; CHECK-NEXT: [[GEP_2:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 9223372036854775805 357; CHECK-NEXT: [[NE:%.*]] = icmp ne ptr [[GEP_1]], [[GEP_2]] 358; CHECK-NEXT: call void @llvm.assume(i1 [[NE]]) 359; CHECK-NEXT: [[CMP_UGE:%.*]] = icmp uge ptr [[GEP_1]], [[GEP_2]] 360; CHECK-NEXT: [[RES:%.*]] = xor i1 true, true 361; CHECK-NEXT: ret i1 [[RES]] 362; 363entry: 364 %gep.1 = getelementptr inbounds i64, ptr %a, i64 9223372036854775804 365 %gep.2 = getelementptr inbounds i64, ptr %a, i64 9223372036854775805 366 %ne = icmp ne ptr %gep.1, %gep.2 367 call void @llvm.assume(i1 %ne) 368 %cmp.ule = icmp ule ptr %gep.1, %gep.2 369 %cmp.uge = icmp uge ptr %gep.1, %gep.2 370 %res = xor i1 %cmp.ule, %cmp.ule 371 ret i1 %res 372} 373 374define i1 @gep_decomp_large_index_63_bits_chained_overflow(ptr %a) { 375; CHECK-LABEL: @gep_decomp_large_index_63_bits_chained_overflow( 376; CHECK-NEXT: entry: 377; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds i64, ptr [[A:%.*]], i64 9223372036854775804 378; CHECK-NEXT: [[GEP_2:%.*]] = getelementptr inbounds ptr, ptr [[A]], i64 1152921504606846976 379; CHECK-NEXT: [[GEP_3:%.*]] = getelementptr inbounds i64, ptr [[GEP_2]], i64 1152921504606846976 380; CHECK-NEXT: [[NE:%.*]] = icmp ne ptr [[GEP_1]], [[GEP_3]] 381; CHECK-NEXT: call void @llvm.assume(i1 [[NE]]) 382; CHECK-NEXT: [[CMP_UGE:%.*]] = icmp uge ptr [[GEP_1]], [[GEP_3]] 383; CHECK-NEXT: [[RES:%.*]] = xor i1 true, true 384; CHECK-NEXT: ret i1 [[RES]] 385; 386entry: 387 %gep.1 = getelementptr inbounds i64, ptr %a, i64 9223372036854775804 388 %gep.2 = getelementptr inbounds ptr, ptr %a, i64 1152921504606846976 389 %gep.3 = getelementptr inbounds i64, ptr %gep.2, i64 1152921504606846976 390 %ne = icmp ne ptr %gep.1, %gep.3 391 call void @llvm.assume(i1 %ne) 392 %cmp.ule = icmp ule ptr %gep.1, %gep.3 393 %cmp.uge = icmp uge ptr %gep.1, %gep.3 394 %res = xor i1 %cmp.ule, %cmp.ule 395 ret i1 %res 396} 397 398%struct = type { [128 x i64], [2 x i32] } 399 400define i1 @gep_decomp_large_index_63_bits_overflow_struct(ptr %a) { 401; CHECK-LABEL: @gep_decomp_large_index_63_bits_overflow_struct( 402; CHECK-NEXT: entry: 403; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds i64, ptr [[A:%.*]], i64 9223372036854775804 404; CHECK-NEXT: [[GEP_2:%.*]] = getelementptr inbounds [[STRUCT:%.*]], ptr [[A]], i64 8937376004704240, i32 1, i32 1 405; CHECK-NEXT: [[NE:%.*]] = icmp ne ptr [[GEP_1]], [[GEP_2]] 406; CHECK-NEXT: call void @llvm.assume(i1 [[NE]]) 407; CHECK-NEXT: [[CMP_UGE:%.*]] = icmp uge ptr [[GEP_1]], [[GEP_2]] 408; CHECK-NEXT: [[RES:%.*]] = xor i1 false, false 409; CHECK-NEXT: ret i1 [[RES]] 410; 411entry: 412 %gep.1 = getelementptr inbounds i64, ptr %a, i64 9223372036854775804 413 %gep.2 = getelementptr inbounds %struct, ptr %a, i64 8937376004704240, i32 1, i32 1 414 %ne = icmp ne ptr %gep.1, %gep.2 415 call void @llvm.assume(i1 %ne) 416 %cmp.ule = icmp ule ptr %gep.1, %gep.2 417 %cmp.uge = icmp uge ptr %gep.1, %gep.2 418 %res = xor i1 %cmp.ule, %cmp.ule 419 ret i1 %res 420} 421 422define i1 @pr68751(i128 %arg) { 423; CHECK-LABEL: @pr68751( 424; CHECK-NEXT: [[SHL1:%.*]] = shl nuw nsw i128 [[ARG:%.*]], 32 425; CHECK-NEXT: [[SHL2:%.*]] = shl nuw nsw i128 [[SHL1]], 32 426; CHECK-NEXT: [[CMP:%.*]] = icmp eq i128 [[SHL2]], 0 427; CHECK-NEXT: ret i1 [[CMP]] 428; 429 %shl1 = shl nuw nsw i128 %arg, 32 430 %shl2 = shl nuw nsw i128 %shl1, 32 431 %cmp = icmp eq i128 %shl2, 0 432 ret i1 %cmp 433} 434 435declare void @llvm.assume(i1) 436