261 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=x86_64-- | FileCheck %s3 4; CodeGenPrepare is expected to form overflow intrinsics to improve DAG/isel.5 6define i1 @usubo_ult_i64(i64 %x, i64 %y, ptr %p) nounwind {7; CHECK-LABEL: usubo_ult_i64:8; CHECK: # %bb.0:9; CHECK-NEXT: subq %rsi, %rdi10; CHECK-NEXT: setb %al11; CHECK-NEXT: movq %rdi, (%rdx)12; CHECK-NEXT: retq13 %s = sub i64 %x, %y14 store i64 %s, ptr %p15 %ov = icmp ult i64 %x, %y16 ret i1 %ov17}18 19; Verify insertion point for single-BB. Toggle predicate.20 21define i1 @usubo_ugt_i32(i32 %x, i32 %y, ptr %p) nounwind {22; CHECK-LABEL: usubo_ugt_i32:23; CHECK: # %bb.0:24; CHECK-NEXT: subl %esi, %edi25; CHECK-NEXT: setb %al26; CHECK-NEXT: movl %edi, (%rdx)27; CHECK-NEXT: retq28 %ov = icmp ugt i32 %y, %x29 %s = sub i32 %x, %y30 store i32 %s, ptr %p31 ret i1 %ov32}33 34; Constant operand should match.35 36define i1 @usubo_ugt_constant_op0_i8(i8 %x, ptr %p) nounwind {37; CHECK-LABEL: usubo_ugt_constant_op0_i8:38; CHECK: # %bb.0:39; CHECK-NEXT: movb $42, %cl40; CHECK-NEXT: subb %dil, %cl41; CHECK-NEXT: setb %al42; CHECK-NEXT: movb %cl, (%rsi)43; CHECK-NEXT: retq44 %s = sub i8 42, %x45 %ov = icmp ugt i8 %x, 4246 store i8 %s, ptr %p47 ret i1 %ov48}49 50; Compare with constant operand 0 is canonicalized by commuting, but verify match for non-canonical form.51 52define i1 @usubo_ult_constant_op0_i16(i16 %x, ptr %p) nounwind {53; CHECK-LABEL: usubo_ult_constant_op0_i16:54; CHECK: # %bb.0:55; CHECK-NEXT: movw $43, %cx56; CHECK-NEXT: subw %di, %cx57; CHECK-NEXT: setb %al58; CHECK-NEXT: movw %cx, (%rsi)59; CHECK-NEXT: retq60 %s = sub i16 43, %x61 %ov = icmp ult i16 43, %x62 store i16 %s, ptr %p63 ret i1 %ov64}65 66; Subtract with constant operand 1 is canonicalized to add.67 68define i1 @usubo_ult_constant_op1_i16(i16 %x, ptr %p) nounwind {69; CHECK-LABEL: usubo_ult_constant_op1_i16:70; CHECK: # %bb.0:71; CHECK-NEXT: subw $44, %di72; CHECK-NEXT: setb %al73; CHECK-NEXT: movw %di, (%rsi)74; CHECK-NEXT: retq75 %s = add i16 %x, -4476 %ov = icmp ult i16 %x, 4477 store i16 %s, ptr %p78 ret i1 %ov79}80 81define i1 @usubo_ugt_constant_op1_i8(i8 %x, ptr %p) nounwind {82; CHECK-LABEL: usubo_ugt_constant_op1_i8:83; CHECK: # %bb.0:84; CHECK-NEXT: subb $45, %dil85; CHECK-NEXT: setb %al86; CHECK-NEXT: movb %dil, (%rsi)87; CHECK-NEXT: retq88 %ov = icmp ugt i8 45, %x89 %s = add i8 %x, -4590 store i8 %s, ptr %p91 ret i1 %ov92}93 94; Special-case: subtract 1 changes the compare predicate and constant.95 96define i1 @usubo_eq_constant1_op1_i32(i32 %x, ptr %p) nounwind {97; CHECK-LABEL: usubo_eq_constant1_op1_i32:98; CHECK: # %bb.0:99; CHECK-NEXT: subl $1, %edi100; CHECK-NEXT: setb %al101; CHECK-NEXT: movl %edi, (%rsi)102; CHECK-NEXT: retq103 %s = add i32 %x, -1104 %ov = icmp eq i32 %x, 0105 store i32 %s, ptr %p106 ret i1 %ov107}108 109; Special-case: subtract from 0 (negate) changes the compare predicate.110 111define i1 @usubo_ne_constant0_op1_i32(i32 %x, ptr %p) {112; CHECK-LABEL: usubo_ne_constant0_op1_i32:113; CHECK: # %bb.0:114; CHECK-NEXT: negl %edi115; CHECK-NEXT: setb %al116; CHECK-NEXT: movl %edi, (%rsi)117; CHECK-NEXT: retq118 %s = sub i32 0, %x119 %ov = icmp ne i32 %x, 0120 store i32 %s, ptr %p121 ret i1 %ov122}123 124; This used to verify insertion point for multi-BB, but now we just bail out.125 126declare void @call(i1)127 128define i1 @usubo_ult_sub_dominates_i64(i64 %x, i64 %y, ptr %p, i1 %cond) nounwind {129; CHECK-LABEL: usubo_ult_sub_dominates_i64:130; CHECK: # %bb.0: # %entry131; CHECK-NEXT: testb $1, %cl132; CHECK-NEXT: je .LBB8_2133; CHECK-NEXT: # %bb.1: # %t134; CHECK-NEXT: movq %rdi, %rax135; CHECK-NEXT: subq %rsi, %rax136; CHECK-NEXT: movq %rax, (%rdx)137; CHECK-NEXT: testb $1, %cl138; CHECK-NEXT: je .LBB8_2139; CHECK-NEXT: # %bb.3: # %end140; CHECK-NEXT: cmpq %rsi, %rdi141; CHECK-NEXT: setb %al142; CHECK-NEXT: retq143; CHECK-NEXT: .LBB8_2: # %f144; CHECK-NEXT: movl %ecx, %eax145; CHECK-NEXT: retq146entry:147 br i1 %cond, label %t, label %f148 149t:150 %s = sub i64 %x, %y151 store i64 %s, ptr %p152 br i1 %cond, label %end, label %f153 154f:155 ret i1 %cond156 157end:158 %ov = icmp ult i64 %x, %y159 ret i1 %ov160}161 162define i1 @usubo_ult_cmp_dominates_i64(i64 %x, i64 %y, ptr %p, i1 %cond) nounwind {163; CHECK-LABEL: usubo_ult_cmp_dominates_i64:164; CHECK: # %bb.0: # %entry165; CHECK-NEXT: pushq %rbp166; CHECK-NEXT: pushq %r15167; CHECK-NEXT: pushq %r14168; CHECK-NEXT: pushq %rbx169; CHECK-NEXT: pushq %rax170; CHECK-NEXT: movl %ecx, %ebp171; CHECK-NEXT: testb $1, %bpl172; CHECK-NEXT: je .LBB9_2173; CHECK-NEXT: # %bb.1: # %t174; CHECK-NEXT: movq %rdx, %rbx175; CHECK-NEXT: movq %rdi, %r14176; CHECK-NEXT: xorl %edi, %edi177; CHECK-NEXT: cmpq %rsi, %r14178; CHECK-NEXT: setb %dil179; CHECK-NEXT: movq %rsi, %r15180; CHECK-NEXT: callq call@PLT181; CHECK-NEXT: subq %r15, %r14182; CHECK-NEXT: jae .LBB9_2183; CHECK-NEXT: # %bb.4: # %end184; CHECK-NEXT: setb %al185; CHECK-NEXT: movq %r14, (%rbx)186; CHECK-NEXT: jmp .LBB9_3187; CHECK-NEXT: .LBB9_2: # %f188; CHECK-NEXT: movl %ebp, %eax189; CHECK-NEXT: .LBB9_3: # %f190; CHECK-NEXT: addq $8, %rsp191; CHECK-NEXT: popq %rbx192; CHECK-NEXT: popq %r14193; CHECK-NEXT: popq %r15194; CHECK-NEXT: popq %rbp195; CHECK-NEXT: retq196entry:197 br i1 %cond, label %t, label %f198 199t:200 %ov = icmp ult i64 %x, %y201 call void @call(i1 %ov)202 br i1 %ov, label %end, label %f203 204f:205 ret i1 %cond206 207end:208 %s = sub i64 %x, %y209 store i64 %s, ptr %p210 ret i1 %ov211}212 213define void @PR41129(ptr %p64) {214; CHECK-LABEL: PR41129:215; CHECK: # %bb.0: # %entry216; CHECK-NEXT: movq (%rdi), %rax217; CHECK-NEXT: testq %rax, %rax218; CHECK-NEXT: je .LBB10_2219; CHECK-NEXT: # %bb.1: # %false220; CHECK-NEXT: andl $7, %eax221; CHECK-NEXT: movq %rax, (%rdi)222; CHECK-NEXT: retq223; CHECK-NEXT: .LBB10_2: # %true224; CHECK-NEXT: decq %rax225; CHECK-NEXT: movq %rax, (%rdi)226; CHECK-NEXT: retq227entry:228 %key = load i64, ptr %p64, align 8229 %cond17 = icmp eq i64 %key, 0230 br i1 %cond17, label %true, label %false231 232false:233 %andval = and i64 %key, 7234 store i64 %andval, ptr %p64235 br label %exit236 237true:238 %svalue = add i64 %key, -1239 store i64 %svalue, ptr %p64240 br label %exit241 242exit:243 ret void244}245 246define i32 @PR42571(i32 %x, i32 %y) {247; CHECK-LABEL: PR42571:248; CHECK: # %bb.0:249; CHECK-NEXT: # kill: def $edi killed $edi def $rdi250; CHECK-NEXT: leal -1(%rdi), %eax251; CHECK-NEXT: andl %edi, %eax252; CHECK-NEXT: cmpl $1, %edi253; CHECK-NEXT: cmovbl %esi, %eax254; CHECK-NEXT: retq255 %tobool = icmp eq i32 %x, 0256 %sub = add nsw i32 %x, -1257 %and = and i32 %sub, %x258 %cond = select i1 %tobool, i32 %y, i32 %and259 ret i32 %cond260}261