setAction({G_ICMP, 1, Ty}, Legal);
if (!ST.useSoftFloat() && ST.hasVFP2()) {
- for (unsigned BinOp : {G_FADD, G_FSUB, G_FMUL, G_FDIV})
+ for (unsigned BinOp : {G_FADD, G_FSUB, G_FMUL, G_FDIV, G_FCONSTANT})
for (auto Ty : {s32, s64})
setAction({BinOp, Ty}, Legal);
for (auto Ty : {s32, s64})
setAction({BinOp, Ty}, Libcall);
+ for (auto Ty : {s32, s64}) {
+ setAction({G_FCONSTANT, Ty}, Custom);
+ }
+
setAction({G_FCMP, s1}, Legal);
setAction({G_FCMP, 1, s32}, Custom);
setAction({G_FCMP, 1, s64}, Custom);
using namespace TargetOpcode;
MIRBuilder.setInstr(MI);
+ LLVMContext &Ctx = MIRBuilder.getMF().getFunction().getContext();
switch (MI.getOpcode()) {
default:
// Our divmod libcalls return a struct containing the quotient and the
// remainder. We need to create a virtual register for it.
- auto &Ctx = MIRBuilder.getMF().getFunction().getContext();
Type *ArgTy = Type::getInt32Ty(Ctx);
StructType *RetTy = StructType::get(Ctx, {ArgTy, ArgTy}, /* Packed */ true);
auto RetVal = MRI.createGenericVirtualRegister(
return true;
}
- auto &Ctx = MIRBuilder.getMF().getFunction().getContext();
assert((OpSize == 32 || OpSize == 64) && "Unsupported operand size");
auto *ArgTy = OpSize == 32 ? Type::getFloatTy(Ctx) : Type::getDoubleTy(Ctx);
auto *RetTy = Type::getInt32Ty(Ctx);
}
break;
}
+ case G_FCONSTANT: {
+ // Convert to integer constants, while preserving the binary representation.
+ auto AsInteger =
+ MI.getOperand(1).getFPImm()->getValueAPF().bitcastToAPInt();
+ MIRBuilder.buildConstant(MI.getOperand(0).getReg(),
+ *ConstantInt::get(Ctx, AsInteger));
+ break;
+ }
}
MI.eraseFromParent();
define void @test_fdiv_float() { ret void }
define void @test_fdiv_double() { ret void }
+ define void @test_fconstant_float() { ret void }
+ define void @test_fconstant_double() { ret void }
+
define void @test_fcmp_true_s32() { ret void }
define void @test_fcmp_false_s32() { ret void }
BX_RET 14, %noreg, implicit %r0, implicit %r1
...
---
+name: test_fconstant_float
+# CHECK-LABEL: name: test_fconstant_float
+legalized: false
+# CHECK: legalized: true
+regBankSelected: false
+selected: false
+tracksRegLiveness: true
+registers:
+ - { id: 0, class: _ }
+body: |
+ bb.0:
+ liveins:
+
+ ; HARD: [[R:%[0-9]+]]:_(s32) = G_FCONSTANT float -1.25
+ ; SOFT-NOT: G_FCONSTANT
+ ; SOFT: [[R:%[0-9]+]]:_(s32) = G_CONSTANT i32 -1080033280
+ ; SOFT-NOT: G_FCONSTANT
+ %0(s32) = G_FCONSTANT float -1.25
+ ; CHECK: %r0 = COPY [[R]]
+ %r0 = COPY %0(s32)
+ BX_RET 14, %noreg, implicit %r0
+...
+---
+name: test_fconstant_double
+# CHECK-LABEL: name: test_fconstant_double
+legalized: false
+# CHECK: legalized: true
+regBankSelected: false
+selected: false
+tracksRegLiveness: true
+registers:
+ - { id: 0, class: _ }
+ - { id: 1, class: _ }
+ - { id: 2, class: _ }
+body: |
+ bb.0:
+ liveins:
+
+ ; HARD: [[R:%[0-9]+]]:_(s64) = G_FCONSTANT double -2.4
+ ; SOFT-NOT: G_FCONSTANT
+ ; SOFT-DAG: [[HI:%[0-9]+]]:_(s32) = G_CONSTANT i32 -1073532109
+ ; SOFT-DAG: [[LO:%[0-9]+]]:_(s32) = G_CONSTANT i32 858993459
+ ; SOFT-NOT: G_FCONSTANT
+ %0(s64) = G_FCONSTANT double -2.4
+ ; HARD-DAG: G_UNMERGE_VALUES [[R]](s64)
+ ; SOFT-DAG: %r0 = COPY [[HI]]
+ ; SOFT-DAG: %r1 = COPY [[LO]]
+ %1(s32),%2(s32) = G_UNMERGE_VALUES %0(s64)
+ %r0 = COPY %2(s32)
+ %r1 = COPY %1(s32)
+ BX_RET 14, %noreg, implicit %r0, implicit %r1
+...
+---
name: test_fcmp_true_s32
# CHECK-LABEL: name: test_fcmp_true_s32
legalized: false