1; RUN: llc -mtriple=x86_64-darwin-unknown < %s | FileCheck %s --check-prefix=DAG 2; RUN: llc -mtriple=x86_64-darwin-unknown -fast-isel -fast-isel-abort < %s | FileCheck %s --check-prefix=FAST 3; RUN: llc -mtriple=x86_64-darwin-unknown < %s | FileCheck %s 4; RUN: llc -mtriple=x86_64-darwin-unknown -fast-isel -fast-isel-abort < %s | FileCheck %s 5 6; 7; Get the actual value of the overflow bit. 8; 9; SADDO reg, reg 10define zeroext i1 @saddo.i8(i8 signext %v1, i8 signext %v2, i8* %res) { 11entry: 12; DAG-LABEL: saddo.i8 13; DAG: addb %sil, %dil 14; DAG-NEXT: seto %al 15; FAST-LABEL: saddo.i8 16; FAST: addb %sil, %dil 17; FAST-NEXT: seto %al 18 %t = call {i8, i1} @llvm.sadd.with.overflow.i8(i8 %v1, i8 %v2) 19 %val = extractvalue {i8, i1} %t, 0 20 %obit = extractvalue {i8, i1} %t, 1 21 store i8 %val, i8* %res 22 ret i1 %obit 23} 24 25define zeroext i1 @saddo.i16(i16 %v1, i16 %v2, i16* %res) { 26entry: 27; DAG-LABEL: saddo.i16 28; DAG: addw %si, %di 29; DAG-NEXT: seto %al 30; FAST-LABEL: saddo.i16 31; FAST: addw %si, %di 32; FAST-NEXT: seto %al 33 %t = call {i16, i1} @llvm.sadd.with.overflow.i16(i16 %v1, i16 %v2) 34 %val = extractvalue {i16, i1} %t, 0 35 %obit = extractvalue {i16, i1} %t, 1 36 store i16 %val, i16* %res 37 ret i1 %obit 38} 39 40define zeroext i1 @saddo.i32(i32 %v1, i32 %v2, i32* %res) { 41entry: 42; DAG-LABEL: saddo.i32 43; DAG: addl %esi, %edi 44; DAG-NEXT: seto %al 45; FAST-LABEL: saddo.i32 46; FAST: addl %esi, %edi 47; FAST-NEXT: seto %al 48 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2) 49 %val = extractvalue {i32, i1} %t, 0 50 %obit = extractvalue {i32, i1} %t, 1 51 store i32 %val, i32* %res 52 ret i1 %obit 53} 54 55define zeroext i1 @saddo.i64(i64 %v1, i64 %v2, i64* %res) { 56entry: 57; DAG-LABEL: saddo.i64 58; DAG: addq %rsi, %rdi 59; DAG-NEXT: seto %al 60; FAST-LABEL: saddo.i64 61; FAST: addq %rsi, %rdi 62; FAST-NEXT: seto %al 63 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2) 64 %val = extractvalue {i64, i1} %t, 0 65 %obit = extractvalue {i64, i1} %t, 1 66 store i64 %val, i64* %res 67 ret i1 %obit 68} 69 70; SADDO reg, imm | imm, reg 71; FIXME: INC isn't supported in FastISel yet 72define zeroext i1 @saddo.i64imm1(i64 %v1, i64* %res) { 73entry: 74; DAG-LABEL: saddo.i64imm1 75; DAG: incq %rdi 76; DAG-NEXT: seto %al 77; FAST-LABEL: saddo.i64imm1 78; FAST: addq $1, %rdi 79; FAST-NEXT: seto %al 80 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 1) 81 %val = extractvalue {i64, i1} %t, 0 82 %obit = extractvalue {i64, i1} %t, 1 83 store i64 %val, i64* %res 84 ret i1 %obit 85} 86 87; FIXME: DAG doesn't optimize immediates on the LHS. 88define zeroext i1 @saddo.i64imm2(i64 %v1, i64* %res) { 89entry: 90; DAG-LABEL: saddo.i64imm2 91; DAG: mov 92; DAG-NEXT: addq 93; DAG-NEXT: seto 94; FAST-LABEL: saddo.i64imm2 95; FAST: addq $1, %rdi 96; FAST-NEXT: seto %al 97 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 1, i64 %v1) 98 %val = extractvalue {i64, i1} %t, 0 99 %obit = extractvalue {i64, i1} %t, 1 100 store i64 %val, i64* %res 101 ret i1 %obit 102} 103 104; Check boundary conditions for large immediates. 105define zeroext i1 @saddo.i64imm3(i64 %v1, i64* %res) { 106entry: 107; DAG-LABEL: saddo.i64imm3 108; DAG: addq $-2147483648, %rdi 109; DAG-NEXT: seto %al 110; FAST-LABEL: saddo.i64imm3 111; FAST: addq $-2147483648, %rdi 112; FAST-NEXT: seto %al 113 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 -2147483648) 114 %val = extractvalue {i64, i1} %t, 0 115 %obit = extractvalue {i64, i1} %t, 1 116 store i64 %val, i64* %res 117 ret i1 %obit 118} 119 120define zeroext i1 @saddo.i64imm4(i64 %v1, i64* %res) { 121entry: 122; DAG-LABEL: saddo.i64imm4 123; DAG: movabsq $-21474836489, %[[REG:[a-z]+]] 124; DAG-NEXT: addq %rdi, %[[REG]] 125; DAG-NEXT: seto 126; FAST-LABEL: saddo.i64imm4 127; FAST: movabsq $-21474836489, %[[REG:[a-z]+]] 128; FAST-NEXT: addq %rdi, %[[REG]] 129; FAST-NEXT: seto 130 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 -21474836489) 131 %val = extractvalue {i64, i1} %t, 0 132 %obit = extractvalue {i64, i1} %t, 1 133 store i64 %val, i64* %res 134 ret i1 %obit 135} 136 137define zeroext i1 @saddo.i64imm5(i64 %v1, i64* %res) { 138entry: 139; DAG-LABEL: saddo.i64imm5 140; DAG: addq $2147483647, %rdi 141; DAG-NEXT: seto 142; FAST-LABEL: saddo.i64imm5 143; FAST: addq $2147483647, %rdi 144; FAST-NEXT: seto 145 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 2147483647) 146 %val = extractvalue {i64, i1} %t, 0 147 %obit = extractvalue {i64, i1} %t, 1 148 store i64 %val, i64* %res 149 ret i1 %obit 150} 151 152; TODO: FastISel shouldn't use movabsq. 153define zeroext i1 @saddo.i64imm6(i64 %v1, i64* %res) { 154entry: 155; DAG-LABEL: saddo.i64imm6 156; DAG: movl $2147483648, %ecx 157; DAG: addq %rdi, %rcx 158; DAG-NEXT: seto 159; FAST-LABEL: saddo.i64imm6 160; FAST: movabsq $2147483648, %[[REG:[a-z]+]] 161; FAST: addq %rdi, %[[REG]] 162; FAST-NEXT: seto 163 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 2147483648) 164 %val = extractvalue {i64, i1} %t, 0 165 %obit = extractvalue {i64, i1} %t, 1 166 store i64 %val, i64* %res 167 ret i1 %obit 168} 169 170; UADDO 171define zeroext i1 @uaddo.i32(i32 %v1, i32 %v2, i32* %res) { 172entry: 173; DAG-LABEL: uaddo.i32 174; DAG: addl %esi, %edi 175; DAG-NEXT: setb %al 176; FAST-LABEL: uaddo.i32 177; FAST: addl %esi, %edi 178; FAST-NEXT: setb %al 179 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2) 180 %val = extractvalue {i32, i1} %t, 0 181 %obit = extractvalue {i32, i1} %t, 1 182 store i32 %val, i32* %res 183 ret i1 %obit 184} 185 186define zeroext i1 @uaddo.i64(i64 %v1, i64 %v2, i64* %res) { 187entry: 188; DAG-LABEL: uaddo.i64 189; DAG: addq %rsi, %rdi 190; DAG-NEXT: setb %al 191; FAST-LABEL: uaddo.i64 192; FAST: addq %rsi, %rdi 193; FAST-NEXT: setb %al 194 %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2) 195 %val = extractvalue {i64, i1} %t, 0 196 %obit = extractvalue {i64, i1} %t, 1 197 store i64 %val, i64* %res 198 ret i1 %obit 199} 200 201; SSUBO 202define zeroext i1 @ssubo.i32(i32 %v1, i32 %v2, i32* %res) { 203entry: 204; DAG-LABEL: ssubo.i32 205; DAG: subl %esi, %edi 206; DAG-NEXT: seto %al 207; FAST-LABEL: ssubo.i32 208; FAST: subl %esi, %edi 209; FAST-NEXT: seto %al 210 %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2) 211 %val = extractvalue {i32, i1} %t, 0 212 %obit = extractvalue {i32, i1} %t, 1 213 store i32 %val, i32* %res 214 ret i1 %obit 215} 216 217define zeroext i1 @ssubo.i64(i64 %v1, i64 %v2, i64* %res) { 218entry: 219; DAG-LABEL: ssubo.i64 220; DAG: subq %rsi, %rdi 221; DAG-NEXT: seto %al 222; FAST-LABEL: ssubo.i64 223; FAST: subq %rsi, %rdi 224; FAST-NEXT: seto %al 225 %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2) 226 %val = extractvalue {i64, i1} %t, 0 227 %obit = extractvalue {i64, i1} %t, 1 228 store i64 %val, i64* %res 229 ret i1 %obit 230} 231 232; USUBO 233define zeroext i1 @usubo.i32(i32 %v1, i32 %v2, i32* %res) { 234entry: 235; DAG-LABEL: usubo.i32 236; DAG: subl %esi, %edi 237; DAG-NEXT: setb %al 238; FAST-LABEL: usubo.i32 239; FAST: subl %esi, %edi 240; FAST-NEXT: setb %al 241 %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2) 242 %val = extractvalue {i32, i1} %t, 0 243 %obit = extractvalue {i32, i1} %t, 1 244 store i32 %val, i32* %res 245 ret i1 %obit 246} 247 248define zeroext i1 @usubo.i64(i64 %v1, i64 %v2, i64* %res) { 249entry: 250; DAG-LABEL: usubo.i64 251; DAG: subq %rsi, %rdi 252; DAG-NEXT: setb %al 253; FAST-LABEL: usubo.i64 254; FAST: subq %rsi, %rdi 255; FAST-NEXT: setb %al 256 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2) 257 %val = extractvalue {i64, i1} %t, 0 258 %obit = extractvalue {i64, i1} %t, 1 259 store i64 %val, i64* %res 260 ret i1 %obit 261} 262 263; SMULO 264define zeroext i1 @smulo.i8(i8 %v1, i8 %v2, i8* %res) { 265entry: 266; FAST-LABEL: smulo.i8 267; FAST: movb %dil, %al 268; FAST-NEXT: imulb %sil 269; FAST-NEXT: seto %cl 270 %t = call {i8, i1} @llvm.smul.with.overflow.i8(i8 %v1, i8 %v2) 271 %val = extractvalue {i8, i1} %t, 0 272 %obit = extractvalue {i8, i1} %t, 1 273 store i8 %val, i8* %res 274 ret i1 %obit 275} 276 277define zeroext i1 @smulo.i16(i16 %v1, i16 %v2, i16* %res) { 278entry: 279; DAG-LABEL: smulo.i16 280; DAG: imulw %si, %di 281; DAG-NEXT: seto %al 282; FAST-LABEL: smulo.i16 283; FAST: imulw %si, %di 284; FAST-NEXT: seto %al 285 %t = call {i16, i1} @llvm.smul.with.overflow.i16(i16 %v1, i16 %v2) 286 %val = extractvalue {i16, i1} %t, 0 287 %obit = extractvalue {i16, i1} %t, 1 288 store i16 %val, i16* %res 289 ret i1 %obit 290} 291 292define zeroext i1 @smulo.i32(i32 %v1, i32 %v2, i32* %res) { 293entry: 294; DAG-LABEL: smulo.i32 295; DAG: imull %esi, %edi 296; DAG-NEXT: seto %al 297; FAST-LABEL: smulo.i32 298; FAST: imull %esi, %edi 299; FAST-NEXT: seto %al 300 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2) 301 %val = extractvalue {i32, i1} %t, 0 302 %obit = extractvalue {i32, i1} %t, 1 303 store i32 %val, i32* %res 304 ret i1 %obit 305} 306 307define zeroext i1 @smulo.i64(i64 %v1, i64 %v2, i64* %res) { 308entry: 309; DAG-LABEL: smulo.i64 310; DAG: imulq %rsi, %rdi 311; DAG-NEXT: seto %al 312; FAST-LABEL: smulo.i64 313; FAST: imulq %rsi, %rdi 314; FAST-NEXT: seto %al 315 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2) 316 %val = extractvalue {i64, i1} %t, 0 317 %obit = extractvalue {i64, i1} %t, 1 318 store i64 %val, i64* %res 319 ret i1 %obit 320} 321 322; UMULO 323define zeroext i1 @umulo.i8(i8 %v1, i8 %v2, i8* %res) { 324entry: 325; FAST-LABEL: umulo.i8 326; FAST: movb %dil, %al 327; FAST-NEXT: mulb %sil 328; FAST-NEXT: seto %cl 329 %t = call {i8, i1} @llvm.umul.with.overflow.i8(i8 %v1, i8 %v2) 330 %val = extractvalue {i8, i1} %t, 0 331 %obit = extractvalue {i8, i1} %t, 1 332 store i8 %val, i8* %res 333 ret i1 %obit 334} 335 336define zeroext i1 @umulo.i16(i16 %v1, i16 %v2, i16* %res) { 337entry: 338; DAG-LABEL: umulo.i16 339; DAG: mulw %si 340; DAG-NEXT: seto 341; FAST-LABEL: umulo.i16 342; FAST: mulw %si 343; FAST-NEXT: seto 344 %t = call {i16, i1} @llvm.umul.with.overflow.i16(i16 %v1, i16 %v2) 345 %val = extractvalue {i16, i1} %t, 0 346 %obit = extractvalue {i16, i1} %t, 1 347 store i16 %val, i16* %res 348 ret i1 %obit 349} 350 351define zeroext i1 @umulo.i32(i32 %v1, i32 %v2, i32* %res) { 352entry: 353; DAG-LABEL: umulo.i32 354; DAG: mull %esi 355; DAG-NEXT: seto 356; FAST-LABEL: umulo.i32 357; FAST: mull %esi 358; FAST-NEXT: seto 359 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2) 360 %val = extractvalue {i32, i1} %t, 0 361 %obit = extractvalue {i32, i1} %t, 1 362 store i32 %val, i32* %res 363 ret i1 %obit 364} 365 366define zeroext i1 @umulo.i64(i64 %v1, i64 %v2, i64* %res) { 367entry: 368; DAG-LABEL: umulo.i64 369; DAG: mulq %rsi 370; DAG-NEXT: seto 371; FAST-LABEL: umulo.i64 372; FAST: mulq %rsi 373; FAST-NEXT: seto 374 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2) 375 %val = extractvalue {i64, i1} %t, 0 376 %obit = extractvalue {i64, i1} %t, 1 377 store i64 %val, i64* %res 378 ret i1 %obit 379} 380 381; 382; Check the use of the overflow bit in combination with a select instruction. 383; 384define i32 @saddo.select.i32(i32 %v1, i32 %v2) { 385entry: 386; CHECK-LABEL: saddo.select.i32 387; CHECK: addl %esi, %eax 388; CHECK-NEXT: cmovol %edi, %esi 389 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2) 390 %obit = extractvalue {i32, i1} %t, 1 391 %ret = select i1 %obit, i32 %v1, i32 %v2 392 ret i32 %ret 393} 394 395define i64 @saddo.select.i64(i64 %v1, i64 %v2) { 396entry: 397; CHECK-LABEL: saddo.select.i64 398; CHECK: addq %rsi, %rax 399; CHECK-NEXT: cmovoq %rdi, %rsi 400 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2) 401 %obit = extractvalue {i64, i1} %t, 1 402 %ret = select i1 %obit, i64 %v1, i64 %v2 403 ret i64 %ret 404} 405 406define i32 @uaddo.select.i32(i32 %v1, i32 %v2) { 407entry: 408; CHECK-LABEL: uaddo.select.i32 409; CHECK: addl %esi, %eax 410; CHECK-NEXT: cmovbl %edi, %esi 411 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2) 412 %obit = extractvalue {i32, i1} %t, 1 413 %ret = select i1 %obit, i32 %v1, i32 %v2 414 ret i32 %ret 415} 416 417define i64 @uaddo.select.i64(i64 %v1, i64 %v2) { 418entry: 419; CHECK-LABEL: uaddo.select.i64 420; CHECK: addq %rsi, %rax 421; CHECK-NEXT: cmovbq %rdi, %rsi 422 %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2) 423 %obit = extractvalue {i64, i1} %t, 1 424 %ret = select i1 %obit, i64 %v1, i64 %v2 425 ret i64 %ret 426} 427 428define i32 @ssubo.select.i32(i32 %v1, i32 %v2) { 429entry: 430; CHECK-LABEL: ssubo.select.i32 431; CHECK: cmpl %esi, %edi 432; CHECK-NEXT: cmovol %edi, %esi 433 %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2) 434 %obit = extractvalue {i32, i1} %t, 1 435 %ret = select i1 %obit, i32 %v1, i32 %v2 436 ret i32 %ret 437} 438 439define i64 @ssubo.select.i64(i64 %v1, i64 %v2) { 440entry: 441; CHECK-LABEL: ssubo.select.i64 442; CHECK: cmpq %rsi, %rdi 443; CHECK-NEXT: cmovoq %rdi, %rsi 444 %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2) 445 %obit = extractvalue {i64, i1} %t, 1 446 %ret = select i1 %obit, i64 %v1, i64 %v2 447 ret i64 %ret 448} 449 450define i32 @usubo.select.i32(i32 %v1, i32 %v2) { 451entry: 452; CHECK-LABEL: usubo.select.i32 453; CHECK: cmpl %esi, %edi 454; CHECK-NEXT: cmovbl %edi, %esi 455 %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2) 456 %obit = extractvalue {i32, i1} %t, 1 457 %ret = select i1 %obit, i32 %v1, i32 %v2 458 ret i32 %ret 459} 460 461define i64 @usubo.select.i64(i64 %v1, i64 %v2) { 462entry: 463; CHECK-LABEL: usubo.select.i64 464; CHECK: cmpq %rsi, %rdi 465; CHECK-NEXT: cmovbq %rdi, %rsi 466 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2) 467 %obit = extractvalue {i64, i1} %t, 1 468 %ret = select i1 %obit, i64 %v1, i64 %v2 469 ret i64 %ret 470} 471 472define i32 @smulo.select.i32(i32 %v1, i32 %v2) { 473entry: 474; CHECK-LABEL: smulo.select.i32 475; CHECK: imull %esi, %eax 476; CHECK-NEXT: cmovol %edi, %esi 477 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2) 478 %obit = extractvalue {i32, i1} %t, 1 479 %ret = select i1 %obit, i32 %v1, i32 %v2 480 ret i32 %ret 481} 482 483define i64 @smulo.select.i64(i64 %v1, i64 %v2) { 484entry: 485; CHECK-LABEL: smulo.select.i64 486; CHECK: imulq %rsi, %rax 487; CHECK-NEXT: cmovoq %rdi, %rsi 488 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2) 489 %obit = extractvalue {i64, i1} %t, 1 490 %ret = select i1 %obit, i64 %v1, i64 %v2 491 ret i64 %ret 492} 493 494define i32 @umulo.select.i32(i32 %v1, i32 %v2) { 495entry: 496; CHECK-LABEL: umulo.select.i32 497; CHECK: mull %esi 498; CHECK-NEXT: cmovol %edi, %esi 499 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2) 500 %obit = extractvalue {i32, i1} %t, 1 501 %ret = select i1 %obit, i32 %v1, i32 %v2 502 ret i32 %ret 503} 504 505define i64 @umulo.select.i64(i64 %v1, i64 %v2) { 506entry: 507; CHECK-LABEL: umulo.select.i64 508; CHECK: mulq %rsi 509; CHECK-NEXT: cmovoq %rdi, %rsi 510 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2) 511 %obit = extractvalue {i64, i1} %t, 1 512 %ret = select i1 %obit, i64 %v1, i64 %v2 513 ret i64 %ret 514} 515 516 517; 518; Check the use of the overflow bit in combination with a branch instruction. 519; 520define zeroext i1 @saddo.br.i32(i32 %v1, i32 %v2) { 521entry: 522; CHECK-LABEL: saddo.br.i32 523; CHECK: addl %esi, %edi 524; CHECK-NEXT: jo 525 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2) 526 %val = extractvalue {i32, i1} %t, 0 527 %obit = extractvalue {i32, i1} %t, 1 528 br i1 %obit, label %overflow, label %continue, !prof !0 529 530overflow: 531 ret i1 false 532 533continue: 534 ret i1 true 535} 536 537define zeroext i1 @saddo.br.i64(i64 %v1, i64 %v2) { 538entry: 539; CHECK-LABEL: saddo.br.i64 540; CHECK: addq %rsi, %rdi 541; CHECK-NEXT: jo 542 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2) 543 %val = extractvalue {i64, i1} %t, 0 544 %obit = extractvalue {i64, i1} %t, 1 545 br i1 %obit, label %overflow, label %continue, !prof !0 546 547overflow: 548 ret i1 false 549 550continue: 551 ret i1 true 552} 553 554define zeroext i1 @uaddo.br.i32(i32 %v1, i32 %v2) { 555entry: 556; CHECK-LABEL: uaddo.br.i32 557; CHECK: addl %esi, %edi 558; CHECK-NEXT: jb 559 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2) 560 %val = extractvalue {i32, i1} %t, 0 561 %obit = extractvalue {i32, i1} %t, 1 562 br i1 %obit, label %overflow, label %continue, !prof !0 563 564overflow: 565 ret i1 false 566 567continue: 568 ret i1 true 569} 570 571define zeroext i1 @uaddo.br.i64(i64 %v1, i64 %v2) { 572entry: 573; CHECK-LABEL: uaddo.br.i64 574; CHECK: addq %rsi, %rdi 575; CHECK-NEXT: jb 576 %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2) 577 %val = extractvalue {i64, i1} %t, 0 578 %obit = extractvalue {i64, i1} %t, 1 579 br i1 %obit, label %overflow, label %continue, !prof !0 580 581overflow: 582 ret i1 false 583 584continue: 585 ret i1 true 586} 587 588define zeroext i1 @ssubo.br.i32(i32 %v1, i32 %v2) { 589entry: 590; CHECK-LABEL: ssubo.br.i32 591; CHECK: cmpl %esi, %edi 592; CHECK-NEXT: jo 593 %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2) 594 %val = extractvalue {i32, i1} %t, 0 595 %obit = extractvalue {i32, i1} %t, 1 596 br i1 %obit, label %overflow, label %continue, !prof !0 597 598overflow: 599 ret i1 false 600 601continue: 602 ret i1 true 603} 604 605define zeroext i1 @ssubo.br.i64(i64 %v1, i64 %v2) { 606entry: 607; CHECK-LABEL: ssubo.br.i64 608; CHECK: cmpq %rsi, %rdi 609; CHECK-NEXT: jo 610 %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2) 611 %val = extractvalue {i64, i1} %t, 0 612 %obit = extractvalue {i64, i1} %t, 1 613 br i1 %obit, label %overflow, label %continue, !prof !0 614 615overflow: 616 ret i1 false 617 618continue: 619 ret i1 true 620} 621 622define zeroext i1 @usubo.br.i32(i32 %v1, i32 %v2) { 623entry: 624; CHECK-LABEL: usubo.br.i32 625; CHECK: cmpl %esi, %edi 626; CHECK-NEXT: jb 627 %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2) 628 %val = extractvalue {i32, i1} %t, 0 629 %obit = extractvalue {i32, i1} %t, 1 630 br i1 %obit, label %overflow, label %continue, !prof !0 631 632overflow: 633 ret i1 false 634 635continue: 636 ret i1 true 637} 638 639define zeroext i1 @usubo.br.i64(i64 %v1, i64 %v2) { 640entry: 641; CHECK-LABEL: usubo.br.i64 642; CHECK: cmpq %rsi, %rdi 643; CHECK-NEXT: jb 644 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2) 645 %val = extractvalue {i64, i1} %t, 0 646 %obit = extractvalue {i64, i1} %t, 1 647 br i1 %obit, label %overflow, label %continue, !prof !0 648 649overflow: 650 ret i1 false 651 652continue: 653 ret i1 true 654} 655 656define zeroext i1 @smulo.br.i32(i32 %v1, i32 %v2) { 657entry: 658; CHECK-LABEL: smulo.br.i32 659; CHECK: imull %esi, %edi 660; CHECK-NEXT: jo 661 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2) 662 %val = extractvalue {i32, i1} %t, 0 663 %obit = extractvalue {i32, i1} %t, 1 664 br i1 %obit, label %overflow, label %continue, !prof !0 665 666overflow: 667 ret i1 false 668 669continue: 670 ret i1 true 671} 672 673define zeroext i1 @smulo.br.i64(i64 %v1, i64 %v2) { 674entry: 675; CHECK-LABEL: smulo.br.i64 676; CHECK: imulq %rsi, %rdi 677; CHECK-NEXT: jo 678 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2) 679 %val = extractvalue {i64, i1} %t, 0 680 %obit = extractvalue {i64, i1} %t, 1 681 br i1 %obit, label %overflow, label %continue, !prof !0 682 683overflow: 684 ret i1 false 685 686continue: 687 ret i1 true 688} 689 690define zeroext i1 @umulo.br.i32(i32 %v1, i32 %v2) { 691entry: 692; CHECK-LABEL: umulo.br.i32 693; CHECK: mull %esi 694; CHECK-NEXT: jo 695 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2) 696 %val = extractvalue {i32, i1} %t, 0 697 %obit = extractvalue {i32, i1} %t, 1 698 br i1 %obit, label %overflow, label %continue, !prof !0 699 700overflow: 701 ret i1 false 702 703continue: 704 ret i1 true 705} 706 707define zeroext i1 @umulo.br.i64(i64 %v1, i64 %v2) { 708entry: 709; CHECK-LABEL: umulo.br.i64 710; CHECK: mulq %rsi 711; CHECK-NEXT: jo 712 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2) 713 %val = extractvalue {i64, i1} %t, 0 714 %obit = extractvalue {i64, i1} %t, 1 715 br i1 %obit, label %overflow, label %continue, !prof !0 716 717overflow: 718 ret i1 false 719 720continue: 721 ret i1 true 722} 723 724declare {i8, i1} @llvm.sadd.with.overflow.i8 (i8, i8 ) nounwind readnone 725declare {i16, i1} @llvm.sadd.with.overflow.i16(i16, i16) nounwind readnone 726declare {i32, i1} @llvm.sadd.with.overflow.i32(i32, i32) nounwind readnone 727declare {i64, i1} @llvm.sadd.with.overflow.i64(i64, i64) nounwind readnone 728declare {i32, i1} @llvm.uadd.with.overflow.i32(i32, i32) nounwind readnone 729declare {i64, i1} @llvm.uadd.with.overflow.i64(i64, i64) nounwind readnone 730declare {i32, i1} @llvm.ssub.with.overflow.i32(i32, i32) nounwind readnone 731declare {i64, i1} @llvm.ssub.with.overflow.i64(i64, i64) nounwind readnone 732declare {i32, i1} @llvm.usub.with.overflow.i32(i32, i32) nounwind readnone 733declare {i64, i1} @llvm.usub.with.overflow.i64(i64, i64) nounwind readnone 734declare {i8, i1} @llvm.smul.with.overflow.i8 (i8, i8 ) nounwind readnone 735declare {i16, i1} @llvm.smul.with.overflow.i16(i16, i16) nounwind readnone 736declare {i32, i1} @llvm.smul.with.overflow.i32(i32, i32) nounwind readnone 737declare {i64, i1} @llvm.smul.with.overflow.i64(i64, i64) nounwind readnone 738declare {i8, i1} @llvm.umul.with.overflow.i8 (i8, i8 ) nounwind readnone 739declare {i16, i1} @llvm.umul.with.overflow.i16(i16, i16) nounwind readnone 740declare {i32, i1} @llvm.umul.with.overflow.i32(i32, i32) nounwind readnone 741declare {i64, i1} @llvm.umul.with.overflow.i64(i64, i64) nounwind readnone 742 743!0 = metadata !{metadata !"branch_weights", i32 0, i32 2147483647} 744