forked from OSchip/llvm-project
R600: Move add/sub with overflow out of AMDILISelLowering
Add more tests for these. llvm-svn: 211517
This commit is contained in:
parent
e54e1c3a21
commit
c4d3d3a16e
|
@ -306,6 +306,10 @@ AMDGPUTargetLowering::AMDGPUTargetLowering(TargetMachine &TM) :
|
|||
setOperationAction(ISD::UMUL_LOHI, VT, Expand);
|
||||
setOperationAction(ISD::SDIVREM, VT, Custom);
|
||||
setOperationAction(ISD::UDIVREM, VT, Custom);
|
||||
setOperationAction(ISD::ADDC, VT, Expand);
|
||||
setOperationAction(ISD::SUBC, VT, Expand);
|
||||
setOperationAction(ISD::ADDE, VT, Expand);
|
||||
setOperationAction(ISD::SUBE, VT, Expand);
|
||||
setOperationAction(ISD::SELECT, VT, Expand);
|
||||
setOperationAction(ISD::VSELECT, VT, Expand);
|
||||
setOperationAction(ISD::SELECT_CC, VT, Expand);
|
||||
|
|
|
@ -21,26 +21,7 @@ using namespace llvm;
|
|||
// TargetLowering Class Implementation Begins
|
||||
//===----------------------------------------------------------------------===//
|
||||
void AMDGPUTargetLowering::InitAMDILLowering() {
|
||||
static const MVT::SimpleValueType types[] = {
|
||||
MVT::i32,
|
||||
MVT::i64,
|
||||
MVT::v2i32,
|
||||
MVT::v4i32
|
||||
};
|
||||
|
||||
for (MVT VT : types) {
|
||||
setOperationAction(ISD::SUBE, VT, Expand);
|
||||
setOperationAction(ISD::SUBC, VT, Expand);
|
||||
setOperationAction(ISD::ADDE, VT, Expand);
|
||||
setOperationAction(ISD::ADDC, VT, Expand);
|
||||
}
|
||||
|
||||
setOperationAction(ISD::SUBC, MVT::Other, Expand);
|
||||
setOperationAction(ISD::ADDE, MVT::Other, Expand);
|
||||
setOperationAction(ISD::ADDC, MVT::Other, Expand);
|
||||
|
||||
setOperationAction(ISD::BRCOND, MVT::Other, Custom);
|
||||
|
||||
setSelectIsExpensive(true); // FIXME: This makes no sense at all
|
||||
}
|
||||
|
||||
|
|
|
@ -169,6 +169,14 @@ R600TargetLowering::R600TargetLowering(TargetMachine &TM) :
|
|||
|
||||
setOperationAction(ISD::GlobalAddress, MVT::i32, Custom);
|
||||
|
||||
const MVT ScalarIntVTs[] = { MVT::i32, MVT::i64 };
|
||||
for (MVT VT : ScalarIntVTs) {
|
||||
setOperationAction(ISD::ADDC, VT, Expand);
|
||||
setOperationAction(ISD::SUBC, VT, Expand);
|
||||
setOperationAction(ISD::ADDE, VT, Expand);
|
||||
setOperationAction(ISD::SUBE, VT, Expand);
|
||||
}
|
||||
|
||||
setBooleanContents(ZeroOrNegativeOneBooleanContent);
|
||||
setBooleanVectorContents(ZeroOrNegativeOneBooleanContent);
|
||||
setSchedulingPreference(Sched::Source);
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
; RUN: llc -march=r600 -mcpu=SI -verify-machineinstrs< %s | FileCheck -check-prefix=SI -check-prefix=FUNC %s
|
||||
; RUN: llc -march=r600 -mcpu=cypress -verify-machineinstrs< %s
|
||||
|
||||
declare { i32, i1 } @llvm.sadd.with.overflow.i32(i32, i32) nounwind readnone
|
||||
declare { i64, i1 } @llvm.sadd.with.overflow.i64(i64, i64) nounwind readnone
|
||||
|
||||
; FUNC-LABEL: @saddo_i64_zext
|
||||
define void @saddo_i64_zext(i64 addrspace(1)* %out, i64 %a, i64 %b) nounwind {
|
||||
%sadd = call { i64, i1 } @llvm.sadd.with.overflow.i64(i64 %a, i64 %b) nounwind
|
||||
%val = extractvalue { i64, i1 } %sadd, 0
|
||||
%carry = extractvalue { i64, i1 } %sadd, 1
|
||||
%ext = zext i1 %carry to i64
|
||||
%add2 = add i64 %val, %ext
|
||||
store i64 %add2, i64 addrspace(1)* %out, align 8
|
||||
ret void
|
||||
}
|
||||
|
||||
; FUNC-LABEL: @s_saddo_i32
|
||||
define void @s_saddo_i32(i32 addrspace(1)* %out, i1 addrspace(1)* %carryout, i32 %a, i32 %b) nounwind {
|
||||
%sadd = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %a, i32 %b) nounwind
|
||||
%val = extractvalue { i32, i1 } %sadd, 0
|
||||
%carry = extractvalue { i32, i1 } %sadd, 1
|
||||
store i32 %val, i32 addrspace(1)* %out, align 4
|
||||
store i1 %carry, i1 addrspace(1)* %carryout
|
||||
ret void
|
||||
}
|
||||
|
||||
; FUNC-LABEL: @v_saddo_i32
|
||||
define void @v_saddo_i32(i32 addrspace(1)* %out, i1 addrspace(1)* %carryout, i32 addrspace(1)* %aptr, i32 addrspace(1)* %bptr) nounwind {
|
||||
%a = load i32 addrspace(1)* %aptr, align 4
|
||||
%b = load i32 addrspace(1)* %bptr, align 4
|
||||
%sadd = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %a, i32 %b) nounwind
|
||||
%val = extractvalue { i32, i1 } %sadd, 0
|
||||
%carry = extractvalue { i32, i1 } %sadd, 1
|
||||
store i32 %val, i32 addrspace(1)* %out, align 4
|
||||
store i1 %carry, i1 addrspace(1)* %carryout
|
||||
ret void
|
||||
}
|
||||
|
||||
; FUNC-LABEL: @s_saddo_i64
|
||||
define void @s_saddo_i64(i64 addrspace(1)* %out, i1 addrspace(1)* %carryout, i64 %a, i64 %b) nounwind {
|
||||
%sadd = call { i64, i1 } @llvm.sadd.with.overflow.i64(i64 %a, i64 %b) nounwind
|
||||
%val = extractvalue { i64, i1 } %sadd, 0
|
||||
%carry = extractvalue { i64, i1 } %sadd, 1
|
||||
store i64 %val, i64 addrspace(1)* %out, align 8
|
||||
store i1 %carry, i1 addrspace(1)* %carryout
|
||||
ret void
|
||||
}
|
||||
|
||||
; FUNC-LABEL: @v_saddo_i64
|
||||
; SI: V_ADD_I32
|
||||
; SI: V_ADDC_U32
|
||||
define void @v_saddo_i64(i64 addrspace(1)* %out, i1 addrspace(1)* %carryout, i64 addrspace(1)* %aptr, i64 addrspace(1)* %bptr) nounwind {
|
||||
%a = load i64 addrspace(1)* %aptr, align 4
|
||||
%b = load i64 addrspace(1)* %bptr, align 4
|
||||
%sadd = call { i64, i1 } @llvm.sadd.with.overflow.i64(i64 %a, i64 %b) nounwind
|
||||
%val = extractvalue { i64, i1 } %sadd, 0
|
||||
%carry = extractvalue { i64, i1 } %sadd, 1
|
||||
store i64 %val, i64 addrspace(1)* %out, align 8
|
||||
store i1 %carry, i1 addrspace(1)* %carryout
|
||||
ret void
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
; RUN: llc -march=r600 -mcpu=SI -verify-machineinstrs< %s | FileCheck -check-prefix=SI -check-prefix=FUNC %s
|
||||
; RUN: llc -march=r600 -mcpu=cypress -verify-machineinstrs< %s
|
||||
|
||||
declare { i32, i1 } @llvm.ssub.with.overflow.i32(i32, i32) nounwind readnone
|
||||
declare { i64, i1 } @llvm.ssub.with.overflow.i64(i64, i64) nounwind readnone
|
||||
|
||||
; FUNC-LABEL: @ssubo_i64_zext
|
||||
define void @ssubo_i64_zext(i64 addrspace(1)* %out, i64 %a, i64 %b) nounwind {
|
||||
%ssub = call { i64, i1 } @llvm.ssub.with.overflow.i64(i64 %a, i64 %b) nounwind
|
||||
%val = extractvalue { i64, i1 } %ssub, 0
|
||||
%carry = extractvalue { i64, i1 } %ssub, 1
|
||||
%ext = zext i1 %carry to i64
|
||||
%add2 = add i64 %val, %ext
|
||||
store i64 %add2, i64 addrspace(1)* %out, align 8
|
||||
ret void
|
||||
}
|
||||
|
||||
; FUNC-LABEL: @s_ssubo_i32
|
||||
define void @s_ssubo_i32(i32 addrspace(1)* %out, i1 addrspace(1)* %carryout, i32 %a, i32 %b) nounwind {
|
||||
%ssub = call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %a, i32 %b) nounwind
|
||||
%val = extractvalue { i32, i1 } %ssub, 0
|
||||
%carry = extractvalue { i32, i1 } %ssub, 1
|
||||
store i32 %val, i32 addrspace(1)* %out, align 4
|
||||
store i1 %carry, i1 addrspace(1)* %carryout
|
||||
ret void
|
||||
}
|
||||
|
||||
; FUNC-LABEL: @v_ssubo_i32
|
||||
define void @v_ssubo_i32(i32 addrspace(1)* %out, i1 addrspace(1)* %carryout, i32 addrspace(1)* %aptr, i32 addrspace(1)* %bptr) nounwind {
|
||||
%a = load i32 addrspace(1)* %aptr, align 4
|
||||
%b = load i32 addrspace(1)* %bptr, align 4
|
||||
%ssub = call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %a, i32 %b) nounwind
|
||||
%val = extractvalue { i32, i1 } %ssub, 0
|
||||
%carry = extractvalue { i32, i1 } %ssub, 1
|
||||
store i32 %val, i32 addrspace(1)* %out, align 4
|
||||
store i1 %carry, i1 addrspace(1)* %carryout
|
||||
ret void
|
||||
}
|
||||
|
||||
; FUNC-LABEL: @s_ssubo_i64
|
||||
; SI: S_SUB_I32
|
||||
; SI: S_SUBB_U32
|
||||
define void @s_ssubo_i64(i64 addrspace(1)* %out, i1 addrspace(1)* %carryout, i64 %a, i64 %b) nounwind {
|
||||
%ssub = call { i64, i1 } @llvm.ssub.with.overflow.i64(i64 %a, i64 %b) nounwind
|
||||
%val = extractvalue { i64, i1 } %ssub, 0
|
||||
%carry = extractvalue { i64, i1 } %ssub, 1
|
||||
store i64 %val, i64 addrspace(1)* %out, align 8
|
||||
store i1 %carry, i1 addrspace(1)* %carryout
|
||||
ret void
|
||||
}
|
||||
|
||||
; FUNC-LABEL: @v_ssubo_i64
|
||||
; SI: V_SUB_I32_e32
|
||||
; SI: V_SUBB_U32_e32
|
||||
define void @v_ssubo_i64(i64 addrspace(1)* %out, i1 addrspace(1)* %carryout, i64 addrspace(1)* %aptr, i64 addrspace(1)* %bptr) nounwind {
|
||||
%a = load i64 addrspace(1)* %aptr, align 4
|
||||
%b = load i64 addrspace(1)* %bptr, align 4
|
||||
%ssub = call { i64, i1 } @llvm.ssub.with.overflow.i64(i64 %a, i64 %b) nounwind
|
||||
%val = extractvalue { i64, i1 } %ssub, 0
|
||||
%carry = extractvalue { i64, i1 } %ssub, 1
|
||||
store i64 %val, i64 addrspace(1)* %out, align 8
|
||||
store i1 %carry, i1 addrspace(1)* %carryout
|
||||
ret void
|
||||
}
|
|
@ -1,8 +1,10 @@
|
|||
; RUN: llc -march=r600 -mcpu=SI -verify-machineinstrs< %s | FileCheck -check-prefix=SI %s
|
||||
; RUN: llc -march=r600 -mcpu=SI -verify-machineinstrs< %s | FileCheck -check-prefix=SI -check-prefix=FUNC %s
|
||||
; RUN: llc -march=r600 -mcpu=cypress -verify-machineinstrs< %s
|
||||
|
||||
declare { i32, i1 } @llvm.uadd.with.overflow.i32(i32, i32) nounwind readnone
|
||||
declare { i64, i1 } @llvm.uadd.with.overflow.i64(i64, i64) nounwind readnone
|
||||
|
||||
; SI-LABEL: @uaddo_i64_zext
|
||||
; FUNC-LABEL: @uaddo_i64_zext
|
||||
; SI: ADD
|
||||
; SI: ADDC
|
||||
; SI: ADDC
|
||||
|
@ -15,3 +17,53 @@ define void @uaddo_i64_zext(i64 addrspace(1)* %out, i64 %a, i64 %b) nounwind {
|
|||
store i64 %add2, i64 addrspace(1)* %out, align 8
|
||||
ret void
|
||||
}
|
||||
|
||||
; FUNC-LABEL: @s_uaddo_i32
|
||||
; SI: S_ADD_I32
|
||||
define void @s_uaddo_i32(i32 addrspace(1)* %out, i1 addrspace(1)* %carryout, i32 %a, i32 %b) nounwind {
|
||||
%uadd = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %a, i32 %b) nounwind
|
||||
%val = extractvalue { i32, i1 } %uadd, 0
|
||||
%carry = extractvalue { i32, i1 } %uadd, 1
|
||||
store i32 %val, i32 addrspace(1)* %out, align 4
|
||||
store i1 %carry, i1 addrspace(1)* %carryout
|
||||
ret void
|
||||
}
|
||||
|
||||
; FUNC-LABEL: @v_uaddo_i32
|
||||
; SI: V_ADD_I32
|
||||
define void @v_uaddo_i32(i32 addrspace(1)* %out, i1 addrspace(1)* %carryout, i32 addrspace(1)* %aptr, i32 addrspace(1)* %bptr) nounwind {
|
||||
%a = load i32 addrspace(1)* %aptr, align 4
|
||||
%b = load i32 addrspace(1)* %bptr, align 4
|
||||
%uadd = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %a, i32 %b) nounwind
|
||||
%val = extractvalue { i32, i1 } %uadd, 0
|
||||
%carry = extractvalue { i32, i1 } %uadd, 1
|
||||
store i32 %val, i32 addrspace(1)* %out, align 4
|
||||
store i1 %carry, i1 addrspace(1)* %carryout
|
||||
ret void
|
||||
}
|
||||
|
||||
; FUNC-LABEL: @s_uaddo_i64
|
||||
; SI: S_ADD_I32
|
||||
; SI: S_ADDC_U32
|
||||
define void @s_uaddo_i64(i64 addrspace(1)* %out, i1 addrspace(1)* %carryout, i64 %a, i64 %b) nounwind {
|
||||
%uadd = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %a, i64 %b) nounwind
|
||||
%val = extractvalue { i64, i1 } %uadd, 0
|
||||
%carry = extractvalue { i64, i1 } %uadd, 1
|
||||
store i64 %val, i64 addrspace(1)* %out, align 8
|
||||
store i1 %carry, i1 addrspace(1)* %carryout
|
||||
ret void
|
||||
}
|
||||
|
||||
; FUNC-LABEL: @v_uaddo_i64
|
||||
; SI: V_ADD_I32
|
||||
; SI: V_ADDC_U32
|
||||
define void @v_uaddo_i64(i64 addrspace(1)* %out, i1 addrspace(1)* %carryout, i64 addrspace(1)* %aptr, i64 addrspace(1)* %bptr) nounwind {
|
||||
%a = load i64 addrspace(1)* %aptr, align 4
|
||||
%b = load i64 addrspace(1)* %bptr, align 4
|
||||
%uadd = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %a, i64 %b) nounwind
|
||||
%val = extractvalue { i64, i1 } %uadd, 0
|
||||
%carry = extractvalue { i64, i1 } %uadd, 1
|
||||
store i64 %val, i64 addrspace(1)* %out, align 8
|
||||
store i1 %carry, i1 addrspace(1)* %carryout
|
||||
ret void
|
||||
}
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
; RUN: llc -march=r600 -mcpu=SI -verify-machineinstrs< %s | FileCheck -check-prefix=SI -check-prefix=FUNC %s
|
||||
; RUN: llc -march=r600 -mcpu=cypress -verify-machineinstrs< %s
|
||||
|
||||
declare { i32, i1 } @llvm.usub.with.overflow.i32(i32, i32) nounwind readnone
|
||||
declare { i64, i1 } @llvm.usub.with.overflow.i64(i64, i64) nounwind readnone
|
||||
|
||||
; FUNC-LABEL: @usubo_i64_zext
|
||||
define void @usubo_i64_zext(i64 addrspace(1)* %out, i64 %a, i64 %b) nounwind {
|
||||
%usub = call { i64, i1 } @llvm.usub.with.overflow.i64(i64 %a, i64 %b) nounwind
|
||||
%val = extractvalue { i64, i1 } %usub, 0
|
||||
%carry = extractvalue { i64, i1 } %usub, 1
|
||||
%ext = zext i1 %carry to i64
|
||||
%add2 = add i64 %val, %ext
|
||||
store i64 %add2, i64 addrspace(1)* %out, align 8
|
||||
ret void
|
||||
}
|
||||
|
||||
; FUNC-LABEL: @s_usubo_i32
|
||||
; SI: S_SUB_I32
|
||||
define void @s_usubo_i32(i32 addrspace(1)* %out, i1 addrspace(1)* %carryout, i32 %a, i32 %b) nounwind {
|
||||
%usub = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %a, i32 %b) nounwind
|
||||
%val = extractvalue { i32, i1 } %usub, 0
|
||||
%carry = extractvalue { i32, i1 } %usub, 1
|
||||
store i32 %val, i32 addrspace(1)* %out, align 4
|
||||
store i1 %carry, i1 addrspace(1)* %carryout
|
||||
ret void
|
||||
}
|
||||
|
||||
; FUNC-LABEL: @v_usubo_i32
|
||||
; SI: V_SUBREV_I32_e32
|
||||
define void @v_usubo_i32(i32 addrspace(1)* %out, i1 addrspace(1)* %carryout, i32 addrspace(1)* %aptr, i32 addrspace(1)* %bptr) nounwind {
|
||||
%a = load i32 addrspace(1)* %aptr, align 4
|
||||
%b = load i32 addrspace(1)* %bptr, align 4
|
||||
%usub = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %a, i32 %b) nounwind
|
||||
%val = extractvalue { i32, i1 } %usub, 0
|
||||
%carry = extractvalue { i32, i1 } %usub, 1
|
||||
store i32 %val, i32 addrspace(1)* %out, align 4
|
||||
store i1 %carry, i1 addrspace(1)* %carryout
|
||||
ret void
|
||||
}
|
||||
|
||||
; FUNC-LABEL: @s_usubo_i64
|
||||
; SI: S_SUB_I32
|
||||
; SI: S_SUBB_U32
|
||||
define void @s_usubo_i64(i64 addrspace(1)* %out, i1 addrspace(1)* %carryout, i64 %a, i64 %b) nounwind {
|
||||
%usub = call { i64, i1 } @llvm.usub.with.overflow.i64(i64 %a, i64 %b) nounwind
|
||||
%val = extractvalue { i64, i1 } %usub, 0
|
||||
%carry = extractvalue { i64, i1 } %usub, 1
|
||||
store i64 %val, i64 addrspace(1)* %out, align 8
|
||||
store i1 %carry, i1 addrspace(1)* %carryout
|
||||
ret void
|
||||
}
|
||||
|
||||
; FUNC-LABEL: @v_usubo_i64
|
||||
; SI: V_SUB_I32
|
||||
; SI: V_SUBB_U32
|
||||
define void @v_usubo_i64(i64 addrspace(1)* %out, i1 addrspace(1)* %carryout, i64 addrspace(1)* %aptr, i64 addrspace(1)* %bptr) nounwind {
|
||||
%a = load i64 addrspace(1)* %aptr, align 4
|
||||
%b = load i64 addrspace(1)* %bptr, align 4
|
||||
%usub = call { i64, i1 } @llvm.usub.with.overflow.i64(i64 %a, i64 %b) nounwind
|
||||
%val = extractvalue { i64, i1 } %usub, 0
|
||||
%carry = extractvalue { i64, i1 } %usub, 1
|
||||
store i64 %val, i64 addrspace(1)* %out, align 8
|
||||
store i1 %carry, i1 addrspace(1)* %carryout
|
||||
ret void
|
||||
}
|
Loading…
Reference in New Issue