From 83eab939a4f85b8571cee5c3907ac3de0f642f06 Mon Sep 17 00:00:00 2001 From: Richard Osborne Date: Thu, 27 Feb 2014 13:20:11 +0000 Subject: [PATCH] [XCore] Add dag combines for instructions that ignore some input bits. These instructions ignore the high bits of one of their input operands - try and use this to simplify the code. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@202394 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/XCore/XCoreISelLowering.cpp | 42 +++++++++++++++++++++++++ test/CodeGen/XCore/resources_combine.ll | 41 ++++++++++++++++++++++++ 2 files changed, 83 insertions(+) diff --git a/lib/Target/XCore/XCoreISelLowering.cpp b/lib/Target/XCore/XCoreISelLowering.cpp index 930a4d19ba0..450f0771d90 100644 --- a/lib/Target/XCore/XCoreISelLowering.cpp +++ b/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(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/test/CodeGen/XCore/resources_combine.ll b/test/CodeGen/XCore/resources_combine.ll index 50ac30e905b..20c184a53b9 100644 --- a/test/CodeGen/XCore/resources_combine.ll +++ b/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 +} -- 2.34.1