Take: typedef unsigned long long uint64_t; typedef uint64_t cvmx_pow_tag_type_t; typedef uint64_t cvmx_pow_tag_op_t; typedef union { uint64_t u64; struct { uint64_t no_sched : 1; uint64_t unused : 2; uint64_t index :13; cvmx_pow_tag_op_t op : 4; uint64_t unused2 : 2; uint64_t qos : 3; uint64_t grp : 4; cvmx_pow_tag_type_t type : 3; uint64_t tag :32; } s_cn38xx; struct { uint64_t no_sched : 1; cvmx_pow_tag_op_t op : 4; uint64_t unused1 : 16; uint64_t grp : 6; uint64_t unused3 : 3; cvmx_pow_tag_type_t type : 2; uint64_t tag :32; } s_cn68xx_other; } cvmx_pow_tag_req_t; int c; #define CVMX_POW_TAG_OP_SWTAG 0 void f(uint64_t *a, int tag, int tag_type) { cvmx_pow_tag_req_t tag_req; tag_req.u64 = 0; if (c) { tag_req.s_cn68xx_other.op = 0; tag_req.s_cn68xx_other.tag = tag; asm("":"+r"(tag_req.u64)); tag_req.s_cn68xx_other.type = tag_type; } else { tag_req.s_cn38xx.op = 0; tag_req.s_cn38xx.tag = tag; // asm("":"+r"(tag_req.u64)); tag_req.s_cn38xx.type = tag_type; } *a = tag_req.u64; } --- CUT --- On the path which contains the asm, we get: rldimi 4,5,32,30 While on the other path, we get: rldic 5,5,32,29 or 4,4,5 NOTE the asm is just there to force combine not to happen :).