34
34
#include " llvm/CodeGen/MachineRegisterInfo.h"
35
35
#include " llvm/CodeGen/TargetOpcodes.h"
36
36
#include " llvm/IR/Constants.h"
37
+ #include " llvm/IR/Instructions.h"
37
38
#include " llvm/IR/PatternMatch.h"
38
39
#include " llvm/IR/Type.h"
39
40
#include " llvm/IR/IntrinsicsAArch64.h"
@@ -177,8 +178,10 @@ class AArch64InstructionSelector : public InstructionSelector {
177
178
MachineIRBuilder &MIRBuilder) const ;
178
179
179
180
// / Emit a floating point comparison between \p LHS and \p RHS.
181
+ // / \p Pred if given is the intended predicate to use.
180
182
MachineInstr *emitFPCompare (Register LHS, Register RHS,
181
- MachineIRBuilder &MIRBuilder) const ;
183
+ MachineIRBuilder &MIRBuilder,
184
+ Optional<CmpInst::Predicate> = None) const ;
182
185
183
186
MachineInstr *emitInstr (unsigned Opcode,
184
187
std::initializer_list<llvm::DstOp> DstOps,
@@ -1483,11 +1486,11 @@ bool AArch64InstructionSelector::selectCompareBranchFedByFCmp(
1483
1486
assert (I.getOpcode () == TargetOpcode::G_BRCOND);
1484
1487
// Unfortunately, the mapping of LLVM FP CC's onto AArch64 CC's isn't
1485
1488
// totally clean. Some of them require two branches to implement.
1486
- emitFPCompare (FCmp.getOperand (2 ).getReg (), FCmp.getOperand (3 ).getReg (), MIB);
1489
+ auto Pred = (CmpInst::Predicate)FCmp.getOperand (1 ).getPredicate ();
1490
+ emitFPCompare (FCmp.getOperand (2 ).getReg (), FCmp.getOperand (3 ).getReg (), MIB,
1491
+ Pred);
1487
1492
AArch64CC::CondCode CC1, CC2;
1488
- changeFCMPPredToAArch64CC (
1489
- static_cast <CmpInst::Predicate>(FCmp.getOperand (1 ).getPredicate ()), CC1,
1490
- CC2);
1493
+ changeFCMPPredToAArch64CC (static_cast <CmpInst::Predicate>(Pred), CC1, CC2);
1491
1494
MachineBasicBlock *DestMBB = I.getOperand (1 ).getMBB ();
1492
1495
MIB.buildInstr (AArch64::Bcc, {}, {}).addImm (CC1).addMBB (DestMBB);
1493
1496
if (CC2 != AArch64CC::AL)
@@ -3090,7 +3093,7 @@ bool AArch64InstructionSelector::select(MachineInstr &I) {
3090
3093
CmpInst::Predicate Pred =
3091
3094
static_cast <CmpInst::Predicate>(I.getOperand (1 ).getPredicate ());
3092
3095
if (!emitFPCompare (I.getOperand (2 ).getReg (), I.getOperand (3 ).getReg (),
3093
- MIRBuilder) ||
3096
+ MIRBuilder, Pred ) ||
3094
3097
!emitCSetForFCmp (I.getOperand (0 ).getReg (), Pred, MIRBuilder))
3095
3098
return false ;
3096
3099
I.eraseFromParent ();
@@ -4211,7 +4214,8 @@ MachineInstr *AArch64InstructionSelector::emitCSetForFCmp(
4211
4214
4212
4215
MachineInstr *
4213
4216
AArch64InstructionSelector::emitFPCompare (Register LHS, Register RHS,
4214
- MachineIRBuilder &MIRBuilder) const {
4217
+ MachineIRBuilder &MIRBuilder,
4218
+ Optional<CmpInst::Predicate> Pred) const {
4215
4219
MachineRegisterInfo &MRI = *MIRBuilder.getMRI ();
4216
4220
LLT Ty = MRI.getType (LHS);
4217
4221
if (Ty.isVector ())
@@ -4224,7 +4228,12 @@ AArch64InstructionSelector::emitFPCompare(Register LHS, Register RHS,
4224
4228
// to explicitly materialize a constant.
4225
4229
const ConstantFP *FPImm = getConstantFPVRegVal (RHS, MRI);
4226
4230
bool ShouldUseImm = FPImm && (FPImm->isZero () && !FPImm->isNegative ());
4227
- if (!ShouldUseImm) {
4231
+
4232
+ auto IsEqualityPred = [](CmpInst::Predicate P) {
4233
+ return P == CmpInst::FCMP_OEQ || P == CmpInst::FCMP_ONE ||
4234
+ P == CmpInst::FCMP_UEQ || P == CmpInst::FCMP_UNE;
4235
+ };
4236
+ if (!ShouldUseImm && Pred && IsEqualityPred (*Pred)) {
4228
4237
// Try commutating the operands.
4229
4238
const ConstantFP *LHSImm = getConstantFPVRegVal (LHS, MRI);
4230
4239
if (LHSImm && (LHSImm->isZero () && !LHSImm->isNegative ())) {
0 commit comments