summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'llvm')
-rw-r--r--llvm/lib/Target/XCore/XCoreISelLowering.cpp42
-rw-r--r--llvm/test/CodeGen/XCore/resources_combine.ll41
2 files changed, 83 insertions, 0 deletions
diff --git a/llvm/lib/Target/XCore/XCoreISelLowering.cpp b/llvm/lib/Target/XCore/XCoreISelLowering.cpp
index 930a4d19ba0..450f0771d90 100644
--- a/llvm/lib/Target/XCore/XCoreISelLowering.cpp
+++ b/llvm/lib/Target/XCore/XCoreISelLowering.cpp
@@ -180,6 +180,8 @@ XCoreTargetLowering::XCoreTargetLowering(XCoreTargetMachine &XTM)
// We have target-specific dag combine patterns for the following nodes:
setTargetDAGCombine(ISD::STORE);
setTargetDAGCombine(ISD::ADD);
+ setTargetDAGCombine(ISD::INTRINSIC_VOID);
+ setTargetDAGCombine(ISD::INTRINSIC_W_CHAIN);
setMinFunctionAlignment(1);
setPrefFunctionAlignment(2);
@@ -1566,6 +1568,46 @@ SDValue XCoreTargetLowering::PerformDAGCombine(SDNode *N,
SDLoc dl(N);
switch (N->getOpcode()) {
default: break;
+ case ISD::INTRINSIC_VOID:
+ switch (cast<ConstantSDNode>(N->getOperand(1))->getZExtValue()) {
+ case Intrinsic::xcore_outt:
+ case Intrinsic::xcore_outct:
+ case Intrinsic::xcore_chkct: {
+ SDValue OutVal = N->getOperand(3);
+ // These instructions ignore the high bits.
+ if (OutVal.hasOneUse()) {
+ unsigned BitWidth = OutVal.getValueSizeInBits();
+ APInt DemandedMask = APInt::getLowBitsSet(BitWidth, 8);
+ APInt KnownZero, KnownOne;
+ TargetLowering::TargetLoweringOpt TLO(DAG, !DCI.isBeforeLegalize(),
+ !DCI.isBeforeLegalizeOps());
+ const TargetLowering &TLI = DAG.getTargetLoweringInfo();
+ if (TLO.ShrinkDemandedConstant(OutVal, DemandedMask) ||
+ TLI.SimplifyDemandedBits(OutVal, DemandedMask, KnownZero, KnownOne,
+ TLO))
+ DCI.CommitTargetLoweringOpt(TLO);
+ }
+ break;
+ }
+ case Intrinsic::xcore_setpt: {
+ SDValue Time = N->getOperand(3);
+ // This instruction ignores the high bits.
+ if (Time.hasOneUse()) {
+ unsigned BitWidth = Time.getValueSizeInBits();
+ APInt DemandedMask = APInt::getLowBitsSet(BitWidth, 16);
+ APInt KnownZero, KnownOne;
+ TargetLowering::TargetLoweringOpt TLO(DAG, !DCI.isBeforeLegalize(),
+ !DCI.isBeforeLegalizeOps());
+ const TargetLowering &TLI = DAG.getTargetLoweringInfo();
+ if (TLO.ShrinkDemandedConstant(Time, DemandedMask) ||
+ TLI.SimplifyDemandedBits(Time, DemandedMask, KnownZero, KnownOne,
+ TLO))
+ DCI.CommitTargetLoweringOpt(TLO);
+ }
+ break;
+ }
+ }
+ break;
case XCoreISD::LADD: {
SDValue N0 = N->getOperand(0);
SDValue N1 = N->getOperand(1);
diff --git a/llvm/test/CodeGen/XCore/resources_combine.ll b/llvm/test/CodeGen/XCore/resources_combine.ll
index 50ac30e905b..20c184a53b9 100644
--- a/llvm/test/CodeGen/XCore/resources_combine.ll
+++ b/llvm/test/CodeGen/XCore/resources_combine.ll
@@ -5,6 +5,10 @@ declare i32 @llvm.xcore.inct.p1i8(i8 addrspace(1)* %r)
declare i32 @llvm.xcore.testct.p1i8(i8 addrspace(1)* %r)
declare i32 @llvm.xcore.testwct.p1i8(i8 addrspace(1)* %r)
declare i32 @llvm.xcore.getts.p1i8(i8 addrspace(1)* %r)
+declare void @llvm.xcore.outt.p1i8(i8 addrspace(1)* %r, i32 %value)
+declare void @llvm.xcore.outct.p1i8(i8 addrspace(1)* %r, i32 %value)
+declare void @llvm.xcore.chkct.p1i8(i8 addrspace(1)* %r, i32 %value)
+declare void @llvm.xcore.setpt.p1i8(i8 addrspace(1)* %r, i32 %value)
define i32 @int(i8 addrspace(1)* %r) nounwind {
; CHECK-LABEL: int:
@@ -50,3 +54,40 @@ define i32 @getts(i8 addrspace(1)* %r) nounwind {
%trunc = and i32 %result, 65535
ret i32 %result
}
+
+define void @outt(i8 addrspace(1)* %r, i32 %value) nounwind {
+; CHECK-LABEL: outt:
+; CHECK-NOT: zext
+; CHECK: outt res[r0], r1
+; CHECK-NEXT: retsp 0
+ %trunc = and i32 %value, 255
+ call void @llvm.xcore.outt.p1i8(i8 addrspace(1)* %r, i32 %trunc)
+ ret void
+}
+
+define void @outct(i8 addrspace(1)* %r, i32 %value) nounwind {
+; CHECK-LABEL: outct:
+; CHECK-NOT: zext
+; CHECK: outct res[r0], r1
+ %trunc = and i32 %value, 255
+ call void @llvm.xcore.outct.p1i8(i8 addrspace(1)* %r, i32 %trunc)
+ ret void
+}
+
+define void @chkct(i8 addrspace(1)* %r, i32 %value) nounwind {
+; CHECK-LABEL: chkct:
+; CHECK-NOT: zext
+; CHECK: chkct res[r0], r1
+ %trunc = and i32 %value, 255
+ call void @llvm.xcore.chkct.p1i8(i8 addrspace(1)* %r, i32 %trunc)
+ ret void
+}
+
+define void @setpt(i8 addrspace(1)* %r, i32 %value) nounwind {
+; CHECK-LABEL: setpt:
+; CHECK-NOT: zext
+; CHECK: setpt res[r0], r1
+ %trunc = and i32 %value, 65535
+ call void @llvm.xcore.setpt.p1i8(i8 addrspace(1)* %r, i32 %trunc)
+ ret void
+}
OpenPOWER on IntegriCloud