LLVM  6.0.0svn
Functions
CMP;CCMP matching

These functions deal with the formation of CMP;CCMP;... More...

Functions

static SDValue emitConditionalComparison (SDValue LHS, SDValue RHS, ISD::CondCode CC, SDValue CCOp, AArch64CC::CondCode Predicate, AArch64CC::CondCode OutCC, const SDLoc &DL, SelectionDAG &DAG)
 Create a conditional comparison; Use CCMP, CCMN or FCCMP as appropriate. More...
 
static bool isConjunctionDisjunctionTree (const SDValue Val, bool &CanNegate, unsigned Depth=0)
 Returns true if Val is a tree of AND/OR/SETCC operations. More...
 
static SDValue emitConjunctionDisjunctionTreeRec (SelectionDAG &DAG, SDValue Val, AArch64CC::CondCode &OutCC, bool Negate, SDValue CCOp, AArch64CC::CondCode Predicate)
 Emit conjunction or disjunction tree with the CMP/FCMP followed by a chain of CCMP/CFCMP ops. More...
 
static SDValue emitConjunctionDisjunctionTree (SelectionDAG &DAG, SDValue Val, AArch64CC::CondCode &OutCC)
 Emit conjunction or disjunction tree with the CMP/FCMP followed by a chain of CCMP/CFCMP ops. More...
 

Detailed Description

These functions deal with the formation of CMP;CCMP;...

sequences. The CCMP/CCMN/FCCMP/FCCMPE instructions allow the conditional execution of a comparison. They set the NZCV flags to a predefined value if their predicate is false. This allows to express arbitrary conjunctions, for example "cmp 0 (and (setCA (cmp A)) (setCB (cmp B))))" expressed as: cmp A ccmp B, inv(CB), CA check for CB flags

In general we can create code for arbitrary "... (and (and A B) C)" sequences. We can also implement some "or" expressions, because "(or A B)" is equivalent to "not (and (not A) (not B))" and we can implement some negation operations: We can negate the results of a single comparison by inverting the flags used when the predicate fails and inverting the flags tested in the next instruction; We can also negate the results of the whole previous conditional compare sequence by inverting the flags tested in the next instruction. However there is no way to negate the result of a partial sequence.

Therefore on encountering an "or" expression we can negate the subtree on one side and have to be able to push the negate to the leafs of the subtree on the other side (see also the comments in code). As complete example: "or (or (setCA (cmp A)) (setCB (cmp B))) (and (setCC (cmp C)) (setCD (cmp D)))" is transformed to "not (and (not (and (setCC (cmp C)) (setCC (cmp D)))) (and (not (setCA (cmp A)) (not (setCB (cmp B))))))" and implemented as: cmp C ccmp D, inv(CD), CC ccmp A, CA, inv(CD) ccmp B, CB, inv(CA) check for CB flags A counterexample is "or (and A B) (and C D)" which cannot be implemented by conditional compare sequences.

Function Documentation

◆ emitConditionalComparison()

static SDValue emitConditionalComparison ( SDValue  LHS,
SDValue  RHS,
ISD::CondCode  CC,
SDValue  CCOp,
AArch64CC::CondCode  Predicate,
AArch64CC::CondCode  OutCC,
const SDLoc DL,
SelectionDAG DAG 
)
static

◆ emitConjunctionDisjunctionTree()

static SDValue emitConjunctionDisjunctionTree ( SelectionDAG DAG,
SDValue  Val,
AArch64CC::CondCode OutCC 
)
static

Emit conjunction or disjunction tree with the CMP/FCMP followed by a chain of CCMP/CFCMP ops.

See CMP;CCMP matching.

See also
emitConjunctionDisjunctionTreeRec().

Definition at line 1708 of file AArch64ISelLowering.cpp.

References llvm::AArch64CC::AL, emitConjunctionDisjunctionTreeRec(), and isConjunctionDisjunctionTree().

Referenced by getAArch64Cmp().

◆ emitConjunctionDisjunctionTreeRec()

static SDValue emitConjunctionDisjunctionTreeRec ( SelectionDAG DAG,
SDValue  Val,
AArch64CC::CondCode OutCC,
bool  Negate,
SDValue  CCOp,
AArch64CC::CondCode  Predicate 
)
static

Emit conjunction or disjunction tree with the CMP/FCMP followed by a chain of CCMP/CFCMP ops.

See CMP;CCMP matching. Tries to transform the given i1 producing node Val to a series compare and conditional compare operations.

Returns
an NZCV flags producing node and sets OutCC to the flags that should be tested or returns SDValue() if transformation was not possible. On recursive invocations PushNegate may be set to true to have negation effects pushed to the tree leafs; Predicate is an NZCV flag predicate for the comparisons in the current subtree; Depth limits the search depth to avoid stack overflow.

Definition at line 1605 of file AArch64ISelLowering.cpp.

References llvm::AArch64CC::AL, llvm::ISD::AND, assert(), changeFPCCToANDAArch64CC(), changeIntCCToAArch64CC(), emitComparison(), emitConditionalComparison(), llvm::AArch64CC::getInvertedCondCode(), llvm::SDValue::getNode(), llvm::SDNode::getOpcode(), llvm::SDNode::getOperand(), llvm::ISD::getSetCCInverse(), llvm::SDValue::getValueType(), llvm::SDNode::hasOneUse(), isConjunctionDisjunctionTree(), llvm::EVT::isFloatingPoint(), llvm::EVT::isInteger(), llvm::ISD::OR, llvm::ISD::SETCC, and std::swap().

Referenced by emitConjunctionDisjunctionTree().

◆ isConjunctionDisjunctionTree()

static bool isConjunctionDisjunctionTree ( const SDValue  Val,
bool CanNegate,
unsigned  Depth = 0 
)
static

Returns true if Val is a tree of AND/OR/SETCC operations.

CanPushNegate is set to true if we can push a negate operation through the tree in a was that we are left with AND operations and negate operations at the leafs only. i.e. "not (or (or x y) z)" can be changed to "and (and (not x) (not y)) (not z)"; "not (or (and x y) z)" cannot be brought into such a form.

Definition at line 1547 of file AArch64ISelLowering.cpp.

References llvm::ISD::AND, llvm::Depth, llvm::MVT::f128, llvm::SDNode::getOpcode(), llvm::SDNode::getOperand(), llvm::SDValue::getValueType(), llvm::SDValue::hasOneUse(), llvm::ISD::OR, and llvm::ISD::SETCC.

Referenced by emitConjunctionDisjunctionTree(), and emitConjunctionDisjunctionTreeRec().