X86 supports i8/i16 overflow ops (except i8 multiplies), we should

generate them.  

Now we compile:

define zeroext i8 @X(i8 signext %a, i8 signext %b) nounwind ssp {
entry:
  %0 = tail call %0 @llvm.sadd.with.overflow.i8(i8 %a, i8 %b)
  %cmp = extractvalue %0 %0, 1
  br i1 %cmp, label %if.then, label %if.end

into:

_X:                                     ## @X
## BB#0:                                ## %entry
	subl	$12, %esp
	movb	16(%esp), %al
	addb	20(%esp), %al
	jo	LBB0_2

Before we were generating:

_X:                                     ## @X
## BB#0:                                ## %entry
	pushl	%ebp
	movl	%esp, %ebp
	subl	$8, %esp
	movb	12(%ebp), %al
	testb	%al, %al
	setge	%cl
	movb	8(%ebp), %dl
	testb	%dl, %dl
	setge	%ah
	cmpb	%cl, %ah
	sete	%cl
	addb	%al, %dl
	testb	%dl, %dl
	setge	%al
	cmpb	%al, %ah
	setne	%al
	andb	%cl, %al
	testb	%al, %al
	jne	LBB0_2




git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@122186 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2010-12-19 20:03:11 +00:00
parent 8dd3417384
commit a34b3cf953
2 changed files with 25 additions and 17 deletions

View File

@ -89,6 +89,7 @@ X86TargetLowering::X86TargetLowering(X86TargetMachine &TM)
TD = getTargetData(); TD = getTargetData();
// Set up the TargetLowering object. // Set up the TargetLowering object.
static MVT IntVTs[] = { MVT::i8, MVT::i16, MVT::i32, MVT::i64 };
// X86 is weird, it always uses i8 for shift amounts and setcc results. // X86 is weird, it always uses i8 for shift amounts and setcc results.
setShiftAmountType(MVT::i8); setShiftAmountType(MVT::i8);
@ -826,9 +827,8 @@ X86TargetLowering::X86TargetLowering(X86TargetMachine &TM)
} }
} }
if (Subtarget->hasSSE42()) { if (Subtarget->hasSSE42())
setOperationAction(ISD::VSETCC, MVT::v2i64, Custom); setOperationAction(ISD::VSETCC, MVT::v2i64, Custom);
}
if (!UseSoftFloat && Subtarget->hasAVX()) { if (!UseSoftFloat && Subtarget->hasAVX()) {
addRegisterClass(MVT::v8f32, X86::VR256RegisterClass); addRegisterClass(MVT::v8f32, X86::VR256RegisterClass);
@ -942,13 +942,6 @@ X86TargetLowering::X86TargetLowering(X86TargetMachine &TM)
// We want to custom lower some of our intrinsics. // We want to custom lower some of our intrinsics.
setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom); setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom);
// Add/Sub/Mul with overflow operations are custom lowered.
setOperationAction(ISD::SADDO, MVT::i32, Custom);
setOperationAction(ISD::UADDO, MVT::i32, Custom);
setOperationAction(ISD::SSUBO, MVT::i32, Custom);
setOperationAction(ISD::USUBO, MVT::i32, Custom);
setOperationAction(ISD::SMULO, MVT::i32, Custom);
setOperationAction(ISD::UMULO, MVT::i32, Custom);
// Only custom-lower 64-bit SADDO and friends on 64-bit because we don't // Only custom-lower 64-bit SADDO and friends on 64-bit because we don't
// handle type legalization for these operations here. // handle type legalization for these operations here.
@ -956,15 +949,21 @@ X86TargetLowering::X86TargetLowering(X86TargetMachine &TM)
// FIXME: We really should do custom legalization for addition and // FIXME: We really should do custom legalization for addition and
// subtraction on x86-32 once PR3203 is fixed. We really can't do much better // subtraction on x86-32 once PR3203 is fixed. We really can't do much better
// than generic legalization for 64-bit multiplication-with-overflow, though. // than generic legalization for 64-bit multiplication-with-overflow, though.
if (Subtarget->is64Bit()) { for (unsigned i = 0, e = 3+Subtarget->is64Bit(); i != e; ++i) {
setOperationAction(ISD::SADDO, MVT::i64, Custom); // Add/Sub/Mul with overflow operations are custom lowered.
setOperationAction(ISD::UADDO, MVT::i64, Custom); MVT VT = IntVTs[i];
setOperationAction(ISD::SSUBO, MVT::i64, Custom); setOperationAction(ISD::SADDO, VT, Custom);
setOperationAction(ISD::USUBO, MVT::i64, Custom); setOperationAction(ISD::UADDO, VT, Custom);
setOperationAction(ISD::SMULO, MVT::i64, Custom); setOperationAction(ISD::SSUBO, VT, Custom);
setOperationAction(ISD::UMULO, MVT::i64, Custom); setOperationAction(ISD::USUBO, VT, Custom);
setOperationAction(ISD::SMULO, VT, Custom);
setOperationAction(ISD::UMULO, VT, Custom);
} }
// There are no 8-bit 3-address imul/mul instructions
setOperationAction(ISD::SMULO, MVT::i8, Expand);
setOperationAction(ISD::UMULO, MVT::i8, Expand);
if (!Subtarget->is64Bit()) { if (!Subtarget->is64Bit()) {
// These libcalls are not available in 32-bit. // These libcalls are not available in 32-bit.
setLibcallName(RTLIB::SHL_I128, 0); setLibcallName(RTLIB::SHL_I128, 0);

View File

@ -80,6 +80,15 @@ define i1 @uaddtest6(i8 %A, i8 %B) {
; CHECK-NEXT: ret i1 %z ; CHECK-NEXT: ret i1 %z
} }
define i8 @uaddtest7(i8 %A, i8 %B) {
%x = call %overflow.result @llvm.uadd.with.overflow.i8(i8 %A, i8 %B)
%z = extractvalue %overflow.result %x, 0
ret i8 %z
; CHECK: @uaddtest7
; CHECK-NEXT: %z = add i8 %A, %B
; CHECK-NEXT: ret i8 %z
}
define i8 @umultest1(i8 %A, i1* %overflowPtr) { define i8 @umultest1(i8 %A, i1* %overflowPtr) {
%x = call %overflow.result @llvm.umul.with.overflow.i8(i8 0, i8 %A) %x = call %overflow.result @llvm.umul.with.overflow.i8(i8 0, i8 %A)