1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-attributes 2; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s 3 4declare void @llvm.assume(i1) 5 6define i1 @test_eq_ne_0(i8 %a, i8 %b) { 7; CHECK-LABEL: @test_eq_ne_0( 8; CHECK-NEXT: entry: 9; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[A:%.*]], 0 10; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]] 11; CHECK: then: 12; CHECK-NEXT: [[C_2:%.*]] = icmp ne i8 [[A]], [[B:%.*]] 13; CHECK-NEXT: [[RES_1:%.*]] = xor i1 false, true 14; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_2]] 15; CHECK-NEXT: ret i1 [[RES_2]] 16; CHECK: else: 17; CHECK-NEXT: [[C_3:%.*]] = icmp ne i8 [[A]], 1 18; CHECK-NEXT: [[C_4:%.*]] = icmp ne i8 [[A]], [[B]] 19; CHECK-NEXT: [[RES_3:%.*]] = xor i1 true, [[C_3]] 20; CHECK-NEXT: [[RES_4:%.*]] = xor i1 [[RES_3]], [[C_4]] 21; CHECK-NEXT: ret i1 [[RES_4]] 22; 23entry: 24 %cmp = icmp eq i8 %a, 0 25 br i1 %cmp, label %then, label %else 26 27then: 28 %f.1 = icmp ne i8 %a, 0 29 %c.1 = icmp ne i8 %a, 1 30 %c.2 = icmp ne i8 %a, %b 31 %res.1 = xor i1 %f.1, %c.1 32 %res.2 = xor i1 %res.1, %c.2 33 ret i1 %res.2 34 35else: 36 %t.1 = icmp ne i8 %a, 0 37 %c.3 = icmp ne i8 %a, 1 38 %c.4 = icmp ne i8 %a, %b 39 %res.3 = xor i1 %t.1, %c.3 40 %res.4 = xor i1 %res.3, %c.4 41 ret i1 %res.4 42} 43 44define i1 @test_ne_eq_0(i8 %a, i8 %b) { 45; CHECK-LABEL: @test_ne_eq_0( 46; CHECK-NEXT: entry: 47; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[A:%.*]], 0 48; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]] 49; CHECK: then: 50; CHECK-NEXT: [[C_1:%.*]] = icmp ne i8 [[A]], 1 51; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, [[C_1]] 52; CHECK-NEXT: [[C_2:%.*]] = icmp ne i8 [[A]], [[B:%.*]] 53; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_2]] 54; CHECK-NEXT: [[C_3:%.*]] = icmp eq i8 [[A]], [[B]] 55; CHECK-NEXT: [[RES_3:%.*]] = xor i1 [[RES_2]], [[C_3]] 56; CHECK-NEXT: [[RES_4:%.*]] = xor i1 [[RES_3]], false 57; CHECK-NEXT: [[RES_5:%.*]] = xor i1 [[RES_4]], true 58; CHECK-NEXT: [[RES_6:%.*]] = xor i1 [[RES_5]], true 59; CHECK-NEXT: [[C_5:%.*]] = icmp ugt i8 [[A]], 1 60; CHECK-NEXT: [[RES_7:%.*]] = xor i1 [[RES_6]], [[C_5]] 61; CHECK-NEXT: [[C_6:%.*]] = icmp sgt i8 [[A]], 0 62; CHECK-NEXT: [[RES_8:%.*]] = xor i1 [[RES_7]], [[C_6]] 63; CHECK-NEXT: ret i1 [[RES_8]] 64; CHECK: else: 65; CHECK-NEXT: [[RES_9:%.*]] = xor i1 false, true 66; CHECK-NEXT: [[C_8:%.*]] = icmp ne i8 [[A]], [[B]] 67; CHECK-NEXT: [[RES_10:%.*]] = xor i1 [[RES_9]], [[C_8]] 68; CHECK-NEXT: [[C_9:%.*]] = icmp eq i8 [[A]], [[B]] 69; CHECK-NEXT: [[RES_11:%.*]] = xor i1 [[RES_10]], [[C_9]] 70; CHECK-NEXT: [[RES_12:%.*]] = xor i1 [[RES_11]], true 71; CHECK-NEXT: [[RES_13:%.*]] = xor i1 [[RES_12]], false 72; CHECK-NEXT: [[RES_14:%.*]] = xor i1 [[RES_13]], false 73; CHECK-NEXT: [[RES_15:%.*]] = xor i1 [[RES_14]], false 74; CHECK-NEXT: [[RES_16:%.*]] = xor i1 [[RES_15]], false 75; CHECK-NEXT: ret i1 [[RES_16]] 76; 77entry: 78 %cmp = icmp ne i8 %a, 0 79 br i1 %cmp, label %then, label %else 80 81then: 82 %t.1 = icmp ne i8 %a, 0 83 %c.1 = icmp ne i8 %a, 1 84 %res.1 = xor i1 %t.1, %c.1 85 86 %c.2 = icmp ne i8 %a, %b 87 %res.2 = xor i1 %res.1, %c.2 88 89 %c.3 = icmp eq i8 %a, %b 90 %res.3 = xor i1 %res.2, %c.3 91 92 %c.4 = icmp eq i8 %a, 0 93 %res.4 = xor i1 %res.3, %c.4 94 95 %t.2 = icmp ugt i8 %a, 0 96 %res.5 = xor i1 %res.4, %t.2 97 98 %t.3 = icmp uge i8 %a, 1 99 %res.6 = xor i1 %res.5, %t.3 100 101 %c.5 = icmp ugt i8 %a, 1 102 %res.7 = xor i1 %res.6, %c.5 103 104 %c.6 = icmp sgt i8 %a, 0 105 %res.8 = xor i1 %res.7, %c.6 106 107 ret i1 %res.8 108 109else: 110 %f.1 = icmp ne i8 %a, 0 111 %c.7 = icmp ne i8 %a, 1 112 %res.9 = xor i1 %f.1, %c.7 113 114 %c.8 = icmp ne i8 %a, %b 115 %res.10 = xor i1 %res.9, %c.8 116 117 %c.9 = icmp eq i8 %a, %b 118 %res.11 = xor i1 %res.10, %c.9 119 120 %c.10 = icmp eq i8 %a, 0 121 %res.12 = xor i1 %res.11, %c.10 122 123 %f.2 = icmp ugt i8 %a, 0 124 %res.13 = xor i1 %res.12, %f.2 125 126 %f.3 = icmp uge i8 %a, 1 127 %res.14 = xor i1 %res.13, %f.3 128 129 %c.11 = icmp ugt i8 %a, 1 130 %res.15 = xor i1 %res.14, %c.11 131 132 %c.12 = icmp sgt i8 %a, 0 133 %res.16 = xor i1 %res.15, %c.12 134 135 ret i1 %res.16 136} 137 138define i1 @test_eq_ne_1(i8 %a, i8 %b) { 139; CHECK-LABEL: @test_eq_ne_1( 140; CHECK-NEXT: entry: 141; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[A:%.*]], 1 142; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]] 143; CHECK: then: 144; CHECK-NEXT: [[C_2:%.*]] = icmp ne i8 [[A]], [[B:%.*]] 145; CHECK-NEXT: [[RES_1:%.*]] = xor i1 true, false 146; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_2]] 147; CHECK-NEXT: ret i1 [[RES_2]] 148; CHECK: else: 149; CHECK-NEXT: [[T_1:%.*]] = icmp ne i8 [[A]], 0 150; CHECK-NEXT: [[C_3:%.*]] = icmp ne i8 [[A]], 1 151; CHECK-NEXT: [[C_4:%.*]] = icmp ne i8 [[A]], [[B]] 152; CHECK-NEXT: [[RES_3:%.*]] = xor i1 [[T_1]], [[C_3]] 153; CHECK-NEXT: [[RES_4:%.*]] = xor i1 [[RES_3]], [[C_4]] 154; CHECK-NEXT: ret i1 [[RES_4]] 155; 156entry: 157 %cmp = icmp eq i8 %a, 1 158 br i1 %cmp, label %then, label %else 159 160then: 161 %f.1 = icmp ne i8 %a, 0 162 %c.1 = icmp ne i8 %a, 1 163 %c.2 = icmp ne i8 %a, %b 164 %res.1 = xor i1 %f.1, %c.1 165 %res.2 = xor i1 %res.1, %c.2 166 ret i1 %res.2 167 168else: 169 %t.1 = icmp ne i8 %a, 0 170 %c.3 = icmp ne i8 %a, 1 171 %c.4 = icmp ne i8 %a, %b 172 %res.3 = xor i1 %t.1, %c.3 173 %res.4 = xor i1 %res.3, %c.4 174 ret i1 %res.4 175} 176 177define i1 @test_ne_eq_1(i8 %a, i8 %b) { 178; CHECK-LABEL: @test_ne_eq_1( 179; CHECK-NEXT: entry: 180; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[A:%.*]], 1 181; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]] 182; CHECK: then: 183; CHECK-NEXT: [[T_1:%.*]] = icmp ne i8 [[A]], 1 184; CHECK-NEXT: [[C_1:%.*]] = icmp ne i8 [[A]], 0 185; CHECK-NEXT: [[RES_1:%.*]] = xor i1 [[T_1]], [[C_1]] 186; CHECK-NEXT: [[C_2:%.*]] = icmp ne i8 [[A]], [[B:%.*]] 187; CHECK-NEXT: [[RES_2:%.*]] = xor i1 [[RES_1]], [[C_2]] 188; CHECK-NEXT: [[C_3:%.*]] = icmp eq i8 [[A]], [[B]] 189; CHECK-NEXT: [[RES_3:%.*]] = xor i1 [[RES_2]], [[C_3]] 190; CHECK-NEXT: [[C_4:%.*]] = icmp eq i8 [[A]], 0 191; CHECK-NEXT: [[RES_4:%.*]] = xor i1 [[RES_3]], [[C_4]] 192; CHECK-NEXT: [[C_5:%.*]] = icmp ugt i8 [[A]], 0 193; CHECK-NEXT: [[RES_5:%.*]] = xor i1 [[RES_4]], [[C_5]] 194; CHECK-NEXT: [[C_6:%.*]] = icmp uge i8 [[A]], 1 195; CHECK-NEXT: [[RES_6:%.*]] = xor i1 [[RES_5]], [[C_6]] 196; CHECK-NEXT: [[C_7:%.*]] = icmp ugt i8 [[A]], 1 197; CHECK-NEXT: [[RES_7:%.*]] = xor i1 [[RES_6]], [[C_5]] 198; CHECK-NEXT: [[C_8:%.*]] = icmp sgt i8 [[A]], 0 199; CHECK-NEXT: [[RES_8:%.*]] = xor i1 [[RES_7]], [[C_6]] 200; CHECK-NEXT: ret i1 [[RES_8]] 201; CHECK: else: 202; CHECK-NEXT: [[RES_9:%.*]] = xor i1 true, false 203; CHECK-NEXT: [[C_10:%.*]] = icmp ne i8 [[A]], [[B]] 204; CHECK-NEXT: [[RES_10:%.*]] = xor i1 [[RES_9]], [[C_10]] 205; CHECK-NEXT: [[C_11:%.*]] = icmp eq i8 [[A]], [[B]] 206; CHECK-NEXT: [[RES_11:%.*]] = xor i1 [[RES_10]], [[C_11]] 207; CHECK-NEXT: [[RES_12:%.*]] = xor i1 [[RES_11]], false 208; CHECK-NEXT: [[RES_13:%.*]] = xor i1 [[RES_12]], true 209; CHECK-NEXT: [[RES_14:%.*]] = xor i1 [[RES_13]], true 210; CHECK-NEXT: [[RES_15:%.*]] = xor i1 [[RES_14]], false 211; CHECK-NEXT: [[RES_16:%.*]] = xor i1 [[RES_15]], true 212; CHECK-NEXT: ret i1 [[RES_16]] 213; 214entry: 215 %cmp = icmp ne i8 %a, 1 216 br i1 %cmp, label %then, label %else 217 218then: 219 %t.1 = icmp ne i8 %a, 1 220 %c.1 = icmp ne i8 %a, 0 221 %res.1 = xor i1 %t.1, %c.1 222 223 %c.2 = icmp ne i8 %a, %b 224 %res.2 = xor i1 %res.1, %c.2 225 226 %c.3 = icmp eq i8 %a, %b 227 %res.3 = xor i1 %res.2, %c.3 228 229 %c.4 = icmp eq i8 %a, 0 230 %res.4 = xor i1 %res.3, %c.4 231 232 %c.5 = icmp ugt i8 %a, 0 233 %res.5 = xor i1 %res.4, %c.5 234 235 %c.6 = icmp uge i8 %a, 1 236 %res.6 = xor i1 %res.5, %c.6 237 238 %c.7 = icmp ugt i8 %a, 1 239 %res.7 = xor i1 %res.6, %c.5 240 241 %c.8 = icmp sgt i8 %a, 0 242 %res.8 = xor i1 %res.7, %c.6 243 244 ret i1 %res.8 245 246else: 247 %t.2 = icmp ne i8 %a, 0 248 %c.9 = icmp ne i8 %a, 1 249 %res.9 = xor i1 %t.2, %c.9 250 251 %c.10 = icmp ne i8 %a, %b 252 %res.10 = xor i1 %res.9, %c.10 253 254 %c.11 = icmp eq i8 %a, %b 255 %res.11 = xor i1 %res.10, %c.11 256 257 %f.1 = icmp eq i8 %a, 0 258 %res.12 = xor i1 %res.11, %f.1 259 260 %t.3 = icmp ugt i8 %a, 0 261 %res.13 = xor i1 %res.12, %t.3 262 263 %t.4 = icmp uge i8 %a, 1 264 %res.14 = xor i1 %res.13, %t.4 265 266 %f.2 = icmp ugt i8 %a, 1 267 %res.15 = xor i1 %res.14, %f.2 268 269 %c.12 = icmp sgt i8 %a, 0 270 %res.16 = xor i1 %res.15, %c.12 271 272 ret i1 %res.16 273} 274 275define i1 @assume_b_plus_1_ult_a(i64 %a, i64 %b) { 276; CHECK-LABEL: @assume_b_plus_1_ult_a( 277; CHECK-NEXT: [[TMP1:%.*]] = add nuw i64 [[B:%.*]], 1 278; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i64 [[TMP1]], [[A:%.*]] 279; CHECK-NEXT: tail call void @llvm.assume(i1 [[TMP2]]) 280; CHECK-NEXT: ret i1 true 281; 282 %1 = add nuw i64 %b, 1 283 %2 = icmp ult i64 %1, %a 284 tail call void @llvm.assume(i1 %2) 285 %3 = icmp ne i64 %a, %b 286 ret i1 %3 287} 288 289define i1 @assume_a_gt_b_and_b_ge_c(i64 %a, i64 %b, i64 %c) { 290; CHECK-LABEL: @assume_a_gt_b_and_b_ge_c( 291; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i64 [[A:%.*]], [[B:%.*]] 292; CHECK-NEXT: tail call void @llvm.assume(i1 [[TMP1]]) 293; CHECK-NEXT: [[TMP2:%.*]] = icmp uge i64 [[B]], [[C:%.*]] 294; CHECK-NEXT: tail call void @llvm.assume(i1 [[TMP2]]) 295; CHECK-NEXT: ret i1 true 296; 297 %1 = icmp ugt i64 %a, %b 298 tail call void @llvm.assume(i1 %1) 299 %2 = icmp uge i64 %b, %c 300 tail call void @llvm.assume(i1 %2) 301 %3 = icmp ne i64 %a, %c 302 ret i1 %3 303} 304 305define i1 @assume_a_ne_b_and_b_ne_c(i64 %a, i64 %b, i64 %c) { 306; CHECK-LABEL: @assume_a_ne_b_and_b_ne_c( 307; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i64 [[A:%.*]], [[B:%.*]] 308; CHECK-NEXT: tail call void @llvm.assume(i1 [[TMP1]]) 309; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i64 [[B]], [[C:%.*]] 310; CHECK-NEXT: tail call void @llvm.assume(i1 [[TMP2]]) 311; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i64 [[A]], [[C]] 312; CHECK-NEXT: ret i1 [[TMP3]] 313; 314 %1 = icmp ne i64 %a, %b 315 tail call void @llvm.assume(i1 %1) 316 %2 = icmp ne i64 %b, %c 317 tail call void @llvm.assume(i1 %2) 318 %3 = icmp ne i64 %a, %c 319 ret i1 %3 320} 321 322define i1 @assume_1a(i64 %a, i64 %b) { 323; CHECK-LABEL: @assume_1a( 324; CHECK-NEXT: [[NE:%.*]] = icmp ne i64 [[A:%.*]], [[B:%.*]] 325; CHECK-NEXT: tail call void @llvm.assume(i1 [[NE]]) 326; CHECK-NEXT: [[RET:%.*]] = icmp ugt i64 [[A]], [[B]] 327; CHECK-NEXT: ret i1 [[RET]] 328; 329 %ne = icmp ne i64 %a, %b 330 tail call void @llvm.assume(i1 %ne) 331 %ret = icmp ugt i64 %a, %b 332 ret i1 %ret 333} 334 335define i1 @assume_1b(i64 %a, i64 %b) { 336; CHECK-LABEL: @assume_1b( 337; CHECK-NEXT: [[NE:%.*]] = icmp ne i64 [[A:%.*]], [[B:%.*]] 338; CHECK-NEXT: tail call void @llvm.assume(i1 [[NE]]) 339; CHECK-NEXT: [[RET:%.*]] = icmp uge i64 [[A]], [[B]] 340; CHECK-NEXT: ret i1 [[RET]] 341; 342 %ne = icmp ne i64 %a, %b 343 tail call void @llvm.assume(i1 %ne) 344 %ret = icmp uge i64 %a, %b 345 ret i1 %ret 346} 347 348define i1 @assume_2a(i64 %a, i64 %b) { 349; CHECK-LABEL: @assume_2a( 350; CHECK-NEXT: [[NE:%.*]] = icmp ne i64 [[A:%.*]], [[B:%.*]] 351; CHECK-NEXT: tail call void @llvm.assume(i1 [[NE]]) 352; CHECK-NEXT: [[RET:%.*]] = icmp ult i64 [[A]], [[B]] 353; CHECK-NEXT: ret i1 [[RET]] 354; 355 %ne = icmp ne i64 %a, %b 356 tail call void @llvm.assume(i1 %ne) 357 %ret = icmp ult i64 %a, %b 358 ret i1 %ret 359} 360 361define i1 @assume_2b(i64 %a, i64 %b) { 362; CHECK-LABEL: @assume_2b( 363; CHECK-NEXT: [[NE:%.*]] = icmp ne i64 [[A:%.*]], [[B:%.*]] 364; CHECK-NEXT: tail call void @llvm.assume(i1 [[NE]]) 365; CHECK-NEXT: [[RET:%.*]] = icmp ule i64 [[A]], [[B]] 366; CHECK-NEXT: ret i1 [[RET]] 367; 368 %ne = icmp ne i64 %a, %b 369 tail call void @llvm.assume(i1 %ne) 370 %ret = icmp ule i64 %a, %b 371 ret i1 %ret 372} 373 374; TODO: extend to support signed comparisons 375define i1 @assume_3a(i64 %a, i64 %b) { 376; CHECK-LABEL: @assume_3a( 377; CHECK-NEXT: [[NE:%.*]] = icmp ne i64 [[A:%.*]], [[B:%.*]] 378; CHECK-NEXT: tail call void @llvm.assume(i1 [[NE]]) 379; CHECK-NEXT: [[RET:%.*]] = icmp sgt i64 [[A]], [[B]] 380; CHECK-NEXT: ret i1 [[RET]] 381; 382 %ne = icmp ne i64 %a, %b 383 tail call void @llvm.assume(i1 %ne) 384 %ret = icmp sgt i64 %a, %b 385 ret i1 %ret 386} 387 388define i1 @assume_3b(i64 %a, i64 %b) { 389; CHECK-LABEL: @assume_3b( 390; CHECK-NEXT: [[NE:%.*]] = icmp ne i64 [[A:%.*]], [[B:%.*]] 391; CHECK-NEXT: tail call void @llvm.assume(i1 [[NE]]) 392; CHECK-NEXT: [[RET:%.*]] = icmp sge i64 [[A]], [[B]] 393; CHECK-NEXT: ret i1 [[RET]] 394; 395 %ne = icmp ne i64 %a, %b 396 tail call void @llvm.assume(i1 %ne) 397 %ret = icmp sge i64 %a, %b 398 ret i1 %ret 399} 400 401define i1 @assume_4a(i64 %a, i64 %b) { 402; CHECK-LABEL: @assume_4a( 403; CHECK-NEXT: [[NE:%.*]] = icmp ne i64 [[A:%.*]], [[B:%.*]] 404; CHECK-NEXT: tail call void @llvm.assume(i1 [[NE]]) 405; CHECK-NEXT: [[RET:%.*]] = icmp slt i64 [[A]], [[B]] 406; CHECK-NEXT: ret i1 [[RET]] 407; 408 %ne = icmp ne i64 %a, %b 409 tail call void @llvm.assume(i1 %ne) 410 %ret = icmp slt i64 %a, %b 411 ret i1 %ret 412} 413 414define i1 @assume_4b(i64 %a, i64 %b) { 415; CHECK-LABEL: @assume_4b( 416; CHECK-NEXT: [[NE:%.*]] = icmp ne i64 [[A:%.*]], [[B:%.*]] 417; CHECK-NEXT: tail call void @llvm.assume(i1 [[NE]]) 418; CHECK-NEXT: [[RET:%.*]] = icmp sle i64 [[A]], [[B]] 419; CHECK-NEXT: ret i1 [[RET]] 420; 421 %ne = icmp ne i64 %a, %b 422 tail call void @llvm.assume(i1 %ne) 423 %ret = icmp sle i64 %a, %b 424 ret i1 %ret 425} 426