418 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=i686-unknown-unknown | FileCheck %s --check-prefixes=X863; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s --check-prefixes=X644 5%WideUInt32 = type { i32, i32 }6 7define void @PR25858_i32(ptr sret(%WideUInt32), ptr, ptr) nounwind {8; X86-LABEL: PR25858_i32:9; X86: # %bb.0: # %top10; X86-NEXT: pushl %esi11; X86-NEXT: movl {{[0-9]+}}(%esp), %eax12; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx13; X86-NEXT: movl {{[0-9]+}}(%esp), %edx14; X86-NEXT: movl (%edx), %esi15; X86-NEXT: movl 4(%edx), %edx16; X86-NEXT: subl (%ecx), %esi17; X86-NEXT: sbbl 4(%ecx), %edx18; X86-NEXT: movl %edx, 4(%eax)19; X86-NEXT: movl %esi, (%eax)20; X86-NEXT: popl %esi21; X86-NEXT: retl $422;23; X64-LABEL: PR25858_i32:24; X64: # %bb.0: # %top25; X64-NEXT: movq %rdi, %rax26; X64-NEXT: movl (%rsi), %ecx27; X64-NEXT: movl 4(%rsi), %esi28; X64-NEXT: subl (%rdx), %ecx29; X64-NEXT: sbbl 4(%rdx), %esi30; X64-NEXT: movl %esi, 4(%rdi)31; X64-NEXT: movl %ecx, (%rdi)32; X64-NEXT: retq33top:34 %3 = load i32, ptr %1, align 435 %4 = load i32, ptr %2, align 436 %5 = sub i32 %3, %437 %6 = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %3, i32 %4)38 %7 = extractvalue { i32, i1 } %6, 139 %8 = getelementptr inbounds %WideUInt32, ptr %1, i32 0, i32 140 %9 = load i32, ptr %8, align 841 %10 = getelementptr inbounds %WideUInt32, ptr %2, i32 0, i32 142 %11 = load i32, ptr %10, align 843 %12 = sub i32 %9, %1144 %.neg1 = sext i1 %7 to i3245 %13 = add i32 %12, %.neg146 %14 = insertvalue %WideUInt32 undef, i32 %5, 047 %15 = insertvalue %WideUInt32 %14, i32 %13, 148 store %WideUInt32 %15, ptr %0, align 449 ret void50}51 52declare { i32, i1 } @llvm.usub.with.overflow.i32(i32, i32)53 54%WideUInt64 = type { i64, i64 }55 56define void @PR25858_i64(ptr sret(%WideUInt64), ptr, ptr) nounwind {57; X86-LABEL: PR25858_i64:58; X86: # %bb.0: # %top59; X86-NEXT: pushl %ebx60; X86-NEXT: pushl %edi61; X86-NEXT: pushl %esi62; X86-NEXT: movl {{[0-9]+}}(%esp), %eax63; X86-NEXT: movl {{[0-9]+}}(%esp), %ebx64; X86-NEXT: movl {{[0-9]+}}(%esp), %edi65; X86-NEXT: movl (%edi), %edx66; X86-NEXT: movl 4(%edi), %esi67; X86-NEXT: movl 12(%edi), %ecx68; X86-NEXT: movl 8(%edi), %edi69; X86-NEXT: subl 8(%ebx), %edi70; X86-NEXT: sbbl 12(%ebx), %ecx71; X86-NEXT: subl (%ebx), %edx72; X86-NEXT: sbbl 4(%ebx), %esi73; X86-NEXT: sbbl $0, %edi74; X86-NEXT: sbbl $0, %ecx75; X86-NEXT: movl %edx, (%eax)76; X86-NEXT: movl %esi, 4(%eax)77; X86-NEXT: movl %edi, 8(%eax)78; X86-NEXT: movl %ecx, 12(%eax)79; X86-NEXT: popl %esi80; X86-NEXT: popl %edi81; X86-NEXT: popl %ebx82; X86-NEXT: retl $483;84; X64-LABEL: PR25858_i64:85; X64: # %bb.0: # %top86; X64-NEXT: movq %rdi, %rax87; X64-NEXT: movq (%rsi), %rcx88; X64-NEXT: movq 8(%rsi), %rsi89; X64-NEXT: subq (%rdx), %rcx90; X64-NEXT: sbbq 8(%rdx), %rsi91; X64-NEXT: movq %rsi, 8(%rdi)92; X64-NEXT: movq %rcx, (%rdi)93; X64-NEXT: retq94top:95 %3 = load i64, ptr %1, align 896 %4 = load i64, ptr %2, align 897 %5 = sub i64 %3, %498 %6 = call { i64, i1 } @llvm.usub.with.overflow.i64(i64 %3, i64 %4)99 %7 = extractvalue { i64, i1 } %6, 1100 %8 = getelementptr inbounds %WideUInt64, ptr %1, i64 0, i32 1101 %9 = load i64, ptr %8, align 8102 %10 = getelementptr inbounds %WideUInt64, ptr %2, i64 0, i32 1103 %11 = load i64, ptr %10, align 8104 %12 = sub i64 %9, %11105 %.neg1 = sext i1 %7 to i64106 %13 = add i64 %12, %.neg1107 %14 = insertvalue %WideUInt64 undef, i64 %5, 0108 %15 = insertvalue %WideUInt64 %14, i64 %13, 1109 store %WideUInt64 %15, ptr %0, align 8110 ret void111}112 113declare { i64, i1 } @llvm.usub.with.overflow.i64(i64, i64)114 115; PR24545 less_than_ideal()116define i8 @PR24545(i32, i32, ptr nocapture readonly) {117; X86-LABEL: PR24545:118; X86: # %bb.0:119; X86-NEXT: movl {{[0-9]+}}(%esp), %eax120; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx121; X86-NEXT: movl {{[0-9]+}}(%esp), %edx122; X86-NEXT: cmpl (%ecx), %edx123; X86-NEXT: sbbl 4(%ecx), %eax124; X86-NEXT: setb %al125; X86-NEXT: retl126;127; X64-LABEL: PR24545:128; X64: # %bb.0:129; X64-NEXT: cmpl (%rdx), %edi130; X64-NEXT: sbbl 4(%rdx), %esi131; X64-NEXT: setb %al132; X64-NEXT: retq133 %4 = load i32, ptr %2134 %5 = icmp ugt i32 %4, %0135 %6 = zext i1 %5 to i8136 %7 = getelementptr inbounds i32, ptr %2, i32 1137 %8 = load i32, ptr %7138 %9 = tail call { i8, i32 } @llvm.x86.subborrow.32(i8 %6, i32 %1, i32 %8)139 %10 = extractvalue { i8, i32 } %9, 0140 %11 = icmp ne i8 %10, 0141 %12 = zext i1 %11 to i8142 ret i8 %12143}144 145define i32 @PR40483_sub1(ptr, i32) nounwind {146; X86-LABEL: PR40483_sub1:147; X86: # %bb.0:148; X86-NEXT: movl {{[0-9]+}}(%esp), %eax149; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx150; X86-NEXT: subl %eax, (%ecx)151; X86-NEXT: xorl %eax, %eax152; X86-NEXT: retl153;154; X64-LABEL: PR40483_sub1:155; X64: # %bb.0:156; X64-NEXT: subl %esi, (%rdi)157; X64-NEXT: xorl %eax, %eax158; X64-NEXT: retq159 %3 = load i32, ptr %0, align 4160 %4 = tail call { i8, i32 } @llvm.x86.subborrow.32(i8 0, i32 %3, i32 %1)161 %5 = extractvalue { i8, i32 } %4, 1162 store i32 %5, ptr %0, align 4163 %6 = sub i32 %1, %3164 %7 = add i32 %6, %5165 ret i32 %7166}167 168define i32 @PR40483_sub2(ptr, i32) nounwind {169; X86-LABEL: PR40483_sub2:170; X86: # %bb.0:171; X86-NEXT: movl {{[0-9]+}}(%esp), %eax172; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx173; X86-NEXT: subl %eax, (%ecx)174; X86-NEXT: xorl %eax, %eax175; X86-NEXT: retl176;177; X64-LABEL: PR40483_sub2:178; X64: # %bb.0:179; X64-NEXT: subl %esi, (%rdi)180; X64-NEXT: xorl %eax, %eax181; X64-NEXT: retq182 %3 = load i32, ptr %0, align 4183 %4 = sub i32 %3, %1184 %5 = tail call { i8, i32 } @llvm.x86.subborrow.32(i8 0, i32 %3, i32 %1)185 %6 = extractvalue { i8, i32 } %5, 1186 store i32 %6, ptr %0, align 4187 %7 = sub i32 %4, %6188 ret i32 %7189}190 191define i32 @PR40483_sub3(ptr, i32) nounwind {192; X86-LABEL: PR40483_sub3:193; X86: # %bb.0:194; X86-NEXT: pushl %esi195; X86-NEXT: movl {{[0-9]+}}(%esp), %eax196; X86-NEXT: movl (%eax), %edx197; X86-NEXT: movl {{[0-9]+}}(%esp), %esi198; X86-NEXT: movl %edx, %ecx199; X86-NEXT: subl %esi, %ecx200; X86-NEXT: subl %esi, %edx201; X86-NEXT: movl %edx, (%eax)202; X86-NEXT: jae .LBB5_1203; X86-NEXT: # %bb.2:204; X86-NEXT: xorl %eax, %eax205; X86-NEXT: popl %esi206; X86-NEXT: retl207; X86-NEXT: .LBB5_1:208; X86-NEXT: movl %ecx, %eax209; X86-NEXT: negl %eax210; X86-NEXT: orl %ecx, %eax211; X86-NEXT: popl %esi212; X86-NEXT: retl213;214; X64-LABEL: PR40483_sub3:215; X64: # %bb.0:216; X64-NEXT: movl (%rdi), %ecx217; X64-NEXT: movl %ecx, %eax218; X64-NEXT: subl %esi, %eax219; X64-NEXT: movl %eax, %edx220; X64-NEXT: negl %edx221; X64-NEXT: orl %eax, %edx222; X64-NEXT: xorl %eax, %eax223; X64-NEXT: subl %esi, %ecx224; X64-NEXT: movl %ecx, (%rdi)225; X64-NEXT: cmovael %edx, %eax226; X64-NEXT: retq227 %3 = load i32, ptr %0, align 8228 %4 = tail call { i8, i32 } @llvm.x86.subborrow.32(i8 0, i32 %3, i32 %1)229 %5 = extractvalue { i8, i32 } %4, 1230 store i32 %5, ptr %0, align 8231 %6 = extractvalue { i8, i32 } %4, 0232 %7 = icmp eq i8 %6, 0233 %8 = sub i32 %1, %3234 %9 = or i32 %5, %8235 %10 = select i1 %7, i32 %9, i32 0236 ret i32 %10237}238 239define i32 @PR40483_sub4(ptr, i32) nounwind {240; X86-LABEL: PR40483_sub4:241; X86: # %bb.0:242; X86-NEXT: movl {{[0-9]+}}(%esp), %edx243; X86-NEXT: movl (%edx), %ecx244; X86-NEXT: xorl %eax, %eax245; X86-NEXT: subl {{[0-9]+}}(%esp), %ecx246; X86-NEXT: movl %ecx, (%edx)247; X86-NEXT: jae .LBB6_2248; X86-NEXT: # %bb.1:249; X86-NEXT: movl %ecx, %eax250; X86-NEXT: .LBB6_2:251; X86-NEXT: retl252;253; X64-LABEL: PR40483_sub4:254; X64: # %bb.0:255; X64-NEXT: movl (%rdi), %eax256; X64-NEXT: xorl %ecx, %ecx257; X64-NEXT: subl %esi, %eax258; X64-NEXT: movl %eax, (%rdi)259; X64-NEXT: cmovael %ecx, %eax260; X64-NEXT: retq261 %3 = load i32, ptr %0, align 8262 %4 = tail call { i8, i32 } @llvm.x86.subborrow.32(i8 0, i32 %3, i32 %1)263 %5 = extractvalue { i8, i32 } %4, 1264 store i32 %5, ptr %0, align 8265 %6 = extractvalue { i8, i32 } %4, 0266 %7 = icmp eq i8 %6, 0267 %8 = sub i32 %3, %1268 %9 = or i32 %5, %8269 %10 = select i1 %7, i32 0, i32 %9270 ret i32 %10271}272 273; Verify that a bogus cmov is simplified.274 275define i32 @PR40483_sub5(ptr, i32) nounwind {276; X86-LABEL: PR40483_sub5:277; X86: # %bb.0:278; X86-NEXT: movl {{[0-9]+}}(%esp), %eax279; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx280; X86-NEXT: subl %eax, (%ecx)281; X86-NEXT: xorl %eax, %eax282; X86-NEXT: retl283;284; X64-LABEL: PR40483_sub5:285; X64: # %bb.0:286; X64-NEXT: subl %esi, (%rdi)287; X64-NEXT: xorl %eax, %eax288; X64-NEXT: retq289 %3 = load i32, ptr %0, align 8290 %4 = tail call { i8, i32 } @llvm.x86.subborrow.32(i8 0, i32 %3, i32 %1)291 %5 = extractvalue { i8, i32 } %4, 1292 store i32 %5, ptr %0, align 8293 %6 = extractvalue { i8, i32 } %4, 0294 %7 = icmp eq i8 %6, 0295 %8 = sub i32 %1, %3296 %9 = add i32 %8, %5297 %10 = select i1 %7, i32 %9, i32 0298 ret i32 %10299}300 301define i32 @PR40483_sub6(ptr, i32) nounwind {302; X86-LABEL: PR40483_sub6:303; X86: # %bb.0:304; X86-NEXT: movl {{[0-9]+}}(%esp), %edx305; X86-NEXT: movl (%edx), %ecx306; X86-NEXT: xorl %eax, %eax307; X86-NEXT: subl {{[0-9]+}}(%esp), %ecx308; X86-NEXT: movl %ecx, (%edx)309; X86-NEXT: jae .LBB8_2310; X86-NEXT: # %bb.1:311; X86-NEXT: leal (%ecx,%ecx), %eax312; X86-NEXT: .LBB8_2:313; X86-NEXT: retl314;315; X64-LABEL: PR40483_sub6:316; X64: # %bb.0:317; X64-NEXT: movl (%rdi), %eax318; X64-NEXT: xorl %ecx, %ecx319; X64-NEXT: subl %esi, %eax320; X64-NEXT: movl %eax, (%rdi)321; X64-NEXT: leal (%rax,%rax), %eax322; X64-NEXT: cmovael %ecx, %eax323; X64-NEXT: retq324 %3 = load i32, ptr %0, align 8325 %4 = tail call { i8, i32 } @llvm.x86.subborrow.32(i8 0, i32 %3, i32 %1)326 %5 = extractvalue { i8, i32 } %4, 1327 store i32 %5, ptr %0, align 8328 %6 = extractvalue { i8, i32 } %4, 0329 %7 = icmp eq i8 %6, 0330 %8 = sub i32 %3, %1331 %9 = add i32 %8, %5332 %10 = select i1 %7, i32 0, i32 %9333 ret i32 %10334}335 336define i32 @sbb_merge_add1(i32 %a0) nounwind {337; X86-LABEL: sbb_merge_add1:338; X86: # %bb.0:339; X86-NEXT: xorl %eax, %eax340; X86-NEXT: cmpl $42, {{[0-9]+}}(%esp)341; X86-NEXT: setb %al342; X86-NEXT: pushl %eax343; X86-NEXT: calll use@PLT344; X86-NEXT: addl $4, %esp345; X86-NEXT: xorl %eax, %eax346; X86-NEXT: retl347;348; X64-LABEL: sbb_merge_add1:349; X64: # %bb.0:350; X64-NEXT: pushq %rax351; X64-NEXT: xorl %eax, %eax352; X64-NEXT: cmpl $42, %edi353; X64-NEXT: setb %al354; X64-NEXT: movl %eax, %edi355; X64-NEXT: callq use@PLT356; X64-NEXT: xorl %eax, %eax357; X64-NEXT: popq %rcx358; X64-NEXT: retq359 %sbb = tail call { i8, i32 } @llvm.x86.subborrow.32(i8 0, i32 %a0, i32 42)360 %borrow = extractvalue { i8, i32 } %sbb, 0361 call void @use(i8 %borrow)362 %diff = extractvalue { i8, i32 } %sbb, 1363 %add = add i32 %a0, -42364 %result = xor i32 %diff, %add365 ret i32 %result366}367 368define i32 @sbb_merge_add2(i32 %a0) nounwind {369; X86-LABEL: sbb_merge_add2:370; X86: # %bb.0:371; X86-NEXT: pushl %edi372; X86-NEXT: pushl %esi373; X86-NEXT: movl $42, %edi374; X86-NEXT: xorl %eax, %eax375; X86-NEXT: subl {{[0-9]+}}(%esp), %edi376; X86-NEXT: setb %al377; X86-NEXT: movl %edi, %esi378; X86-NEXT: negl %esi379; X86-NEXT: pushl %eax380; X86-NEXT: calll use@PLT381; X86-NEXT: addl $4, %esp382; X86-NEXT: xorl %edi, %esi383; X86-NEXT: movl %esi, %eax384; X86-NEXT: popl %esi385; X86-NEXT: popl %edi386; X86-NEXT: retl387;388; X64-LABEL: sbb_merge_add2:389; X64: # %bb.0:390; X64-NEXT: pushq %rbp391; X64-NEXT: pushq %rbx392; X64-NEXT: pushq %rax393; X64-NEXT: movl $42, %ebp394; X64-NEXT: xorl %eax, %eax395; X64-NEXT: subl %edi, %ebp396; X64-NEXT: setb %al397; X64-NEXT: movl %ebp, %ebx398; X64-NEXT: negl %ebx399; X64-NEXT: movl %eax, %edi400; X64-NEXT: callq use@PLT401; X64-NEXT: xorl %ebp, %ebx402; X64-NEXT: movl %ebx, %eax403; X64-NEXT: addq $8, %rsp404; X64-NEXT: popq %rbx405; X64-NEXT: popq %rbp406; X64-NEXT: retq407 %sbb = tail call { i8, i32 } @llvm.x86.subborrow.32(i8 0, i32 42, i32 %a0)408 %borrow = extractvalue { i8, i32 } %sbb, 0409 call void @use(i8 %borrow)410 %diff = extractvalue { i8, i32 } %sbb, 1411 %add = add i32 %a0, -42412 %result = xor i32 %diff, %add413 ret i32 %result414}415 416declare { i8, i32 } @llvm.x86.subborrow.32(i8, i32, i32)417declare void @use(i8)418