1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2 3; RUN: opt -instcombine -S %s | FileCheck %s 4 5declare { i32, i1 } @llvm.usub.with.overflow.i32(i32, i32) 6 7define i32 @test1(i32 %a, i32 %b) { 8; CHECK-LABEL: @test1( 9; CHECK-NEXT: [[COND:%.*]] = icmp ult i32 [[A:%.*]], [[B:%.*]] 10; CHECK-NEXT: br i1 [[COND]], label [[BB3:%.*]], label [[BB1:%.*]] 11; CHECK: bb1: 12; CHECK-NEXT: br i1 false, label [[BB2:%.*]], label [[BB3]] 13; CHECK: bb2: 14; CHECK-NEXT: ret i32 undef 15; CHECK: bb3: 16; CHECK-NEXT: ret i32 0 17; 18 %cond = icmp uge i32 %a, %b 19 br i1 %cond, label %bb1, label %bb3 20 21bb1: 22 %sub1 = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %a, i32 %b) 23 %r1 = extractvalue { i32, i1 } %sub1, 0 24 %c1 = extractvalue { i32, i1 } %sub1, 1 25 br i1 %c1, label %bb2, label %bb3 26 27bb2: 28 ret i32 %r1 29 30bb3: 31 ret i32 0 32} 33 34define i32 @test2(i32 %a, i32 %b) { 35; CHECK-LABEL: @test2( 36; CHECK-NEXT: [[COND:%.*]] = icmp ult i32 [[A:%.*]], [[B:%.*]] 37; CHECK-NEXT: br i1 [[COND]], label [[BB3:%.*]], label [[BB1:%.*]] 38; CHECK: bb1: 39; CHECK-NEXT: br i1 false, label [[BB3]], label [[BB2:%.*]] 40; CHECK: bb2: 41; CHECK-NEXT: [[SUB1:%.*]] = sub nuw i32 [[A]], [[B]] 42; CHECK-NEXT: ret i32 [[SUB1]] 43; CHECK: bb3: 44; CHECK-NEXT: ret i32 0 45; 46 %cond = icmp uge i32 %a, %b 47 br i1 %cond, label %bb1, label %bb3 48 49bb1: 50 %sub1 = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %a, i32 %b) 51 %r1 = extractvalue { i32, i1 } %sub1, 0 52 %c1 = extractvalue { i32, i1 } %sub1, 1 53 br i1 %c1, label %bb3, label %bb2 54 55bb2: 56 ret i32 %r1 57 58bb3: 59 ret i32 0 60} 61 62 63define i32 @test3(i32 %a, i32 %b) { 64; CHECK-LABEL: @test3( 65; CHECK-NEXT: [[COND:%.*]] = icmp ugt i32 [[A:%.*]], [[B:%.*]] 66; CHECK-NEXT: br i1 [[COND]], label [[BB1:%.*]], label [[BB3:%.*]] 67; CHECK: bb1: 68; CHECK-NEXT: br i1 false, label [[BB2:%.*]], label [[BB3]] 69; CHECK: bb2: 70; CHECK-NEXT: ret i32 undef 71; CHECK: bb3: 72; CHECK-NEXT: ret i32 0 73; 74 %cond = icmp ugt i32 %a, %b 75 br i1 %cond, label %bb1, label %bb3 76 77bb1: 78 %sub1 = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %a, i32 %b) 79 %r1 = extractvalue { i32, i1 } %sub1, 0 80 %c1 = extractvalue { i32, i1 } %sub1, 1 81 br i1 %c1, label %bb2, label %bb3 82 83bb2: 84 ret i32 %r1 85 86bb3: 87 ret i32 0 88} 89 90define i32 @test4(i32 %a, i32 %b) { 91; CHECK-LABEL: @test4( 92; CHECK-NEXT: [[COND:%.*]] = icmp ugt i32 [[A:%.*]], [[B:%.*]] 93; CHECK-NEXT: br i1 [[COND]], label [[BB1:%.*]], label [[BB3:%.*]] 94; CHECK: bb1: 95; CHECK-NEXT: br i1 false, label [[BB3]], label [[BB2:%.*]] 96; CHECK: bb2: 97; CHECK-NEXT: [[SUB1:%.*]] = sub nuw i32 [[A]], [[B]] 98; CHECK-NEXT: ret i32 [[SUB1]] 99; CHECK: bb3: 100; CHECK-NEXT: ret i32 0 101; 102 %cond = icmp ugt i32 %a, %b 103 br i1 %cond, label %bb1, label %bb3 104 105bb1: 106 %sub1 = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %a, i32 %b) 107 %r1 = extractvalue { i32, i1 } %sub1, 0 108 %c1 = extractvalue { i32, i1 } %sub1, 1 109 br i1 %c1, label %bb3, label %bb2 110 111bb2: 112 ret i32 %r1 113 114bb3: 115 ret i32 0 116} 117 118 119define i32 @test5(i32 %a, i32 %b) { 120; CHECK-LABEL: @test5( 121; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]] 122; CHECK-NEXT: br i1 [[COND]], label [[BB1:%.*]], label [[BB3:%.*]] 123; CHECK: bb1: 124; CHECK-NEXT: br i1 false, label [[BB3]], label [[BB2:%.*]] 125; CHECK: bb2: 126; CHECK-NEXT: [[SUB1:%.*]] = sub nuw i32 [[A]], [[B]] 127; CHECK-NEXT: ret i32 [[SUB1]] 128; CHECK: bb3: 129; CHECK-NEXT: ret i32 0 130; 131 %cond = icmp eq i32 %a, %b 132 br i1 %cond, label %bb1, label %bb3 133 134bb1: 135 %sub1 = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %a, i32 %b) 136 %r1 = extractvalue { i32, i1 } %sub1, 0 137 %c1 = extractvalue { i32, i1 } %sub1, 1 138 br i1 %c1, label %bb3, label %bb2 139 140bb2: 141 ret i32 %r1 142 143bb3: 144 ret i32 0 145} 146 147define i32 @test6(i32 %a, i32 %b) { 148; CHECK-LABEL: @test6( 149; CHECK-NEXT: [[COND:%.*]] = icmp ult i32 [[A:%.*]], [[B:%.*]] 150; CHECK-NEXT: br i1 [[COND]], label [[BB1:%.*]], label [[BB3:%.*]] 151; CHECK: bb1: 152; CHECK-NEXT: br i1 true, label [[BB3]], label [[BB2:%.*]] 153; CHECK: bb2: 154; CHECK-NEXT: ret i32 undef 155; CHECK: bb3: 156; CHECK-NEXT: ret i32 0 157; 158 %cond = icmp ult i32 %a, %b 159 br i1 %cond, label %bb1, label %bb3 160 161bb1: 162 %sub1 = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %a, i32 %b) 163 %r1 = extractvalue { i32, i1 } %sub1, 0 164 %c1 = extractvalue { i32, i1 } %sub1, 1 165 br i1 %c1, label %bb3, label %bb2 166 167bb2: 168 ret i32 %r1 169 170bb3: 171 ret i32 0 172} 173 174define i32 @test7(i32 %a, i32 %b) { 175; CHECK-LABEL: @test7( 176; CHECK-NEXT: [[COND:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]] 177; CHECK-NEXT: br i1 [[COND]], label [[BB1:%.*]], label [[BB3:%.*]] 178; CHECK: bb1: 179; CHECK-NEXT: [[SUB1:%.*]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 [[A]], i32 [[B]]) 180; CHECK-NEXT: [[C1:%.*]] = extractvalue { i32, i1 } [[SUB1]], 1 181; CHECK-NEXT: br i1 [[C1]], label [[BB3]], label [[BB2:%.*]] 182; CHECK: bb2: 183; CHECK-NEXT: [[R1:%.*]] = extractvalue { i32, i1 } [[SUB1]], 0 184; CHECK-NEXT: ret i32 [[R1]] 185; CHECK: bb3: 186; CHECK-NEXT: ret i32 0 187; 188 %cond = icmp slt i32 %a, %b 189 br i1 %cond, label %bb1, label %bb3 190 191bb1: 192 %sub1 = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %a, i32 %b) 193 %r1 = extractvalue { i32, i1 } %sub1, 0 194 %c1 = extractvalue { i32, i1 } %sub1, 1 195 br i1 %c1, label %bb3, label %bb2 196 197bb2: 198 ret i32 %r1 199 200bb3: 201 ret i32 0 202} 203 204define i32 @test8(i32 %a, i32 %b) { 205; CHECK-LABEL: @test8( 206; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]] 207; CHECK-NEXT: br i1 [[COND]], label [[BB3:%.*]], label [[BB1:%.*]] 208; CHECK: bb1: 209; CHECK-NEXT: [[SUB1:%.*]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 [[A]], i32 [[B]]) 210; CHECK-NEXT: [[C1:%.*]] = extractvalue { i32, i1 } [[SUB1]], 1 211; CHECK-NEXT: br i1 [[C1]], label [[BB3]], label [[BB2:%.*]] 212; CHECK: bb2: 213; CHECK-NEXT: [[R1:%.*]] = extractvalue { i32, i1 } [[SUB1]], 0 214; CHECK-NEXT: ret i32 [[R1]] 215; CHECK: bb3: 216; CHECK-NEXT: ret i32 0 217; 218 %cond = icmp ne i32 %a, %b 219 br i1 %cond, label %bb1, label %bb3 220 221bb1: 222 %sub1 = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %a, i32 %b) 223 %r1 = extractvalue { i32, i1 } %sub1, 0 224 %c1 = extractvalue { i32, i1 } %sub1, 1 225 br i1 %c1, label %bb3, label %bb2 226 227bb2: 228 ret i32 %r1 229 230bb3: 231 ret i32 0 232} 233 234define i32 @test9(i32 %a, i32 %b, i1 %cond2) { 235; CHECK-LABEL: @test9( 236; CHECK-NEXT: [[COND:%.*]] = icmp ugt i32 [[A:%.*]], [[B:%.*]] 237; CHECK-NEXT: [[AND:%.*]] = and i1 [[COND]], [[COND2:%.*]] 238; CHECK-NEXT: br i1 [[AND]], label [[BB1:%.*]], label [[BB3:%.*]] 239; CHECK: bb1: 240; CHECK-NEXT: br i1 false, label [[BB3]], label [[BB2:%.*]] 241; CHECK: bb2: 242; CHECK-NEXT: [[SUB1:%.*]] = sub nuw i32 [[A]], [[B]] 243; CHECK-NEXT: ret i32 [[SUB1]] 244; CHECK: bb3: 245; CHECK-NEXT: ret i32 0 246; 247 %cond = icmp ugt i32 %a, %b 248 %and = and i1 %cond, %cond2 249 br i1 %and, label %bb1, label %bb3 250 251bb1: 252 %sub1 = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %a, i32 %b) 253 %r1 = extractvalue { i32, i1 } %sub1, 0 254 %c1 = extractvalue { i32, i1 } %sub1, 1 255 br i1 %c1, label %bb3, label %bb2 256 257bb2: 258 ret i32 %r1 259 260bb3: 261 ret i32 0 262} 263 264define i32 @test10(i32 %a, i32 %b, i1 %cond2) { 265; CHECK-LABEL: @test10( 266; CHECK-NEXT: [[COND:%.*]] = icmp ugt i32 [[A:%.*]], [[B:%.*]] 267; CHECK-NEXT: [[AND:%.*]] = and i1 [[COND]], [[COND2:%.*]] 268; CHECK-NEXT: br i1 [[AND]], label [[BB3:%.*]], label [[BB1:%.*]] 269; CHECK: bb1: 270; CHECK-NEXT: [[SUB1:%.*]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 [[A]], i32 [[B]]) 271; CHECK-NEXT: [[C1:%.*]] = extractvalue { i32, i1 } [[SUB1]], 1 272; CHECK-NEXT: br i1 [[C1]], label [[BB3]], label [[BB2:%.*]] 273; CHECK: bb2: 274; CHECK-NEXT: [[R1:%.*]] = extractvalue { i32, i1 } [[SUB1]], 0 275; CHECK-NEXT: ret i32 [[R1]] 276; CHECK: bb3: 277; CHECK-NEXT: ret i32 0 278; 279 %cond = icmp ugt i32 %a, %b 280 %and = and i1 %cond, %cond2 281 br i1 %and, label %bb3, label %bb1 282 283bb1: 284 %sub1 = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %a, i32 %b) 285 %r1 = extractvalue { i32, i1 } %sub1, 0 286 %c1 = extractvalue { i32, i1 } %sub1, 1 287 br i1 %c1, label %bb3, label %bb2 288 289bb2: 290 ret i32 %r1 291 292bb3: 293 ret i32 0 294} 295 296define i32 @test11(i32 %a, i32 %b, i1 %cond2) { 297; CHECK-LABEL: @test11( 298; CHECK-NEXT: [[COND:%.*]] = icmp ugt i32 [[A:%.*]], [[B:%.*]] 299; CHECK-NEXT: [[OR:%.*]] = or i1 [[COND]], [[COND2:%.*]] 300; CHECK-NEXT: br i1 [[OR]], label [[BB1:%.*]], label [[BB3:%.*]] 301; CHECK: bb1: 302; CHECK-NEXT: [[SUB1:%.*]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 [[A]], i32 [[B]]) 303; CHECK-NEXT: [[C1:%.*]] = extractvalue { i32, i1 } [[SUB1]], 1 304; CHECK-NEXT: br i1 [[C1]], label [[BB3]], label [[BB2:%.*]] 305; CHECK: bb2: 306; CHECK-NEXT: [[R1:%.*]] = extractvalue { i32, i1 } [[SUB1]], 0 307; CHECK-NEXT: ret i32 [[R1]] 308; CHECK: bb3: 309; CHECK-NEXT: ret i32 0 310; 311 %cond = icmp ugt i32 %a, %b 312 %or = or i1 %cond, %cond2 313 br i1 %or, label %bb1, label %bb3 314 315bb1: 316 %sub1 = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %a, i32 %b) 317 %r1 = extractvalue { i32, i1 } %sub1, 0 318 %c1 = extractvalue { i32, i1 } %sub1, 1 319 br i1 %c1, label %bb3, label %bb2 320 321bb2: 322 ret i32 %r1 323 324bb3: 325 ret i32 0 326} 327 328define i32 @test12(i32 %a, i32 %b, i1 %cond2) { 329; CHECK-LABEL: @test12( 330; CHECK-NEXT: [[COND:%.*]] = icmp ugt i32 [[A:%.*]], [[B:%.*]] 331; CHECK-NEXT: [[OR:%.*]] = or i1 [[COND]], [[COND2:%.*]] 332; CHECK-NEXT: br i1 [[OR]], label [[BB3:%.*]], label [[BB1:%.*]] 333; CHECK: bb1: 334; CHECK-NEXT: [[SUB1:%.*]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 [[A]], i32 [[B]]) 335; CHECK-NEXT: [[C1:%.*]] = extractvalue { i32, i1 } [[SUB1]], 1 336; CHECK-NEXT: br i1 [[C1]], label [[BB3]], label [[BB2:%.*]] 337; CHECK: bb2: 338; CHECK-NEXT: [[R1:%.*]] = extractvalue { i32, i1 } [[SUB1]], 0 339; CHECK-NEXT: ret i32 [[R1]] 340; CHECK: bb3: 341; CHECK-NEXT: ret i32 0 342; 343 %cond = icmp ugt i32 %a, %b 344 %or = or i1 %cond, %cond2 345 br i1 %or, label %bb3, label %bb1 346 347bb1: 348 %sub1 = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %a, i32 %b) 349 %r1 = extractvalue { i32, i1 } %sub1, 0 350 %c1 = extractvalue { i32, i1 } %sub1, 1 351 br i1 %c1, label %bb3, label %bb2 352 353bb2: 354 ret i32 %r1 355 356bb3: 357 ret i32 0 358} 359