summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorAmara Emerson <aemerson@apple.com>2017-10-09 15:15:09 +0000
committerAmara Emerson <aemerson@apple.com>2017-10-09 15:15:09 +0000
commit24ca39ce71e6312672f58d311b6bb6af727f9ca7 (patch)
tree92eafa5cc4f54c2eef848c11ce5d311a740a5331 /llvm/lib
parent8557e2940813f25d017bed66bf03ac55db6381fa (diff)
downloadbcm5719-llvm-24ca39ce71e6312672f58d311b6bb6af727f9ca7.tar.gz
bcm5719-llvm-24ca39ce71e6312672f58d311b6bb6af727f9ca7.zip
[AArch64] Improve codegen for inverted overflow checking intrinsics
E.g. if we have a (xor(overflow-bit), 1) where overflow-bit comes from an intrinsic like llvm.sadd.with.overflow then we can kill the xor and use the inverted condition code for the CSEL. rdar://28495949 Reviewed By: kristof.beyls Differential Revision: https://reviews.llvm.org/D38160 llvm-svn: 315205
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/AArch64/AArch64ISelLowering.cpp42
1 files changed, 33 insertions, 9 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index ff9bf2a7daf..ea63919474c 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -1972,10 +1972,41 @@ SDValue AArch64TargetLowering::LowerF128Call(SDValue Op, SelectionDAG &DAG,
return makeLibCall(DAG, Call, MVT::f128, Ops, false, SDLoc(Op)).first;
}
+// Returns true if the given Op is the overflow flag result of an overflow
+// intrinsic operation.
+static bool isOverflowIntrOpRes(SDValue Op) {
+ unsigned Opc = Op.getOpcode();
+ return (Op.getResNo() == 1 &&
+ (Opc == ISD::SADDO || Opc == ISD::UADDO || Opc == ISD::SSUBO ||
+ Opc == ISD::USUBO || Opc == ISD::SMULO || Opc == ISD::UMULO));
+}
+
static SDValue LowerXOR(SDValue Op, SelectionDAG &DAG) {
SDValue Sel = Op.getOperand(0);
SDValue Other = Op.getOperand(1);
+ SDLoc dl(Sel);
+ // If the operand is an overflow checking operation, invert the condition
+ // code and kill the Not operation. I.e., transform:
+ // (xor (overflow_op_bool, 1))
+ // -->
+ // (csel 1, 0, invert(cc), overflow_op_bool)
+ // ... which later gets transformed to just a cset instruction with an
+ // inverted condition code, rather than a cset + eor sequence.
+ if (isOneConstant(Other) && isOverflowIntrOpRes(Sel)) {
+ // Only lower legal XALUO ops.
+ if (!DAG.getTargetLoweringInfo().isTypeLegal(Sel->getValueType(0)))
+ return SDValue();
+
+ SDValue TVal = DAG.getConstant(1, dl, MVT::i32);
+ SDValue FVal = DAG.getConstant(0, dl, MVT::i32);
+ AArch64CC::CondCode CC;
+ SDValue Value, Overflow;
+ std::tie(Value, Overflow) = getAArch64XALUOOp(CC, Sel.getValue(0), DAG);
+ SDValue CCVal = DAG.getConstant(getInvertedCondCode(CC), dl, MVT::i32);
+ return DAG.getNode(AArch64ISD::CSEL, dl, Op.getValueType(), TVal, FVal,
+ CCVal, Overflow);
+ }
// If neither operand is a SELECT_CC, give up.
if (Sel.getOpcode() != ISD::SELECT_CC)
std::swap(Sel, Other);
@@ -1994,7 +2025,6 @@ static SDValue LowerXOR(SDValue Op, SelectionDAG &DAG) {
SDValue RHS = Sel.getOperand(1);
SDValue TVal = Sel.getOperand(2);
SDValue FVal = Sel.getOperand(3);
- SDLoc dl(Sel);
// FIXME: This could be generalized to non-integer comparisons.
if (LHS.getValueType() != MVT::i32 && LHS.getValueType() != MVT::i64)
@@ -3958,10 +3988,7 @@ SDValue AArch64TargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const {
// Optimize {s|u}{add|sub|mul}.with.overflow feeding into a branch
// instruction.
- unsigned Opc = LHS.getOpcode();
- if (LHS.getResNo() == 1 && isOneConstant(RHS) &&
- (Opc == ISD::SADDO || Opc == ISD::UADDO || Opc == ISD::SSUBO ||
- Opc == ISD::USUBO || Opc == ISD::SMULO || Opc == ISD::UMULO)) {
+ if (isOverflowIntrOpRes(LHS) && isOneConstant(RHS)) {
assert((CC == ISD::SETEQ || CC == ISD::SETNE) &&
"Unexpected condition code.");
// Only lower legal XALUO ops.
@@ -4453,12 +4480,9 @@ SDValue AArch64TargetLowering::LowerSELECT(SDValue Op,
SDValue FVal = Op->getOperand(2);
SDLoc DL(Op);
- unsigned Opc = CCVal.getOpcode();
// Optimize {s|u}{add|sub|mul}.with.overflow feeding into a select
// instruction.
- if (CCVal.getResNo() == 1 &&
- (Opc == ISD::SADDO || Opc == ISD::UADDO || Opc == ISD::SSUBO ||
- Opc == ISD::USUBO || Opc == ISD::SMULO || Opc == ISD::UMULO)) {
+ if (isOverflowIntrOpRes(CCVal)) {
// Only lower legal XALUO ops.
if (!DAG.getTargetLoweringInfo().isTypeLegal(CCVal->getValueType(0)))
return SDValue();
OpenPOWER on IntegriCloud