Hello, I tried compiling your code with g++ 7.1 and clang 4 and both generate the same code (on Intel) If you prepend `static` to the template declaration you'll get something similar to what you want (i.e: replace `void f(const T& x) __attribute__((noinline));` with `static void f(const T& x) __attribute__((noinline));`) Out of curiosity, why are you using the `noinline` attribute? Regards, Juan. 2017-06-28 5:56 GMT-03:00 Wilhelm Meier <wilhelm.meier@xxxxxxxx>: > Hi all, > > in the following example g++ (at least avr-g++) doesn't optimize the > call f(n2) to use a single value register as in the case of f(n1). Is > this a bug or can one use some option to enforce that. > > Version: gcc-7.1.0 > > #include <cstdint> > #include <type_traits> > > struct A { > A() = default; > A(const volatile A& o) : m1(o.m1) {} > uint8_t m1{0}; > }; > > volatile uint8_t v; > > template<typename T> > void f(const T& x) __attribute__((noinline)); > template<typename T> > void f(const T& x) { > if constexpr(std::is_same<std::remove_cv_t<T>, A>::value) { > v = x.m1; > } > else { > v = x; > } > } > > volatile uint8_t v1; > uint8_t n1; > > volatile A v2; > A n2; > > int main() { > f(v1); > f(n1); > f(v2); > f(n2); > } > > The generated machine code: > > .text > .type void f<unsigned char>(unsigned char const&) [clone > .isra.0], @function > void f<unsigned char>(unsigned char const&) [clone .isra.0]: > sts v,r24 ; v, ISRA.2 > ret > .size void f<unsigned char>(unsigned char const&) [clone > .isra.0], .-void f<unsigned char>(unsigned char const&) [clone .isra. > 0] > .section .text._Z1fIVhEvRKT_,"axG",@progbits,void > f<unsigned char volatile>(unsigned char volatile const&),comdat > .weak void f<unsigned char volatile>(unsigned char volatile > const&) > .type void f<unsigned char volatile>(unsigned char volatile > const&), @function > void f<unsigned char volatile>(unsigned char volatile const&): > movw r30,r24 ; , x > ld r24,Z ; _1, *x_3(D) > sts v,r24 ; v, _1 > ret > .size void f<unsigned char volatile>(unsigned char volatile > const&), .-void f<unsigned char volatile>(unsigned char volatile c > onst&) > .section .text._Z1fIV1AEvRKT_,"axG",@progbits,void f<A > volatile>(A volatile const&),comdat > .weak void f<A volatile>(A volatile const&) > .type void f<A volatile>(A volatile const&), @function > void f<A volatile>(A volatile const&): > movw r30,r24 ; , x > ld r24,Z ; _1, x_3(D)->m1 > sts v,r24 ; v, _1 > ret > .size void f<A volatile>(A volatile const&), .-void f<A > volatile>(A volatile const&) > .section .text._Z1fI1AEvRKT_,"axG",@progbits,void f<A>(A > const&),comdat > .weak void f<A>(A const&) > .type void f<A>(A const&), @function > void f<A>(A const&): > movw r30,r24 ; , x > ld r24,Z ; _1, x_3(D)->m1 > sts v,r24 ; v, _1 > ret > .size void f<A>(A const&), .-void f<A>(A const&) > .section .text.startup,"ax",@progbits > .type main, @function > main: > ldi r24,lo8(v1) ; , > ldi r25,hi8(v1) ; , > call void f<unsigned char volatile>(unsigned char volatile > const&) ; > lds r24,n1 ; , n1 > call void f<unsigned char>(unsigned char const&) [clone .isra.0] > ; > ldi r24,lo8(v2) ; , > ldi r25,hi8(v2) ; , > call void f<A volatile>(A volatile const&) ; > ldi r24,lo8(n2) ; , > ldi r25,hi8(n2) ; , > call void f<A>(A const&) ; > ldi r25,0 ; > ldi r24,0 ; > ret > .size main, .-main > .section .bss > .type n2, @object > .size n2, 1 > n2: > .zero 1 >