diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.cpp | 30 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86InstrInfo.cpp | 7 |
2 files changed, 37 insertions, 0 deletions
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index 9c74575916e..fb923436959 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -33452,6 +33452,36 @@ static SDValue combineCMov(SDNode *N, SelectionDAG &DAG, } } + // Handle (CMOV (ADD (CTTZ X), C), C-1, (X != 0)) -> + // (ADD (CMOV (CTTZ X), -1, (X != 0)), C) or + // (CMOV C-1, (ADD (CTTZ X), C), (X == 0)) -> + // (ADD (CMOV C-1, (CTTZ X), (X == 0)), C) + if (CC == X86::COND_NE || CC == X86::COND_E) { + auto *Cnst = CC == X86::COND_E ? dyn_cast<ConstantSDNode>(TrueOp) + : dyn_cast<ConstantSDNode>(FalseOp); + SDValue Add = CC == X86::COND_E ? FalseOp : TrueOp; + + if (Cnst && Add.getOpcode() == ISD::ADD && Add.hasOneUse()) { + auto *AddOp1 = dyn_cast<ConstantSDNode>(Add.getOperand(1)); + SDValue AddOp2 = Add.getOperand(0); + if (AddOp1 && (AddOp2.getOpcode() == ISD::CTTZ_ZERO_UNDEF || + AddOp2.getOpcode() == ISD::CTTZ)) { + APInt Diff = Cnst->getAPIntValue() - AddOp1->getAPIntValue(); + if (CC == X86::COND_NE) { + Add = DAG.getNode(X86ISD::CMOV, DL, Add.getValueType(), AddOp2, + DAG.getConstant(Diff, DL, Add.getValueType()), + DAG.getConstant(CC, DL, MVT::i8), Cond); + } else { + Add = DAG.getNode(X86ISD::CMOV, DL, Add.getValueType(), + DAG.getConstant(Diff, DL, Add.getValueType()), + AddOp2, DAG.getConstant(CC, DL, MVT::i8), Cond); + } + return DAG.getNode(X86ISD::ADD, DL, Add.getValueType(), Add, + SDValue(AddOp1, 0)); + } + } + } + return SDValue(); } diff --git a/llvm/lib/Target/X86/X86InstrInfo.cpp b/llvm/lib/Target/X86/X86InstrInfo.cpp index 700e34ad0d0..c6f679a3c6b 100644 --- a/llvm/lib/Target/X86/X86InstrInfo.cpp +++ b/llvm/lib/Target/X86/X86InstrInfo.cpp @@ -3591,6 +3591,13 @@ static X86::CondCode isUseDefConvertible(MachineInstr &MI) { case X86::TZCNT32rr: case X86::TZCNT32rm: case X86::TZCNT64rr: case X86::TZCNT64rm: return X86::COND_B; + case X86::BSF16rr: + case X86::BSF16rm: + case X86::BSF32rr: + case X86::BSF32rm: + case X86::BSF64rr: + case X86::BSF64rm: + return X86::COND_E; } } |