Index: lib/CodeGen/GlobalISel/LegalizerHelper.cpp =================================================================== --- lib/CodeGen/GlobalISel/LegalizerHelper.cpp +++ lib/CodeGen/GlobalISel/LegalizerHelper.cpp @@ -91,6 +91,9 @@ case TargetOpcode::G_FADD: assert((Size == 32 || Size == 64) && "Unsupported size"); return Size == 64 ? RTLIB::ADD_F64 : RTLIB::ADD_F32; + case TargetOpcode::G_FSUB: + assert((Size == 32 || Size == 64) && "Unsupported size"); + return Size == 64 ? RTLIB::SUB_F64 : RTLIB::SUB_F32; case TargetOpcode::G_FREM: return Size == 64 ? RTLIB::REM_F64 : RTLIB::REM_F32; case TargetOpcode::G_FPOW: @@ -146,6 +149,7 @@ break; } case TargetOpcode::G_FADD: + case TargetOpcode::G_FSUB: case TargetOpcode::G_FPOW: case TargetOpcode::G_FREM: { Type *HLTy = Size == 64 ? Type::getDoubleTy(Ctx) : Type::getFloatTy(Ctx); Index: lib/Target/ARM/ARMLegalizerInfo.cpp =================================================================== --- lib/Target/ARM/ARMLegalizerInfo.cpp +++ lib/Target/ARM/ARMLegalizerInfo.cpp @@ -103,8 +103,9 @@ setAction({G_ICMP, 1, Ty}, Legal); if (!ST.useSoftFloat() && ST.hasVFP2()) { - setAction({G_FADD, s32}, Legal); - setAction({G_FADD, s64}, Legal); + for (unsigned BinOp : {G_FADD, G_FSUB}) + for (auto Ty : {s32, s64}) + setAction({BinOp, Ty}, Legal); setAction({G_LOAD, s64}, Legal); setAction({G_STORE, s64}, Legal); @@ -113,8 +114,9 @@ setAction({G_FCMP, 1, s32}, Legal); setAction({G_FCMP, 1, s64}, Legal); } else { - for (auto Ty : {s32, s64}) - setAction({G_FADD, Ty}, Libcall); + for (unsigned BinOp : {G_FADD, G_FSUB}) + for (auto Ty : {s32, s64}) + setAction({BinOp, Ty}, Libcall); setAction({G_FCMP, s1}, Legal); setAction({G_FCMP, 1, s32}, Custom); Index: test/CodeGen/ARM/GlobalISel/arm-isel-fp.ll =================================================================== --- test/CodeGen/ARM/GlobalISel/arm-isel-fp.ll +++ test/CodeGen/ARM/GlobalISel/arm-isel-fp.ll @@ -50,6 +50,24 @@ ret double %r } +define arm_aapcscc float @test_sub_float(float %x, float %y) { +; CHECK-LABEL: test_sub_float: +; HARD: vsub.f32 +; SOFT-AEABI: blx __aeabi_fsub +; SOFT-DEFAULT: blx __subsf3 + %r = fsub float %x, %y + ret float %r +} + +define arm_aapcscc double @test_sub_double(double %x, double %y) { +; CHECK-LABEL: test_sub_double: +; HARD: vsub.f64 +; SOFT-AEABI: blx __aeabi_dsub +; SOFT-DEFAULT: blx __subdf3 + %r = fsub double %x, %y + ret double %r +} + define arm_aapcs_vfpcc i32 @test_cmp_float_ogt(float %x, float %y) { ; CHECK-LABEL: test_cmp_float_ogt ; HARD: vcmp.f32