int a, rcx;
        Prog *p1;
        uvlong sc;
+       Type *tcount;
 
        a = optoas(op, nl->type);
 
 
        rcx = reg[D_CX];
        nodreg(&n1, types[TUINT32], D_CX);
+       
+       // Allow either uint32 or uint64 as shift type,
+       // to avoid unnecessary conversion from uint32 to uint64
+       // just to do the comparison.
+       tcount = types[simtype[nr->type->etype]];
+       if(tcount->etype < TUINT32)
+               tcount = types[TUINT32];
+
        regalloc(&n1, nr->type, &n1);           // to hold the shift type in CX
-       regalloc(&n3, types[TUINT64], &n1);     // to clear high bits of CX
+       regalloc(&n3, tcount, &n1);     // to clear high bits of CX
 
        nodreg(&cx, types[TUINT64], D_CX);
        memset(&oldcx, 0, sizeof oldcx);
                regalloc(&oldcx, types[TUINT64], N);
                gmove(&cx, &oldcx);
        }
+       cx.type = tcount;
 
        if(samereg(&cx, res))
                regalloc(&n2, nl->type, N);
        regfree(&n3);
 
        // test and fix up large shifts
-       nodconst(&n3, types[TUINT64], nl->type->width*8);
-       gins(optoas(OCMP, types[TUINT64]), &n1, &n3);
-       p1 = gbranch(optoas(OLT, types[TUINT64]), T);
+       nodconst(&n3, tcount, nl->type->width*8);
+       gins(optoas(OCMP, tcount), &n1, &n3);
+       p1 = gbranch(optoas(OLT, tcount), T);
        if(op == ORSH && issigned[nl->type->etype]) {
                nodconst(&n3, types[TUINT32], nl->type->width*8-1);
                gins(a, &n3, &n2);
        gins(a, &n1, &n2);
 
        if(oldcx.op != 0) {
+               cx.type = types[TUINT64];
                gmove(&oldcx, &cx);
                regfree(&oldcx);
        }