diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/UseMethod.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/UseMethod.java
index 4be0aeba052f8c8ce93e7a755e78b6114aa83f9d..a9e57bb24b883f6227834accc249dae5183ea44c 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/UseMethod.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/UseMethod.java
@@ -18,7 +18,9 @@ import com.oracle.truffle.api.frame.*;
 import com.oracle.truffle.r.nodes.*;
 import com.oracle.truffle.r.nodes.access.*;
 import com.oracle.truffle.r.nodes.builtin.*;
+import com.oracle.truffle.r.nodes.builtin.base.UseMethodFactory.*;
 import com.oracle.truffle.r.nodes.control.*;
+import com.oracle.truffle.r.nodes.unary.*;
 import com.oracle.truffle.r.runtime.*;
 import com.oracle.truffle.r.runtime.data.*;
 import com.oracle.truffle.r.runtime.data.model.*;
@@ -48,25 +50,13 @@ public abstract class UseMethod extends RBuiltinNode {
         controlVisibility();
         if (useMethodNode == null) {
             CompilerDirectives.transferToInterpreterAndInvalidate();
-            useMethodNode = insert(new UseMethodUninitializedNode());
-        }
-        return useMethodNode.execute(frame, generic, arg);
-    }
-
-    private static final class UseMethodUninitializedNode extends UseMethodNode {
-        @Override
-        public Object execute(VirtualFrame frame, final String generic, Object obj) {
-            CompilerDirectives.transferToInterpreterAndInvalidate();
-            return specialize(obj).execute(frame, generic, obj);
-        }
-
-        private UseMethodNode specialize(Object obj) {
-            CompilerAsserts.neverPartOfCompilation();
-            if (obj instanceof RMissing) {
-                return this.replace(new UseMethodGenericOnlyNode());
+            if (arg instanceof RMissing) {
+                useMethodNode = insert(new UseMethodGenericOnlyNode());
+            } else {
+                useMethodNode = insert(new UseMethodGenericAndObjectNode());
             }
-            return this.replace(new UseMethodGenericAndObjectNode());
         }
+        throw new ReturnException(useMethodNode.execute(frame, generic, arg));
     }
 
     /*
@@ -83,7 +73,7 @@ public abstract class UseMethod extends RBuiltinNode {
             }
             Object enclosingArg = RArguments.getArgument(frame, 0);
             initDispatchedCallNode(generic);
-            throw new ReturnException(dispatchedCallNode.execute(frame, getClassHierarchy(enclosingArg)));
+            return dispatchedCallNode.execute(frame, classHierarchyNode.execute(frame, enclosingArg));
         }
     }
 
@@ -92,13 +82,14 @@ public abstract class UseMethod extends RBuiltinNode {
         @Override
         public Object execute(VirtualFrame frame, final String generic, Object obj) {
             initDispatchedCallNode(generic);
-            throw new ReturnException(dispatchedCallNode.execute(frame, getClassHierarchy(obj)));
+            return dispatchedCallNode.execute(frame, classHierarchyNode.execute(frame, obj));
         }
     }
 
     private abstract static class UseMethodNode extends RNode {
 
         @Child protected DispatchedCallNode dispatchedCallNode;
+        @Child ClassHierarchyNode classHierarchyNode = ClassHierarchyNodeFactory.create(null);
         protected String lastGenericName;
 
         @Override
@@ -115,28 +106,41 @@ public abstract class UseMethod extends RBuiltinNode {
             }
         }
 
-        protected RStringVector getClassHierarchy(Object anObj) {
-            if (anObj instanceof RAbstractContainer) {
-                return ((RAbstractContainer) anObj).getClassHierarchy();
-            }
-            if (anObj instanceof Byte) {
-                return RDataFactory.createStringVector(RRuntime.TYPE_LOGICAL);
-            }
-            if (anObj instanceof String) {
-                return RDataFactory.createStringVector(RRuntime.TYPE_CHARACTER);
-            }
-            if (anObj instanceof Integer) {
-                return RDataFactory.createStringVector(RRuntime.TYPE_INTEGER);
-            }
-            if (anObj instanceof Double) {
-                return RDataFactory.createStringVector(RRuntime.CLASS_DOUBLE, RDataFactory.COMPLETE_VECTOR);
-            }
-            if (anObj instanceof RComplex) {
-                return RDataFactory.createStringVector(RRuntime.TYPE_COMPLEX);
-            }
-            throw new AssertionError();
+        public abstract Object execute(VirtualFrame frame, final String generic, final Object o);
+    }
+
+    protected abstract static class ClassHierarchyNode extends UnaryNode {
+
+        public abstract RStringVector execute(VirtualFrame frame, Object arg);
+
+        @Specialization(order = 0)
+        public RStringVector getClassHr(RAbstractContainer arg) {
+            return arg.getClassHierarchy();
         }
 
-        public abstract Object execute(VirtualFrame frame, final String generic, final Object o);
+        @Specialization
+        public RStringVector getClassHr(@SuppressWarnings("unused") byte arg) {
+            return RDataFactory.createStringVector(RRuntime.TYPE_LOGICAL);
+        }
+
+        @Specialization
+        public RStringVector getClassHr(@SuppressWarnings("unused") String arg) {
+            return RDataFactory.createStringVector(RRuntime.TYPE_CHARACTER);
+        }
+
+        @Specialization
+        public RStringVector getClassHr(@SuppressWarnings("unused") int arg) {
+            return RDataFactory.createStringVector(RRuntime.TYPE_INTEGER);
+        }
+
+        @Specialization
+        public RStringVector getClassHr(@SuppressWarnings("unused") double arg) {
+            return RDataFactory.createStringVector(RRuntime.CLASS_DOUBLE, RDataFactory.COMPLETE_VECTOR);
+        }
+
+        @Specialization
+        public RStringVector getClassHr(@SuppressWarnings("unused") RComplex arg) {
+            return RDataFactory.createStringVector(RRuntime.TYPE_COMPLEX);
+        }
     }
 }
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test
index d766979e4a6636d6186bd0cce12ceb8b67daab4a..11f58623677bf1e01fa1dc0696c2f7505574ccd7 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test
@@ -10003,6 +10003,10 @@ f second 1
 ##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testUseMethodSimple
 #{f <- function(x){ UseMethod("f",x); };f.first <- function(x){cat("f first",x)};f.second <- function(x){cat("f second",x)};obj <-1;attr(obj,"class")  <- "first";f(obj);attr(obj,"class")  <- "second";}
 f first 1
+##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testUseMethodSimple
+#{f<-function(x){UseMethod("f")};f.logical<-function(x){print("logical")};f(TRUE)}
+[1] "logical"
+
 ##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testVectorConstructor
 #{ vector("integer") }
 integer(0)
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/all/AllTests.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/all/AllTests.java
index dc3535b68973d0d1dcb1f0ff23421509f24b640e..609c718e213e19ab7126433d42c860172c492f16 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/all/AllTests.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/all/AllTests.java
@@ -12403,6 +12403,11 @@ public class AllTests extends TestBase {
         assertEval("{f <- function(x){ UseMethod(\"f\",x); };f.first <- function(x){cat(\"f first\",x)};f.second <- function(x){cat(\"f second\",x)};obj <-1;attr(obj,\"class\")  <- \"first\";f(obj);attr(obj,\"class\")  <- \"second\";}");
     }
 
+    @Test
+    public void TestSimpleBuiltins_testUseMethodSimple_24e4b6579385856080f94ac48ee5406f() {
+        assertEval("{f<-function(x){UseMethod(\"f\")};f.logical<-function(x){print(\"logical\")};f(TRUE)}");
+    }
+
     @Test
     public void TestSimpleBuiltins_testVectorConstructor_629fc5f98d9d6659735740d0b0894210() {
         assertEval("{ vector() }");
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/simple/TestSimpleBuiltins.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/simple/TestSimpleBuiltins.java
index 42a620ec19910ad5ffa1842ede2fd13924db113c..0c25e086089d35378afdd078ff507dc6e0e04d44 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/simple/TestSimpleBuiltins.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/simple/TestSimpleBuiltins.java
@@ -2586,6 +2586,7 @@ public class TestSimpleBuiltins extends TestBase {
         // Basic UseMethod
         assertEval("{f <- function(x){ UseMethod(\"f\",x); };" + "f.first <- function(x){cat(\"f first\",x)};" + "f.second <- function(x){cat(\"f second\",x)};" + "obj <-1;"
                         + "attr(obj,\"class\")  <- \"first\";" + "f(obj);" + "attr(obj,\"class\")  <- \"second\";}");
+        assertEval("{f<-function(x){UseMethod(\"f\")};f.logical<-function(x){print(\"logical\")};f(TRUE)}");
     }
 
     @Test