diff --git a/tccgen.c b/tccgen.c
index 8f2f1bd3..71297be0 100644
--- a/tccgen.c
+++ b/tccgen.c
@@ -790,11 +790,14 @@ ST_FUNC int gv(int rc)
             r = get_reg(rc);
 #ifdef TCC_TARGET_X86_64
             if (((vtop->type.t & VT_BTYPE) == VT_QLONG) || ((vtop->type.t & VT_BTYPE) == VT_QFLOAT)) {
+                int addr_type = VT_LLONG, load_size = 8, load_type = ((vtop->type.t & VT_BTYPE) == VT_QLONG) ? VT_LLONG : VT_DOUBLE;
 #else
             if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
+                int addr_type = VT_INT, load_size = 4, load_type = VT_INT;
 #endif
-                int r2;
+                int r2, original_type;
                 unsigned long long ll;
+                original_type = vtop->type.t;
                 /* two register type load : expand to two words
                    temporarily */
 #ifndef TCC_TARGET_X86_64
@@ -809,11 +812,6 @@ ST_FUNC int gv(int rc)
 #endif
                 if (r >= VT_CONST || /* XXX: test to VT_CONST incorrect ? */
                            (vtop->r & VT_LVAL)) {
-#ifdef TCC_TARGET_X86_64
-                    int addr_type = VT_LLONG, load_size = 8, load_type = ((vtop->type.t & VT_BTYPE) == VT_QLONG) ? VT_LLONG : VT_DOUBLE;
-#else
-                    int addr_type = VT_INT, load_size = 4, load_type = VT_INT;
-#endif
                     /* We do not want to modifier the long long
                        pointer here, so the safest (and less
                        efficient) is to save all the other registers
@@ -845,6 +843,7 @@ ST_FUNC int gv(int rc)
                 vpop();
                 /* write second register */
                 vtop->r2 = r2;
+                vtop->type.t = original_type;
             } else if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) {
                 int t1, t;
                 /* lvalue of scalar type : need to use lvalue type
diff --git a/tests/abitest.c b/tests/abitest.c
index aa11cc74..7e3d34a8 100644
--- a/tests/abitest.c
+++ b/tests/abitest.c
@@ -38,10 +38,10 @@ static int run_callback(const char *src, callback_type callback) {
   return result;
 }
 
-#define RET_PRIMITIVE_TEST(name, type) \
+#define RET_PRIMITIVE_TEST(name, type, val) \
   static int ret_ ## name ## _test_callback(void *ptr) { \
     type (*callback) (type) = (type(*)(type))ptr; \
-    type x = 29; \
+    type x = val; \
     type y = callback(x); \
     return (y == x+x) ? 0 : -1; \
   } \
@@ -51,11 +51,11 @@ static int run_callback(const char *src, callback_type callback) {
     return run_callback(src, ret_ ## name ## _test_callback); \
   }
 
-RET_PRIMITIVE_TEST(int, int)
-RET_PRIMITIVE_TEST(longlong, long long)
-RET_PRIMITIVE_TEST(float, float)
-RET_PRIMITIVE_TEST(double, double)
-RET_PRIMITIVE_TEST(longdouble, long double)
+RET_PRIMITIVE_TEST(int, int, 70000)
+RET_PRIMITIVE_TEST(longlong, long long, 4333369356528LL)
+RET_PRIMITIVE_TEST(float, float, 63.0)
+RET_PRIMITIVE_TEST(double, double, 14789798.0)
+RET_PRIMITIVE_TEST(longdouble, long double, 378943892.0)
 
 /*
  * ret_2float_test: