diff --git a/arm-gen.c b/arm-gen.c
index 20ceac4e..91b62c67 100644
--- a/arm-gen.c
+++ b/arm-gen.c
@@ -785,7 +785,7 @@ static void gcall_or_jmp(int is_jmp)
 
 static void gen_bounds_call(int v)
 {
-    Sym *sym = external_global_sym(v, &func_old_type);
+    Sym *sym = external_helper_sym(v);
 
     greloc(cur_text_section, sym, ind, R_ARM_PC24);
     o(0xebfffffe);
@@ -1717,7 +1717,7 @@ done:
       vtop--;
       break;
     case 3:
-      vpush_global_sym(&func_old_type, func);
+      vpush_helper_func(func);
       vrott(3);
       gfunc_call(2);
       vpushi(0);
@@ -2137,7 +2137,7 @@ ST_FUNC void gen_cvt_itof(int t)
         func=TOK___floatdidf;
     }
     if(func_type) {
-      vpush_global_sym(func_type, func);
+      vpushsym(func_type, external_helper_sym(func));
       vswap();
       gfunc_call(1);
       vpushi(0);
@@ -2196,7 +2196,7 @@ void gen_cvt_ftoi(int t)
       func=TOK___fixdfdi;
   }
   if(func) {
-    vpush_global_sym(&func_old_type, func);
+    vpush_helper_func(func);
     vswap();
     gfunc_call(1);
     vpushi(0);
@@ -2277,7 +2277,7 @@ ST_FUNC void gen_vla_alloc(CType *type, int align) {
         vtop->r = TREG_R0;
         o(0xe1a0000d | (vtop->r << 12)); // mov r0,sp
         vswap();
-        vpush_global_sym(&func_old_type, TOK___bound_new_region);
+        vpush_helper_func(TOK___bound_new_region);
         vrott(3);
         gfunc_call(2);
         func_bound_add_epilog = 1;
diff --git a/arm64-gen.c b/arm64-gen.c
index ed09afef..61ca1e36 100644
--- a/arm64-gen.c
+++ b/arm64-gen.c
@@ -662,7 +662,7 @@ static void arm64_gen_bl_or_b(int b)
 
 static void gen_bounds_call(int v)
 {
-    Sym *sym = external_global_sym(v, &func_old_type);
+    Sym *sym = external_helper_sym(v);
 
     greloca(cur_text_section, sym, ind, R_AARCH64_CALL26, 0);
     o(0x94000000); // bl
@@ -1782,7 +1782,7 @@ ST_FUNC void gen_opf(int op)
         case TOK_GT: func = TOK___gttf2; cond = 13; break;
         default: assert(0); break;
         }
-        vpush_global_sym(&func_old_type, func);
+        vpush_helper_func(func);
         vrott(3);
         gfunc_call(2);
         vpushi(0);
@@ -1885,7 +1885,7 @@ ST_FUNC void gen_cvt_itof(int t)
         int func = (f & VT_BTYPE) == VT_LLONG ?
           (f & VT_UNSIGNED ? TOK___floatunditf : TOK___floatditf) :
           (f & VT_UNSIGNED ? TOK___floatunsitf : TOK___floatsitf);
-        vpush_global_sym(&func_old_type, func);
+        vpush_helper_func(func);
         vrott(2);
         gfunc_call(1);
         vpushi(0);
@@ -1913,7 +1913,7 @@ ST_FUNC void gen_cvt_ftoi(int t)
         int func = (t & VT_BTYPE) == VT_LLONG ?
           (t & VT_UNSIGNED ? TOK___fixunstfdi : TOK___fixtfdi) :
           (t & VT_UNSIGNED ? TOK___fixunstfsi : TOK___fixtfsi);
-        vpush_global_sym(&func_old_type, func);
+        vpush_helper_func(func);
         vrott(2);
         gfunc_call(1);
         vpushi(0);
@@ -1947,7 +1947,7 @@ ST_FUNC void gen_cvt_ftof(int t)
         int func = (t == VT_LDOUBLE) ?
             (f == VT_FLOAT ? TOK___extendsftf2 : TOK___extenddftf2) :
             (t == VT_FLOAT ? TOK___trunctfsf2 : TOK___trunctfdf2);
-        vpush_global_sym(&func_old_type, func);
+        vpush_helper_func(func);
         vrott(2);
         gfunc_call(1);
         vpushi(0);
@@ -2061,7 +2061,7 @@ ST_FUNC void gen_vla_alloc(CType *type, int align) {
         vtop->r = TREG_R(0);
         o(0x910003e0 | vtop->r); // mov r0,sp
         vswap();
-        vpush_global_sym(&func_old_type, TOK___bound_new_region);
+        vpush_helper_func(TOK___bound_new_region);
         vrott(3);
         gfunc_call(2);
         func_bound_add_epilog = 1;
diff --git a/c67-gen.c b/c67-gen.c
index 2498aed7..3f963617 100644
--- a/c67-gen.c
+++ b/c67-gen.c
@@ -2254,7 +2254,7 @@ void gen_opi(int op)
       call_func:
 	vswap();
 	/* call generic idiv function */
-	vpush_global_sym(&func_old_type, t);
+	vpush_helper_func(t);
 	vrott(3);
 	gfunc_call(2);
 	vpushi(0);
@@ -2385,7 +2385,7 @@ void gen_opf(int op)
 		// must call intrinsic DP floating point divide
 		vswap();
 		/* call generic idiv function */
-		vpush_global_sym(&func_old_type, TOK__divd);
+		vpush_helper_func(TOK__divd);
 		vrott(3);
 		gfunc_call(2);
 		vpushi(0);
@@ -2396,7 +2396,7 @@ void gen_opf(int op)
 		// must call intrinsic SP floating point divide
 		vswap();
 		/* call generic idiv function */
-		vpush_global_sym(&func_old_type, TOK__divf);
+		vpush_helper_func(TOK__divf);
 		vrott(3);
 		gfunc_call(2);
 		vpushi(0);
diff --git a/i386-gen.c b/i386-gen.c
index 8a0fb355..d2727980 100644
--- a/i386-gen.c
+++ b/i386-gen.c
@@ -345,7 +345,7 @@ static void gen_static_call(int v)
 {
     Sym *sym;
 
-    sym = external_global_sym(v, &func_old_type);
+    sym = external_helper_sym(v);
     oad(0xe8, -4);
     greloc(cur_text_section, sym, ind-4, R_386_PC32);
 }
@@ -985,11 +985,11 @@ ST_FUNC void gen_cvt_ftoi(int t)
 {
     int bt = vtop->type.t & VT_BTYPE;
     if (bt == VT_FLOAT)
-        vpush_global_sym(&func_old_type, TOK___fixsfdi);
+        vpush_helper_func(TOK___fixsfdi);
     else if (bt == VT_LDOUBLE)
-        vpush_global_sym(&func_old_type, TOK___fixxfdi);
+        vpush_helper_func(TOK___fixxfdi);
     else
-        vpush_global_sym(&func_old_type, TOK___fixdfdi);
+        vpush_helper_func(TOK___fixdfdi);
     vswap();
     gfunc_call(1);
     vpushi(0);
@@ -1099,7 +1099,7 @@ ST_FUNC void gen_vla_alloc(CType *type, int align) {
 #endif
     if (use_call)
     {
-        vpush_global_sym(&func_old_type, TOK_alloca);
+        vpush_helper_func(TOK_alloca);
         vswap(); /* Move alloca ref past allocation size */
         gfunc_call(1);
     }
diff --git a/riscv64-gen.c b/riscv64-gen.c
index 33e049ac..413adc30 100644
--- a/riscv64-gen.c
+++ b/riscv64-gen.c
@@ -402,7 +402,7 @@ static void gcall_or_jmp(int docall)
 
 static void gen_bounds_call(int v)
 {
-    Sym *sym = external_global_sym(v, &func_old_type);
+    Sym *sym = external_helper_sym(v);
 
     greloca(cur_text_section, sym, ind, R_RISCV_CALL_PLT, 0);
     o(0x17 | (1 << 7));   // auipc TR, 0 %call(func)
@@ -1125,7 +1125,7 @@ ST_FUNC void gen_opf(int op)
         case TOK_GT: func = TOK___gttf2; cond = 13; break;
         default: assert(0); break;
         }
-        vpush_global_sym(&func_old_type, func);
+        vpush_helper_func(func);
         vrott(3);
         gfunc_call(2);
         vpushi(0);
@@ -1213,7 +1213,7 @@ ST_FUNC void gen_cvt_itof(int t)
         int func = l ?
           (u ? TOK___floatunditf : TOK___floatditf) :
           (u ? TOK___floatunsitf : TOK___floatsitf);
-        vpush_global_sym(&func_old_type, func);
+        vpush_helper_func(func);
         vrott(2);
         gfunc_call(1);
         vpushi(0);
@@ -1239,7 +1239,7 @@ ST_FUNC void gen_cvt_ftoi(int t)
         int func = l ?
           (u ? TOK___fixunstfdi : TOK___fixtfdi) :
           (u ? TOK___fixunstfsi : TOK___fixtfsi);
-        vpush_global_sym(&func_old_type, func);
+        vpush_helper_func(func);
         vrott(2);
         gfunc_call(1);
         vpushi(0);
@@ -1281,7 +1281,7 @@ ST_FUNC void gen_cvt_ftof(int dt)
                 vtop->r2 = 1 + vtop->r;
             }
         }
-        vpush_global_sym(&func_old_type, func);
+        vpush_helper_func(func);
         gcall_or_jmp(1);
         vtop -= 2;
         vpushi(0);
@@ -1342,7 +1342,7 @@ ST_FUNC void gen_vla_alloc(CType *type, int align)
         vtop->r = TREG_R(0);
         o(0x00010513); /* mv a0,sp */
         vswap();
-        vpush_global_sym(&func_old_type, TOK___bound_new_region);
+        vpush_helper_func(TOK___bound_new_region);
         vrott(3);
         gfunc_call(2);
         func_bound_add_epilog = 1;
diff --git a/tcc.h b/tcc.h
index ccb3b603..3c130ec0 100644
--- a/tcc.h
+++ b/tcc.h
@@ -1437,10 +1437,11 @@ ST_FUNC void vpushi(int v);
 ST_FUNC ElfSym *elfsym(Sym *);
 ST_FUNC void update_storage(Sym *sym);
 ST_FUNC Sym *external_global_sym(int v, CType *type);
+ST_FUNC Sym *external_helper_sym(int v);
+ST_FUNC void vpush_helper_func(int v);
 ST_FUNC void vset(CType *type, int r, int v);
 ST_FUNC void vset_VT_CMP(int op);
 ST_FUNC void vswap(void);
-ST_FUNC void vpush_global_sym(CType *type, int v);
 ST_FUNC void vrote(SValue *e, int n);
 ST_FUNC void vrott(int n);
 ST_FUNC void vrotb(int n);
diff --git a/tccgen.c b/tccgen.c
index 3b2201ca..61c538e6 100644
--- a/tccgen.c
+++ b/tccgen.c
@@ -80,7 +80,7 @@ ST_DATA int func_var; /* true if current function is variadic (used by return in
 ST_DATA int func_vc;
 static int last_line_num, new_file, func_ind; /* debug info control */
 ST_DATA const char *funcname;
-ST_DATA CType int_type, func_old_type, char_type, char_pointer_type, func_mem_move, void_type, void_ptr_type;
+ST_DATA CType int_type, func_old_type, char_type, char_pointer_type;
 static CString initstr;
 
 #if PTR_SIZE == 4
@@ -800,14 +800,6 @@ ST_FUNC void tccgen_init(TCCState *s1)
     char_pointer_type = char_type;
     mk_pointer(&char_pointer_type);
 
-    void_type.t = VT_VOID;
-    void_ptr_type = void_type;
-    mk_pointer(&void_ptr_type);
-    func_mem_move.t = VT_FUNC;
-    func_mem_move.ref = sym_push(SYM_FIELD, &void_ptr_type, 0, 0);
-    func_mem_move.ref->f.func_call = FUNC_CDECL;
-    func_mem_move.ref->f.func_type = FUNC_OLD;
-
     func_old_type.t = VT_FUNC;
     func_old_type.ref = sym_push(SYM_FIELD, &int_type, 0, 0);
     func_old_type.ref->f.func_call = FUNC_CDECL;
@@ -1493,6 +1485,20 @@ ST_FUNC Sym *external_global_sym(int v, CType *type)
     return s;
 }
 
+/* create an external reference with no specific type similar to asm labels.
+   This avoids type conflicts if the symbol is used from C too */
+ST_FUNC Sym *external_helper_sym(int v)
+{
+    CType ct = { VT_ASM, NULL };
+    return external_global_sym(v, &ct);
+}
+
+/* push a reference to an helper function (such as memmove) */
+ST_FUNC void vpush_helper_func(int v)
+{
+    vpushsym(&func_old_type, external_helper_sym(v));
+}
+
 /* Merge symbol attributes.  */
 static void merge_symattr(struct SymAttr *sa, struct SymAttr *sa1)
 {
@@ -1681,12 +1687,6 @@ static Sym *external_sym(int v, CType *type, int r, AttributeDef *ad)
     return s;
 }
 
-/* push a reference to global symbol v */
-ST_FUNC void vpush_global_sym(CType *type, int v)
-{
-    vpushsym(type, external_global_sym(v, type));
-}
-
 /* save registers up to (vtop - n) stack entry */
 ST_FUNC void save_regs(int n)
 {
@@ -1904,7 +1904,7 @@ static void gen_bounded_ptr_add(void)
       vpushv(&vtop[-1]);
       vrott(3);
     }
-    vpush_global_sym(&func_old_type, TOK___bound_ptr_add);
+    vpush_helper_func(TOK___bound_ptr_add);
     vrott(3);
     gfunc_call(2);
     vtop -= save;
@@ -1941,7 +1941,7 @@ static void gen_bounded_ptr_deref(void)
         /* may happen with struct member access */
         return;
     }
-    sym = external_global_sym(func, &func_old_type);
+    sym = external_helper_sym(func);
     if (!sym->c)
         put_extern_sym(sym, NULL, 0, 0);
     /* patch relocation */
@@ -1998,7 +1998,7 @@ ST_FUNC void gbound_args(int nb_args)
           || v == TOK___sigsetjmp
 #endif
           ) {
-            vpush_global_sym(&func_old_type, TOK___bound_setjmp);
+            vpush_helper_func(TOK___bound_setjmp);
             vpushv(sv + 1);
             gfunc_call(1);
             func_bound_add_epilog = 1;
@@ -2415,7 +2415,7 @@ static void gen_opl(int op)
 #endif
     gen_func:
         /* call generic long long function */
-        vpush_global_sym(&func_old_type, func);
+        vpush_helper_func(func);
         vrott(3);
         gfunc_call(2);
         vpushi(0);
@@ -3379,13 +3379,13 @@ static void gen_cvt_itof1(int t)
         (VT_LLONG | VT_UNSIGNED)) {
 
         if (t == VT_FLOAT)
-            vpush_global_sym(&func_old_type, TOK___floatundisf);
+            vpush_helper_func(TOK___floatundisf);
 #if LDOUBLE_SIZE != 8
         else if (t == VT_LDOUBLE)
-            vpush_global_sym(&func_old_type, TOK___floatundixf);
+            vpush_helper_func(TOK___floatundixf);
 #endif
         else
-            vpush_global_sym(&func_old_type, TOK___floatundidf);
+            vpush_helper_func(TOK___floatundidf);
         vrott(2);
         gfunc_call(1);
         vpushi(0);
@@ -3407,13 +3407,13 @@ static void gen_cvt_ftoi1(int t)
         /* not handled natively */
         st = vtop->type.t & VT_BTYPE;
         if (st == VT_FLOAT)
-            vpush_global_sym(&func_old_type, TOK___fixunssfdi);
+            vpush_helper_func(TOK___fixunssfdi);
 #if LDOUBLE_SIZE != 8
         else if (st == VT_LDOUBLE)
-            vpush_global_sym(&func_old_type, TOK___fixunsxfdi);
+            vpush_helper_func(TOK___fixunsxfdi);
 #endif
         else
-            vpush_global_sym(&func_old_type, TOK___fixunsdfdi);
+            vpush_helper_func(TOK___fixunsdfdi);
         vrott(2);
         gfunc_call(1);
         vpushi(0);
@@ -3904,13 +3904,13 @@ ST_FUNC void vstore(void)
             /* address of memcpy() */
 #ifdef TCC_ARM_EABI
             if(!(align & 7))
-                vpush_global_sym(&func_old_type, TOK_memmove8);
+                vpush_helper_func(TOK_memmove8);
             else if(!(align & 3))
-                vpush_global_sym(&func_old_type, TOK_memmove4);
+                vpush_helper_func(TOK_memmove4);
             else
 #endif
             /* Use memmove, rather than memcpy, as dest and src may be same: */
-            vpush_global_sym(&func_mem_move, TOK_memmove);
+            vpush_helper_func(TOK_memmove);
 
             vswap();
             /* source */
@@ -7363,7 +7363,7 @@ static void init_putz(init_params *p, unsigned long c, int size)
     if (p->sec) {
         /* nothing to do because globals are already set to zero */
     } else {
-        vpush_global_sym(&func_old_type, TOK_memset);
+        vpush_helper_func(TOK_memset);
         vseti(VT_LOCAL, c);
 #ifdef TCC_TARGET_ARM
         vpushs(size);
diff --git a/x86_64-gen.c b/x86_64-gen.c
index 44ff3e51..57e24718 100644
--- a/x86_64-gen.c
+++ b/x86_64-gen.c
@@ -653,7 +653,7 @@ static void gcall_or_jmp(int is_jmp)
 
 static void gen_bounds_call(int v)
 {
-    Sym *sym = external_global_sym(v, &func_old_type);
+    Sym *sym = external_helper_sym(v);
     oad(0xe8, 0);
 #ifdef TCC_TARGET_PE
     greloca(cur_text_section, sym, ind-4, R_X86_64_PC32, -4);
@@ -1022,7 +1022,7 @@ void gfunc_epilog(void)
     v = -loc;
 
     if (v >= 4096) {
-        Sym *sym = external_global_sym(TOK___chkstk, &func_old_type);
+        Sym *sym = external_helper_sym(TOK___chkstk);
         oad(0xb8, v); /* mov stacksize, %eax */
         oad(0xe8, 0); /* call __chkstk, (does the stackframe too) */
         greloca(cur_text_section, sym, ind-4, R_X86_64_PC32, -4);
@@ -2209,7 +2209,7 @@ ST_FUNC void gen_vla_alloc(CType *type, int align) {
 #endif
     if (use_call)
     {
-        vpush_global_sym(&func_old_type, TOK_alloca);
+        vpush_helper_func(TOK_alloca);
         vswap(); /* Move alloca ref past allocation size */
         gfunc_call(1);
     }