From a69bb4d0b780c06a598567bbdfb62aa8eb79a51a Mon Sep 17 00:00:00 2001 From: Alex Malyshev Date: Tue, 10 Oct 2023 12:35:18 -0700 Subject: [PATCH] Fix return type of LongBinaryOp Summary: It will return a float when the exponent is negative. Caught when running tests with AutoJIT + type profiling. I don't see other instances of `Float | Long` types in HIR anywhere yet, but it appears to work fine. Reviewed By: mpage, swtaarrs Differential Revision: D50091025 fbshipit-source-id: 77ad3b50a48da9c28bf43f776a163c88e068d8f3 --- Jit/hir/ssa.cpp | 4 ++ .../hir_tests/profile_data_hir_test.txt | 69 +++++++++++++++++++ 2 files changed, 73 insertions(+) diff --git a/Jit/hir/ssa.cpp b/Jit/hir/ssa.cpp index 75d71f589ae..dc14da38270 100644 --- a/Jit/hir/ssa.cpp +++ b/Jit/hir/ssa.cpp @@ -517,6 +517,10 @@ Type outputType( if (binop.op() == BinaryOpKind::kTrueDivide) { return TFloatExact; } + if (binop.op() == BinaryOpKind::kPower) { + // Will be floating-point for negative exponents. + return TFloatExact | TLongExact; + } return TLongExact; } case Opcode::kLongCompare: diff --git a/RuntimeTests/hir_tests/profile_data_hir_test.txt b/RuntimeTests/hir_tests/profile_data_hir_test.txt index 827d98cf4bb..72929e7eec7 100644 --- a/RuntimeTests/hir_tests/profile_data_hir_test.txt +++ b/RuntimeTests/hir_tests/profile_data_hir_test.txt @@ -308,6 +308,75 @@ fun jittestmodule:test { } } --- +SpecializePowerHasCorrectType +--- +class Point: + def __init__(self, x, y): + self.x = x + self.y = y + + __slots__ = ("x", "y") + +def test(p): + return p.x ** p.y + +test(Point(1, -2)) +--- +fun jittestmodule:test { + bb 0 { + v4:Object = LoadArg<0; "p"> + Snapshot + v6:ObjectUser[Point:Exact] = GuardType v4 { + GuiltyReg v4 + } + DeoptPatchpoint<0xdeadbeef> { + Descr 'member descriptor attribute' + GuiltyReg v6 + } + UseType v6 + v14:OptObject = LoadField v6 + v15:Object = CheckField<"x"> v14 { + GuiltyReg v6 + FrameState { + NextInstrOffset 4 + Locals<1> v6 + } + } + Snapshot + DeoptPatchpoint<0xdeadbeef> { + Descr 'member descriptor attribute' + GuiltyReg v6 + } + UseType v6 + v16:OptObject = LoadField v6 + v17:Object = CheckField<"y"> v16 { + GuiltyReg v6 + FrameState { + NextInstrOffset 8 + Locals<1> v6 + Stack<1> v15 + } + } + Snapshot + v11:LongExact = GuardType v15 { + GuiltyReg v15 + } + v12:LongExact = GuardType v17 { + GuiltyReg v17 + } + UseType v11 + UseType v12 + v18:{FloatExact|LongExact} = LongBinaryOp v11 v12 { + FrameState { + NextInstrOffset 10 + Locals<1> v6 + } + } + Snapshot + Return v18 + } +} +--- SpecializeSplitDictLoadAttr --- class Person: