summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/X86/X86ISelLowering.cpp30
-rw-r--r--llvm/lib/Target/X86/X86InstrInfo.cpp7
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;
}
}
OpenPOWER on IntegriCloud