1068 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -mtriple=x86_64-darwin-unknown < %s | FileCheck %s --check-prefixes=CHECK,SDAG,GENERIC3; RUN: llc -mtriple=x86_64-darwin-unknown -fast-isel -fast-isel-abort=1 < %s | FileCheck %s --check-prefixes=CHECK,FAST4; RUN: llc -mtriple=x86_64-darwin-unknown -mcpu=knl < %s | FileCheck %s --check-prefixes=CHECK,SDAG,KNL5 6;7; Get the actual value of the overflow bit.8;9; SADDO reg, reg10define zeroext i1 @saddoi8(i8 signext %v1, i8 signext %v2, ptr %res) {11; SDAG-LABEL: saddoi8:12; SDAG: ## %bb.0:13; SDAG-NEXT: addb %sil, %dil14; SDAG-NEXT: seto %al15; SDAG-NEXT: movb %dil, (%rdx)16; SDAG-NEXT: retq17;18; FAST-LABEL: saddoi8:19; FAST: ## %bb.0:20; FAST-NEXT: addb %sil, %dil21; FAST-NEXT: seto %al22; FAST-NEXT: movb %dil, (%rdx)23; FAST-NEXT: andb $1, %al24; FAST-NEXT: retq25 %t = call {i8, i1} @llvm.sadd.with.overflow.i8(i8 %v1, i8 %v2)26 %val = extractvalue {i8, i1} %t, 027 %obit = extractvalue {i8, i1} %t, 128 store i8 %val, ptr %res29 ret i1 %obit30}31 32define zeroext i1 @saddoi16(i16 %v1, i16 %v2, ptr %res) {33; SDAG-LABEL: saddoi16:34; SDAG: ## %bb.0:35; SDAG-NEXT: addw %si, %di36; SDAG-NEXT: seto %al37; SDAG-NEXT: movw %di, (%rdx)38; SDAG-NEXT: retq39;40; FAST-LABEL: saddoi16:41; FAST: ## %bb.0:42; FAST-NEXT: addw %si, %di43; FAST-NEXT: seto %al44; FAST-NEXT: movw %di, (%rdx)45; FAST-NEXT: andb $1, %al46; FAST-NEXT: retq47 %t = call {i16, i1} @llvm.sadd.with.overflow.i16(i16 %v1, i16 %v2)48 %val = extractvalue {i16, i1} %t, 049 %obit = extractvalue {i16, i1} %t, 150 store i16 %val, ptr %res51 ret i1 %obit52}53 54define zeroext i1 @saddoi32(i32 %v1, i32 %v2, ptr %res) {55; SDAG-LABEL: saddoi32:56; SDAG: ## %bb.0:57; SDAG-NEXT: addl %esi, %edi58; SDAG-NEXT: seto %al59; SDAG-NEXT: movl %edi, (%rdx)60; SDAG-NEXT: retq61;62; FAST-LABEL: saddoi32:63; FAST: ## %bb.0:64; FAST-NEXT: addl %esi, %edi65; FAST-NEXT: seto %al66; FAST-NEXT: movl %edi, (%rdx)67; FAST-NEXT: andb $1, %al68; FAST-NEXT: retq69 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2)70 %val = extractvalue {i32, i1} %t, 071 %obit = extractvalue {i32, i1} %t, 172 store i32 %val, ptr %res73 ret i1 %obit74}75 76define zeroext i1 @saddoi64(i64 %v1, i64 %v2, ptr %res) {77; SDAG-LABEL: saddoi64:78; SDAG: ## %bb.0:79; SDAG-NEXT: addq %rsi, %rdi80; SDAG-NEXT: seto %al81; SDAG-NEXT: movq %rdi, (%rdx)82; SDAG-NEXT: retq83;84; FAST-LABEL: saddoi64:85; FAST: ## %bb.0:86; FAST-NEXT: addq %rsi, %rdi87; FAST-NEXT: seto %al88; FAST-NEXT: movq %rdi, (%rdx)89; FAST-NEXT: andb $1, %al90; FAST-NEXT: retq91 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2)92 %val = extractvalue {i64, i1} %t, 093 %obit = extractvalue {i64, i1} %t, 194 store i64 %val, ptr %res95 ret i1 %obit96}97 98; SADDO reg, 1 | INC99define zeroext i1 @saddoinci8(i8 %v1, ptr %res) {100; SDAG-LABEL: saddoinci8:101; SDAG: ## %bb.0:102; SDAG-NEXT: incb %dil103; SDAG-NEXT: seto %al104; SDAG-NEXT: movb %dil, (%rsi)105; SDAG-NEXT: retq106;107; FAST-LABEL: saddoinci8:108; FAST: ## %bb.0:109; FAST-NEXT: incb %dil110; FAST-NEXT: seto %al111; FAST-NEXT: movb %dil, (%rsi)112; FAST-NEXT: andb $1, %al113; FAST-NEXT: retq114 %t = call {i8, i1} @llvm.sadd.with.overflow.i8(i8 %v1, i8 1)115 %val = extractvalue {i8, i1} %t, 0116 %obit = extractvalue {i8, i1} %t, 1117 store i8 %val, ptr %res118 ret i1 %obit119}120 121define zeroext i1 @saddoinci16(i16 %v1, ptr %res) {122; SDAG-LABEL: saddoinci16:123; SDAG: ## %bb.0:124; SDAG-NEXT: incw %di125; SDAG-NEXT: seto %al126; SDAG-NEXT: movw %di, (%rsi)127; SDAG-NEXT: retq128;129; FAST-LABEL: saddoinci16:130; FAST: ## %bb.0:131; FAST-NEXT: incw %di132; FAST-NEXT: seto %al133; FAST-NEXT: movw %di, (%rsi)134; FAST-NEXT: andb $1, %al135; FAST-NEXT: retq136 %t = call {i16, i1} @llvm.sadd.with.overflow.i16(i16 %v1, i16 1)137 %val = extractvalue {i16, i1} %t, 0138 %obit = extractvalue {i16, i1} %t, 1139 store i16 %val, ptr %res140 ret i1 %obit141}142 143define zeroext i1 @saddoinci32(i32 %v1, ptr %res) {144; SDAG-LABEL: saddoinci32:145; SDAG: ## %bb.0:146; SDAG-NEXT: incl %edi147; SDAG-NEXT: seto %al148; SDAG-NEXT: movl %edi, (%rsi)149; SDAG-NEXT: retq150;151; FAST-LABEL: saddoinci32:152; FAST: ## %bb.0:153; FAST-NEXT: incl %edi154; FAST-NEXT: seto %al155; FAST-NEXT: movl %edi, (%rsi)156; FAST-NEXT: andb $1, %al157; FAST-NEXT: retq158 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 1)159 %val = extractvalue {i32, i1} %t, 0160 %obit = extractvalue {i32, i1} %t, 1161 store i32 %val, ptr %res162 ret i1 %obit163}164 165define zeroext i1 @saddoinci64(i64 %v1, ptr %res) {166; SDAG-LABEL: saddoinci64:167; SDAG: ## %bb.0:168; SDAG-NEXT: incq %rdi169; SDAG-NEXT: seto %al170; SDAG-NEXT: movq %rdi, (%rsi)171; SDAG-NEXT: retq172;173; FAST-LABEL: saddoinci64:174; FAST: ## %bb.0:175; FAST-NEXT: incq %rdi176; FAST-NEXT: seto %al177; FAST-NEXT: movq %rdi, (%rsi)178; FAST-NEXT: andb $1, %al179; FAST-NEXT: retq180 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 1)181 %val = extractvalue {i64, i1} %t, 0182 %obit = extractvalue {i64, i1} %t, 1183 store i64 %val, ptr %res184 ret i1 %obit185}186 187; SADDO reg, imm | imm, reg188define zeroext i1 @saddoi64imm1(i64 %v1, ptr %res) {189; SDAG-LABEL: saddoi64imm1:190; SDAG: ## %bb.0:191; SDAG-NEXT: addq $2, %rdi192; SDAG-NEXT: seto %al193; SDAG-NEXT: movq %rdi, (%rsi)194; SDAG-NEXT: retq195;196; FAST-LABEL: saddoi64imm1:197; FAST: ## %bb.0:198; FAST-NEXT: addq $2, %rdi199; FAST-NEXT: seto %al200; FAST-NEXT: movq %rdi, (%rsi)201; FAST-NEXT: andb $1, %al202; FAST-NEXT: retq203 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 2, i64 %v1)204 %val = extractvalue {i64, i1} %t, 0205 %obit = extractvalue {i64, i1} %t, 1206 store i64 %val, ptr %res207 ret i1 %obit208}209 210; Check boundary conditions for large immediates.211define zeroext i1 @saddoi64imm2(i64 %v1, ptr %res) {212; SDAG-LABEL: saddoi64imm2:213; SDAG: ## %bb.0:214; SDAG-NEXT: addq $-2147483648, %rdi ## imm = 0x80000000215; SDAG-NEXT: seto %al216; SDAG-NEXT: movq %rdi, (%rsi)217; SDAG-NEXT: retq218;219; FAST-LABEL: saddoi64imm2:220; FAST: ## %bb.0:221; FAST-NEXT: addq $-2147483648, %rdi ## imm = 0x80000000222; FAST-NEXT: seto %al223; FAST-NEXT: movq %rdi, (%rsi)224; FAST-NEXT: andb $1, %al225; FAST-NEXT: retq226 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 -2147483648)227 %val = extractvalue {i64, i1} %t, 0228 %obit = extractvalue {i64, i1} %t, 1229 store i64 %val, ptr %res230 ret i1 %obit231}232 233define zeroext i1 @saddoi64imm3(i64 %v1, ptr %res) {234; SDAG-LABEL: saddoi64imm3:235; SDAG: ## %bb.0:236; SDAG-NEXT: movabsq $-21474836489, %rcx ## imm = 0xFFFFFFFAFFFFFFF7237; SDAG-NEXT: addq %rdi, %rcx238; SDAG-NEXT: seto %al239; SDAG-NEXT: movq %rcx, (%rsi)240; SDAG-NEXT: retq241;242; FAST-LABEL: saddoi64imm3:243; FAST: ## %bb.0:244; FAST-NEXT: movabsq $-21474836489, %rcx ## imm = 0xFFFFFFFAFFFFFFF7245; FAST-NEXT: addq %rdi, %rcx246; FAST-NEXT: seto %al247; FAST-NEXT: movq %rcx, (%rsi)248; FAST-NEXT: andb $1, %al249; FAST-NEXT: retq250 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 -21474836489)251 %val = extractvalue {i64, i1} %t, 0252 %obit = extractvalue {i64, i1} %t, 1253 store i64 %val, ptr %res254 ret i1 %obit255}256 257define zeroext i1 @saddoi64imm4(i64 %v1, ptr %res) {258; SDAG-LABEL: saddoi64imm4:259; SDAG: ## %bb.0:260; SDAG-NEXT: addq $2147483647, %rdi ## imm = 0x7FFFFFFF261; SDAG-NEXT: seto %al262; SDAG-NEXT: movq %rdi, (%rsi)263; SDAG-NEXT: retq264;265; FAST-LABEL: saddoi64imm4:266; FAST: ## %bb.0:267; FAST-NEXT: addq $2147483647, %rdi ## imm = 0x7FFFFFFF268; FAST-NEXT: seto %al269; FAST-NEXT: movq %rdi, (%rsi)270; FAST-NEXT: andb $1, %al271; FAST-NEXT: retq272 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 2147483647)273 %val = extractvalue {i64, i1} %t, 0274 %obit = extractvalue {i64, i1} %t, 1275 store i64 %val, ptr %res276 ret i1 %obit277}278 279define zeroext i1 @saddoi64imm5(i64 %v1, ptr %res) {280; SDAG-LABEL: saddoi64imm5:281; SDAG: ## %bb.0:282; SDAG-NEXT: subq $-2147483648, %rdi ## imm = 0x80000000283; SDAG-NEXT: seto %al284; SDAG-NEXT: movq %rdi, (%rsi)285; SDAG-NEXT: retq286;287; FAST-LABEL: saddoi64imm5:288; FAST: ## %bb.0:289; FAST-NEXT: movl $2147483648, %ecx ## imm = 0x80000000290; FAST-NEXT: addq %rdi, %rcx291; FAST-NEXT: seto %al292; FAST-NEXT: movq %rcx, (%rsi)293; FAST-NEXT: andb $1, %al294; FAST-NEXT: retq295 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 2147483648)296 %val = extractvalue {i64, i1} %t, 0297 %obit = extractvalue {i64, i1} %t, 1298 store i64 %val, ptr %res299 ret i1 %obit300}301 302; UADDO303define zeroext i1 @uaddoi32(i32 %v1, i32 %v2, ptr %res) {304; SDAG-LABEL: uaddoi32:305; SDAG: ## %bb.0:306; SDAG-NEXT: addl %esi, %edi307; SDAG-NEXT: setb %al308; SDAG-NEXT: movl %edi, (%rdx)309; SDAG-NEXT: retq310;311; FAST-LABEL: uaddoi32:312; FAST: ## %bb.0:313; FAST-NEXT: addl %esi, %edi314; FAST-NEXT: setb %al315; FAST-NEXT: movl %edi, (%rdx)316; FAST-NEXT: andb $1, %al317; FAST-NEXT: retq318 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)319 %val = extractvalue {i32, i1} %t, 0320 %obit = extractvalue {i32, i1} %t, 1321 store i32 %val, ptr %res322 ret i1 %obit323}324 325define zeroext i1 @uaddoi64(i64 %v1, i64 %v2, ptr %res) {326; SDAG-LABEL: uaddoi64:327; SDAG: ## %bb.0:328; SDAG-NEXT: addq %rsi, %rdi329; SDAG-NEXT: setb %al330; SDAG-NEXT: movq %rdi, (%rdx)331; SDAG-NEXT: retq332;333; FAST-LABEL: uaddoi64:334; FAST: ## %bb.0:335; FAST-NEXT: addq %rsi, %rdi336; FAST-NEXT: setb %al337; FAST-NEXT: movq %rdi, (%rdx)338; FAST-NEXT: andb $1, %al339; FAST-NEXT: retq340 %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2)341 %val = extractvalue {i64, i1} %t, 0342 %obit = extractvalue {i64, i1} %t, 1343 store i64 %val, ptr %res344 ret i1 %obit345}346 347; UADDO reg, 1 | NOT INC348define zeroext i1 @uaddoinci8(i8 %v1, ptr %res) {349; SDAG-LABEL: uaddoinci8:350; SDAG: ## %bb.0:351; SDAG-NEXT: incb %dil352; SDAG-NEXT: sete %al353; SDAG-NEXT: movb %dil, (%rsi)354; SDAG-NEXT: retq355;356; FAST-LABEL: uaddoinci8:357; FAST: ## %bb.0:358; FAST-NEXT: addb $1, %dil359; FAST-NEXT: setb %al360; FAST-NEXT: movb %dil, (%rsi)361; FAST-NEXT: andb $1, %al362; FAST-NEXT: retq363 %t = call {i8, i1} @llvm.uadd.with.overflow.i8(i8 %v1, i8 1)364 %val = extractvalue {i8, i1} %t, 0365 %obit = extractvalue {i8, i1} %t, 1366 store i8 %val, ptr %res367 ret i1 %obit368}369 370define zeroext i1 @uaddoinci16(i16 %v1, ptr %res) {371; SDAG-LABEL: uaddoinci16:372; SDAG: ## %bb.0:373; SDAG-NEXT: incw %di374; SDAG-NEXT: sete %al375; SDAG-NEXT: movw %di, (%rsi)376; SDAG-NEXT: retq377;378; FAST-LABEL: uaddoinci16:379; FAST: ## %bb.0:380; FAST-NEXT: addw $1, %di381; FAST-NEXT: setb %al382; FAST-NEXT: movw %di, (%rsi)383; FAST-NEXT: andb $1, %al384; FAST-NEXT: retq385 %t = call {i16, i1} @llvm.uadd.with.overflow.i16(i16 %v1, i16 1)386 %val = extractvalue {i16, i1} %t, 0387 %obit = extractvalue {i16, i1} %t, 1388 store i16 %val, ptr %res389 ret i1 %obit390}391 392define zeroext i1 @uaddoinci32(i32 %v1, ptr %res) {393; SDAG-LABEL: uaddoinci32:394; SDAG: ## %bb.0:395; SDAG-NEXT: incl %edi396; SDAG-NEXT: sete %al397; SDAG-NEXT: movl %edi, (%rsi)398; SDAG-NEXT: retq399;400; FAST-LABEL: uaddoinci32:401; FAST: ## %bb.0:402; FAST-NEXT: addl $1, %edi403; FAST-NEXT: setb %al404; FAST-NEXT: movl %edi, (%rsi)405; FAST-NEXT: andb $1, %al406; FAST-NEXT: retq407 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 1)408 %val = extractvalue {i32, i1} %t, 0409 %obit = extractvalue {i32, i1} %t, 1410 store i32 %val, ptr %res411 ret i1 %obit412}413 414define zeroext i1 @uaddoinci64(i64 %v1, ptr %res) {415; SDAG-LABEL: uaddoinci64:416; SDAG: ## %bb.0:417; SDAG-NEXT: incq %rdi418; SDAG-NEXT: sete %al419; SDAG-NEXT: movq %rdi, (%rsi)420; SDAG-NEXT: retq421;422; FAST-LABEL: uaddoinci64:423; FAST: ## %bb.0:424; FAST-NEXT: addq $1, %rdi425; FAST-NEXT: setb %al426; FAST-NEXT: movq %rdi, (%rsi)427; FAST-NEXT: andb $1, %al428; FAST-NEXT: retq429 %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 1)430 %val = extractvalue {i64, i1} %t, 0431 %obit = extractvalue {i64, i1} %t, 1432 store i64 %val, ptr %res433 ret i1 %obit434}435 436; SSUBO437define zeroext i1 @ssuboi32(i32 %v1, i32 %v2, ptr %res) {438; SDAG-LABEL: ssuboi32:439; SDAG: ## %bb.0:440; SDAG-NEXT: subl %esi, %edi441; SDAG-NEXT: seto %al442; SDAG-NEXT: movl %edi, (%rdx)443; SDAG-NEXT: retq444;445; FAST-LABEL: ssuboi32:446; FAST: ## %bb.0:447; FAST-NEXT: subl %esi, %edi448; FAST-NEXT: seto %al449; FAST-NEXT: movl %edi, (%rdx)450; FAST-NEXT: andb $1, %al451; FAST-NEXT: retq452 %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2)453 %val = extractvalue {i32, i1} %t, 0454 %obit = extractvalue {i32, i1} %t, 1455 store i32 %val, ptr %res456 ret i1 %obit457}458 459define zeroext i1 @ssuboi64(i64 %v1, i64 %v2, ptr %res) {460; SDAG-LABEL: ssuboi64:461; SDAG: ## %bb.0:462; SDAG-NEXT: subq %rsi, %rdi463; SDAG-NEXT: seto %al464; SDAG-NEXT: movq %rdi, (%rdx)465; SDAG-NEXT: retq466;467; FAST-LABEL: ssuboi64:468; FAST: ## %bb.0:469; FAST-NEXT: subq %rsi, %rdi470; FAST-NEXT: seto %al471; FAST-NEXT: movq %rdi, (%rdx)472; FAST-NEXT: andb $1, %al473; FAST-NEXT: retq474 %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2)475 %val = extractvalue {i64, i1} %t, 0476 %obit = extractvalue {i64, i1} %t, 1477 store i64 %val, ptr %res478 ret i1 %obit479}480 481; USUBO482define zeroext i1 @usuboi32(i32 %v1, i32 %v2, ptr %res) {483; SDAG-LABEL: usuboi32:484; SDAG: ## %bb.0:485; SDAG-NEXT: subl %esi, %edi486; SDAG-NEXT: setb %al487; SDAG-NEXT: movl %edi, (%rdx)488; SDAG-NEXT: retq489;490; FAST-LABEL: usuboi32:491; FAST: ## %bb.0:492; FAST-NEXT: subl %esi, %edi493; FAST-NEXT: setb %al494; FAST-NEXT: movl %edi, (%rdx)495; FAST-NEXT: andb $1, %al496; FAST-NEXT: retq497 %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2)498 %val = extractvalue {i32, i1} %t, 0499 %obit = extractvalue {i32, i1} %t, 1500 store i32 %val, ptr %res501 ret i1 %obit502}503 504define zeroext i1 @usuboi64(i64 %v1, i64 %v2, ptr %res) {505; SDAG-LABEL: usuboi64:506; SDAG: ## %bb.0:507; SDAG-NEXT: subq %rsi, %rdi508; SDAG-NEXT: setb %al509; SDAG-NEXT: movq %rdi, (%rdx)510; SDAG-NEXT: retq511;512; FAST-LABEL: usuboi64:513; FAST: ## %bb.0:514; FAST-NEXT: subq %rsi, %rdi515; FAST-NEXT: setb %al516; FAST-NEXT: movq %rdi, (%rdx)517; FAST-NEXT: andb $1, %al518; FAST-NEXT: retq519 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2)520 %val = extractvalue {i64, i1} %t, 0521 %obit = extractvalue {i64, i1} %t, 1522 store i64 %val, ptr %res523 ret i1 %obit524}525 526;527; Check the use of the overflow bit in combination with a select instruction.528;529define i32 @saddoselecti32(i32 %v1, i32 %v2) {530; CHECK-LABEL: saddoselecti32:531; CHECK: ## %bb.0:532; CHECK-NEXT: movl %esi, %eax533; CHECK-NEXT: movl %edi, %ecx534; CHECK-NEXT: addl %esi, %ecx535; CHECK-NEXT: cmovol %edi, %eax536; CHECK-NEXT: retq537 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2)538 %obit = extractvalue {i32, i1} %t, 1539 %ret = select i1 %obit, i32 %v1, i32 %v2540 ret i32 %ret541}542 543define i64 @saddoselecti64(i64 %v1, i64 %v2) {544; CHECK-LABEL: saddoselecti64:545; CHECK: ## %bb.0:546; CHECK-NEXT: movq %rsi, %rax547; CHECK-NEXT: movq %rdi, %rcx548; CHECK-NEXT: addq %rsi, %rcx549; CHECK-NEXT: cmovoq %rdi, %rax550; CHECK-NEXT: retq551 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2)552 %obit = extractvalue {i64, i1} %t, 1553 %ret = select i1 %obit, i64 %v1, i64 %v2554 ret i64 %ret555}556 557define i32 @uaddoselecti32(i32 %v1, i32 %v2) {558; CHECK-LABEL: uaddoselecti32:559; CHECK: ## %bb.0:560; CHECK-NEXT: movl %esi, %eax561; CHECK-NEXT: movl %edi, %ecx562; CHECK-NEXT: addl %esi, %ecx563; CHECK-NEXT: cmovbl %edi, %eax564; CHECK-NEXT: retq565 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)566 %obit = extractvalue {i32, i1} %t, 1567 %ret = select i1 %obit, i32 %v1, i32 %v2568 ret i32 %ret569}570 571define i64 @uaddoselecti64(i64 %v1, i64 %v2) {572; CHECK-LABEL: uaddoselecti64:573; CHECK: ## %bb.0:574; CHECK-NEXT: movq %rsi, %rax575; CHECK-NEXT: movq %rdi, %rcx576; CHECK-NEXT: addq %rsi, %rcx577; CHECK-NEXT: cmovbq %rdi, %rax578; CHECK-NEXT: retq579 %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2)580 %obit = extractvalue {i64, i1} %t, 1581 %ret = select i1 %obit, i64 %v1, i64 %v2582 ret i64 %ret583}584 585define i32 @ssuboselecti32(i32 %v1, i32 %v2) {586; CHECK-LABEL: ssuboselecti32:587; CHECK: ## %bb.0:588; CHECK-NEXT: movl %esi, %eax589; CHECK-NEXT: cmpl %esi, %edi590; CHECK-NEXT: cmovol %edi, %eax591; CHECK-NEXT: retq592 %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2)593 %obit = extractvalue {i32, i1} %t, 1594 %ret = select i1 %obit, i32 %v1, i32 %v2595 ret i32 %ret596}597 598define i64 @ssuboselecti64(i64 %v1, i64 %v2) {599; CHECK-LABEL: ssuboselecti64:600; CHECK: ## %bb.0:601; CHECK-NEXT: movq %rsi, %rax602; CHECK-NEXT: cmpq %rsi, %rdi603; CHECK-NEXT: cmovoq %rdi, %rax604; CHECK-NEXT: retq605 %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2)606 %obit = extractvalue {i64, i1} %t, 1607 %ret = select i1 %obit, i64 %v1, i64 %v2608 ret i64 %ret609}610 611define i32 @usuboselecti32(i32 %v1, i32 %v2) {612; CHECK-LABEL: usuboselecti32:613; CHECK: ## %bb.0:614; CHECK-NEXT: movl %esi, %eax615; CHECK-NEXT: cmpl %esi, %edi616; CHECK-NEXT: cmovbl %edi, %eax617; CHECK-NEXT: retq618 %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2)619 %obit = extractvalue {i32, i1} %t, 1620 %ret = select i1 %obit, i32 %v1, i32 %v2621 ret i32 %ret622}623 624define i64 @usuboselecti64(i64 %v1, i64 %v2) {625; CHECK-LABEL: usuboselecti64:626; CHECK: ## %bb.0:627; CHECK-NEXT: movq %rsi, %rax628; CHECK-NEXT: cmpq %rsi, %rdi629; CHECK-NEXT: cmovbq %rdi, %rax630; CHECK-NEXT: retq631 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2)632 %obit = extractvalue {i64, i1} %t, 1633 %ret = select i1 %obit, i64 %v1, i64 %v2634 ret i64 %ret635}636 637;638; Check the use of the overflow bit in combination with a branch instruction.639;640define zeroext i1 @saddobri32(i32 %v1, i32 %v2) {641; SDAG-LABEL: saddobri32:642; SDAG: ## %bb.0:643; SDAG-NEXT: addl %esi, %edi644; SDAG-NEXT: jo LBB31_1645; SDAG-NEXT: ## %bb.2: ## %continue646; SDAG-NEXT: movb $1, %al647; SDAG-NEXT: retq648; SDAG-NEXT: LBB31_1: ## %overflow649; SDAG-NEXT: xorl %eax, %eax650; SDAG-NEXT: retq651;652; FAST-LABEL: saddobri32:653; FAST: ## %bb.0:654; FAST-NEXT: addl %esi, %edi655; FAST-NEXT: jo LBB31_1656; FAST-NEXT: ## %bb.2: ## %continue657; FAST-NEXT: movb $1, %al658; FAST-NEXT: andb $1, %al659; FAST-NEXT: retq660; FAST-NEXT: LBB31_1: ## %overflow661; FAST-NEXT: xorl %eax, %eax662; FAST-NEXT: andb $1, %al663; FAST-NEXT: ## kill: def $al killed $al killed $eax664; FAST-NEXT: retq665 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2)666 %val = extractvalue {i32, i1} %t, 0667 %obit = extractvalue {i32, i1} %t, 1668 br i1 %obit, label %overflow, label %continue, !prof !0669 670overflow:671 ret i1 false672 673continue:674 ret i1 true675}676 677define zeroext i1 @saddobri64(i64 %v1, i64 %v2) {678; SDAG-LABEL: saddobri64:679; SDAG: ## %bb.0:680; SDAG-NEXT: addq %rsi, %rdi681; SDAG-NEXT: jo LBB32_1682; SDAG-NEXT: ## %bb.2: ## %continue683; SDAG-NEXT: movb $1, %al684; SDAG-NEXT: retq685; SDAG-NEXT: LBB32_1: ## %overflow686; SDAG-NEXT: xorl %eax, %eax687; SDAG-NEXT: retq688;689; FAST-LABEL: saddobri64:690; FAST: ## %bb.0:691; FAST-NEXT: addq %rsi, %rdi692; FAST-NEXT: jo LBB32_1693; FAST-NEXT: ## %bb.2: ## %continue694; FAST-NEXT: movb $1, %al695; FAST-NEXT: andb $1, %al696; FAST-NEXT: retq697; FAST-NEXT: LBB32_1: ## %overflow698; FAST-NEXT: xorl %eax, %eax699; FAST-NEXT: andb $1, %al700; FAST-NEXT: ## kill: def $al killed $al killed $eax701; FAST-NEXT: retq702 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2)703 %val = extractvalue {i64, i1} %t, 0704 %obit = extractvalue {i64, i1} %t, 1705 br i1 %obit, label %overflow, label %continue, !prof !0706 707overflow:708 ret i1 false709 710continue:711 ret i1 true712}713 714define zeroext i1 @uaddobri32(i32 %v1, i32 %v2) {715; SDAG-LABEL: uaddobri32:716; SDAG: ## %bb.0:717; SDAG-NEXT: addl %esi, %edi718; SDAG-NEXT: jb LBB33_1719; SDAG-NEXT: ## %bb.2: ## %continue720; SDAG-NEXT: movb $1, %al721; SDAG-NEXT: retq722; SDAG-NEXT: LBB33_1: ## %overflow723; SDAG-NEXT: xorl %eax, %eax724; SDAG-NEXT: retq725;726; FAST-LABEL: uaddobri32:727; FAST: ## %bb.0:728; FAST-NEXT: addl %esi, %edi729; FAST-NEXT: jb LBB33_1730; FAST-NEXT: ## %bb.2: ## %continue731; FAST-NEXT: movb $1, %al732; FAST-NEXT: andb $1, %al733; FAST-NEXT: retq734; FAST-NEXT: LBB33_1: ## %overflow735; FAST-NEXT: xorl %eax, %eax736; FAST-NEXT: andb $1, %al737; FAST-NEXT: ## kill: def $al killed $al killed $eax738; FAST-NEXT: retq739 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)740 %val = extractvalue {i32, i1} %t, 0741 %obit = extractvalue {i32, i1} %t, 1742 br i1 %obit, label %overflow, label %continue, !prof !0743 744overflow:745 ret i1 false746 747continue:748 ret i1 true749}750 751define zeroext i1 @uaddobri64(i64 %v1, i64 %v2) {752; SDAG-LABEL: uaddobri64:753; SDAG: ## %bb.0:754; SDAG-NEXT: addq %rsi, %rdi755; SDAG-NEXT: jb LBB34_1756; SDAG-NEXT: ## %bb.2: ## %continue757; SDAG-NEXT: movb $1, %al758; SDAG-NEXT: retq759; SDAG-NEXT: LBB34_1: ## %overflow760; SDAG-NEXT: xorl %eax, %eax761; SDAG-NEXT: retq762;763; FAST-LABEL: uaddobri64:764; FAST: ## %bb.0:765; FAST-NEXT: addq %rsi, %rdi766; FAST-NEXT: jb LBB34_1767; FAST-NEXT: ## %bb.2: ## %continue768; FAST-NEXT: movb $1, %al769; FAST-NEXT: andb $1, %al770; FAST-NEXT: retq771; FAST-NEXT: LBB34_1: ## %overflow772; FAST-NEXT: xorl %eax, %eax773; FAST-NEXT: andb $1, %al774; FAST-NEXT: ## kill: def $al killed $al killed $eax775; FAST-NEXT: retq776 %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2)777 %val = extractvalue {i64, i1} %t, 0778 %obit = extractvalue {i64, i1} %t, 1779 br i1 %obit, label %overflow, label %continue, !prof !0780 781overflow:782 ret i1 false783 784continue:785 ret i1 true786}787 788define zeroext i1 @ssubobri32(i32 %v1, i32 %v2) {789; SDAG-LABEL: ssubobri32:790; SDAG: ## %bb.0:791; SDAG-NEXT: cmpl %esi, %edi792; SDAG-NEXT: jo LBB35_1793; SDAG-NEXT: ## %bb.2: ## %continue794; SDAG-NEXT: movb $1, %al795; SDAG-NEXT: retq796; SDAG-NEXT: LBB35_1: ## %overflow797; SDAG-NEXT: xorl %eax, %eax798; SDAG-NEXT: retq799;800; FAST-LABEL: ssubobri32:801; FAST: ## %bb.0:802; FAST-NEXT: cmpl %esi, %edi803; FAST-NEXT: jo LBB35_1804; FAST-NEXT: ## %bb.2: ## %continue805; FAST-NEXT: movb $1, %al806; FAST-NEXT: andb $1, %al807; FAST-NEXT: retq808; FAST-NEXT: LBB35_1: ## %overflow809; FAST-NEXT: xorl %eax, %eax810; FAST-NEXT: andb $1, %al811; FAST-NEXT: ## kill: def $al killed $al killed $eax812; FAST-NEXT: retq813 %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2)814 %val = extractvalue {i32, i1} %t, 0815 %obit = extractvalue {i32, i1} %t, 1816 br i1 %obit, label %overflow, label %continue, !prof !0817 818overflow:819 ret i1 false820 821continue:822 ret i1 true823}824 825define zeroext i1 @ssubobri64(i64 %v1, i64 %v2) {826; SDAG-LABEL: ssubobri64:827; SDAG: ## %bb.0:828; SDAG-NEXT: cmpq %rsi, %rdi829; SDAG-NEXT: jo LBB36_1830; SDAG-NEXT: ## %bb.2: ## %continue831; SDAG-NEXT: movb $1, %al832; SDAG-NEXT: retq833; SDAG-NEXT: LBB36_1: ## %overflow834; SDAG-NEXT: xorl %eax, %eax835; SDAG-NEXT: retq836;837; FAST-LABEL: ssubobri64:838; FAST: ## %bb.0:839; FAST-NEXT: cmpq %rsi, %rdi840; FAST-NEXT: jo LBB36_1841; FAST-NEXT: ## %bb.2: ## %continue842; FAST-NEXT: movb $1, %al843; FAST-NEXT: andb $1, %al844; FAST-NEXT: retq845; FAST-NEXT: LBB36_1: ## %overflow846; FAST-NEXT: xorl %eax, %eax847; FAST-NEXT: andb $1, %al848; FAST-NEXT: ## kill: def $al killed $al killed $eax849; FAST-NEXT: retq850 %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2)851 %val = extractvalue {i64, i1} %t, 0852 %obit = extractvalue {i64, i1} %t, 1853 br i1 %obit, label %overflow, label %continue, !prof !0854 855overflow:856 ret i1 false857 858continue:859 ret i1 true860}861 862define zeroext i1 @usubobri32(i32 %v1, i32 %v2) {863; SDAG-LABEL: usubobri32:864; SDAG: ## %bb.0:865; SDAG-NEXT: cmpl %esi, %edi866; SDAG-NEXT: jb LBB37_1867; SDAG-NEXT: ## %bb.2: ## %continue868; SDAG-NEXT: movb $1, %al869; SDAG-NEXT: retq870; SDAG-NEXT: LBB37_1: ## %overflow871; SDAG-NEXT: xorl %eax, %eax872; SDAG-NEXT: retq873;874; FAST-LABEL: usubobri32:875; FAST: ## %bb.0:876; FAST-NEXT: cmpl %esi, %edi877; FAST-NEXT: jb LBB37_1878; FAST-NEXT: ## %bb.2: ## %continue879; FAST-NEXT: movb $1, %al880; FAST-NEXT: andb $1, %al881; FAST-NEXT: retq882; FAST-NEXT: LBB37_1: ## %overflow883; FAST-NEXT: xorl %eax, %eax884; FAST-NEXT: andb $1, %al885; FAST-NEXT: ## kill: def $al killed $al killed $eax886; FAST-NEXT: retq887 %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2)888 %val = extractvalue {i32, i1} %t, 0889 %obit = extractvalue {i32, i1} %t, 1890 br i1 %obit, label %overflow, label %continue, !prof !0891 892overflow:893 ret i1 false894 895continue:896 ret i1 true897}898 899define zeroext i1 @usubobri64(i64 %v1, i64 %v2) {900; SDAG-LABEL: usubobri64:901; SDAG: ## %bb.0:902; SDAG-NEXT: cmpq %rsi, %rdi903; SDAG-NEXT: jb LBB38_1904; SDAG-NEXT: ## %bb.2: ## %continue905; SDAG-NEXT: movb $1, %al906; SDAG-NEXT: retq907; SDAG-NEXT: LBB38_1: ## %overflow908; SDAG-NEXT: xorl %eax, %eax909; SDAG-NEXT: retq910;911; FAST-LABEL: usubobri64:912; FAST: ## %bb.0:913; FAST-NEXT: cmpq %rsi, %rdi914; FAST-NEXT: jb LBB38_1915; FAST-NEXT: ## %bb.2: ## %continue916; FAST-NEXT: movb $1, %al917; FAST-NEXT: andb $1, %al918; FAST-NEXT: retq919; FAST-NEXT: LBB38_1: ## %overflow920; FAST-NEXT: xorl %eax, %eax921; FAST-NEXT: andb $1, %al922; FAST-NEXT: ## kill: def $al killed $al killed $eax923; FAST-NEXT: retq924 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2)925 %val = extractvalue {i64, i1} %t, 0926 %obit = extractvalue {i64, i1} %t, 1927 br i1 %obit, label %overflow, label %continue, !prof !0928 929overflow:930 ret i1 false931 932continue:933 ret i1 true934}935 936define {i64, i1} @saddoovf(i64 %a, i64 %b) {937; CHECK-LABEL: saddoovf:938; CHECK: ## %bb.0:939; CHECK-NEXT: sarq $17, %rdi940; CHECK-NEXT: shrq $31, %rsi941; CHECK-NEXT: leaq (%rsi,%rdi), %rax942; CHECK-NEXT: xorl %edx, %edx943; CHECK-NEXT: retq944 %1 = ashr i64 %a, 17945 %2 = lshr i64 %b, 31946 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %1, i64 %2)947 ret {i64, i1} %t948}949 950define {i64, i1} @ssuboovf(i64 %a, i64 %b) {951; CHECK-LABEL: ssuboovf:952; CHECK: ## %bb.0:953; CHECK-NEXT: movzwl %di, %eax954; CHECK-NEXT: shrq $22, %rsi955; CHECK-NEXT: subq %rsi, %rax956; CHECK-NEXT: xorl %edx, %edx957; CHECK-NEXT: retq958 %1 = and i64 %a, 65535959 %2 = lshr i64 %b, 22960 %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %1, i64 %2)961 ret {i64, i1} %t962}963 964define {i64, i1} @uaddoovf(i64 %a, i64 %b) {965; CHECK-LABEL: uaddoovf:966; CHECK: ## %bb.0:967; CHECK-NEXT: movzbl %dil, %ecx968; CHECK-NEXT: movzbl %sil, %eax969; CHECK-NEXT: addq %rcx, %rax970; CHECK-NEXT: xorl %edx, %edx971; CHECK-NEXT: retq972 %1 = and i64 %a, 255973 %2 = and i64 %b, 255974 %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %1, i64 %2)975 ret {i64, i1} %t976}977 978define {i64, i1} @usuboovf(i64 %a, i64 %b) {979; CHECK-LABEL: usuboovf:980; CHECK: ## %bb.0:981; CHECK-NEXT: movq %rsi, %rax982; CHECK-NEXT: notq %rax983; CHECK-NEXT: xorl %edx, %edx984; CHECK-NEXT: retq985 %t0 = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %a, i64 %a)986 %v0 = extractvalue {i64, i1} %t0, 0987 %o0 = extractvalue {i64, i1} %t0, 1988 %t1 = call {i64, i1} @llvm.usub.with.overflow.i64(i64 -1, i64 %b)989 %v1 = extractvalue {i64, i1} %t1, 0990 %o1 = extractvalue {i64, i1} %t1, 1991 %oo = or i1 %o0, %o1992 %t2 = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v0)993 %v2 = extractvalue {i64, i1} %t2, 0994 %o2 = extractvalue {i64, i1} %t2, 1995 %ooo = or i1 %oo, %o2996 %t = insertvalue {i64, i1} %t2, i1 %ooo, 1997 ret {i64, i1} %t998}999 1000; Make sure we select an INC for both the data use and the flag use.1001define i32 @incovfselectstore(i32 %v1, i32 %v2, ptr %x) {1002; CHECK-LABEL: incovfselectstore:1003; CHECK: ## %bb.0:1004; CHECK-NEXT: movl %esi, %eax1005; CHECK-NEXT: movl %edi, %ecx1006; CHECK-NEXT: incl %ecx1007; CHECK-NEXT: cmovol %edi, %eax1008; CHECK-NEXT: movl %ecx, (%rdx)1009; CHECK-NEXT: retq1010 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 1)1011 %obit = extractvalue {i32, i1} %t, 11012 %ret = select i1 %obit, i32 %v1, i32 %v21013 %val = extractvalue {i32, i1} %t, 01014 store i32 %val, ptr %x1015 ret i32 %ret1016}1017 1018; Make sure we select a DEC for both the data use and the flag use.1019define i32 @decovfselectstore(i32 %v1, i32 %v2, ptr %x) {1020; GENERIC-LABEL: decovfselectstore:1021; GENERIC: ## %bb.0:1022; GENERIC-NEXT: movl %esi, %eax1023; GENERIC-NEXT: movl %edi, %ecx1024; GENERIC-NEXT: decl %ecx1025; GENERIC-NEXT: cmovol %edi, %eax1026; GENERIC-NEXT: movl %ecx, (%rdx)1027; GENERIC-NEXT: retq1028;1029; FAST-LABEL: decovfselectstore:1030; FAST: ## %bb.0:1031; FAST-NEXT: movl %esi, %eax1032; FAST-NEXT: movl %edi, %ecx1033; FAST-NEXT: decl %ecx1034; FAST-NEXT: cmovol %edi, %eax1035; FAST-NEXT: movl %ecx, (%rdx)1036; FAST-NEXT: retq1037;1038; KNL-LABEL: decovfselectstore:1039; KNL: ## %bb.0:1040; KNL-NEXT: movl %esi, %eax1041; KNL-NEXT: movl %edi, %ecx1042; KNL-NEXT: addl $-1, %ecx1043; KNL-NEXT: cmovol %edi, %eax1044; KNL-NEXT: movl %ecx, (%rdx)1045; KNL-NEXT: retq1046 %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 1)1047 %obit = extractvalue {i32, i1} %t, 11048 %ret = select i1 %obit, i32 %v1, i32 %v21049 %val = extractvalue {i32, i1} %t, 01050 store i32 %val, ptr %x1051 ret i32 %ret1052}1053 1054declare {i8, i1} @llvm.sadd.with.overflow.i8 (i8, i8 ) nounwind readnone1055declare {i16, i1} @llvm.sadd.with.overflow.i16(i16, i16) nounwind readnone1056declare {i32, i1} @llvm.sadd.with.overflow.i32(i32, i32) nounwind readnone1057declare {i64, i1} @llvm.sadd.with.overflow.i64(i64, i64) nounwind readnone1058declare {i8, i1} @llvm.uadd.with.overflow.i8 (i8, i8 ) nounwind readnone1059declare {i16, i1} @llvm.uadd.with.overflow.i16(i16, i16) nounwind readnone1060declare {i32, i1} @llvm.uadd.with.overflow.i32(i32, i32) nounwind readnone1061declare {i64, i1} @llvm.uadd.with.overflow.i64(i64, i64) nounwind readnone1062declare {i32, i1} @llvm.ssub.with.overflow.i32(i32, i32) nounwind readnone1063declare {i64, i1} @llvm.ssub.with.overflow.i64(i64, i64) nounwind readnone1064declare {i32, i1} @llvm.usub.with.overflow.i32(i32, i32) nounwind readnone1065declare {i64, i1} @llvm.usub.with.overflow.i64(i64, i64) nounwind readnone1066 1067!0 = !{!"branch_weights", i32 0, i32 2147483647}1068