I tried recent versions of gcc (9.2.1) and clang (9.0.1) for such code:
//pure.cpp
int square (int x) __attribute__ ((pure));
int square (int x)
{
        return  x * x;
}
//test.cpp
#include <stdio.h>
int square (int x) __attribute__ ((pure));
int main(int argc, char *argv[])
{
        const int same = argc;
        printf("result: %d\n", square(same));
        printf("result2: %d\n", square(same));
}
and compile it like this:
g++ -ggdb -Ofast -c test.cpp
g++ -ggdb -Ofast -c pure.cpp
g++ -ggdb -Ofast -o test test.o pure.o
as result I see:
    1043:       e8 58 01 00 00          callq  11a0 <_Z6squarei>
    1048:       48 8d 3d b5 0f 00 00    lea    0xfb5(%rip),%rdi        # 2004 <_IO_stdin_used+0x4>
    104f:       89 c6                   mov    %eax,%esi
    1051:       31 c0                   xor    %eax,%eax
    1053:       e8 d8 ff ff ff          callq  1030 <printf@plt>
        printf("result2: %d\n", square(same));
    1058:       89 ef                   mov    %ebp,%edi
    105a:       e8 41 01 00 00          callq  11a0 <_Z6squarei>
    105f:       48 8d 3d aa 0f 00 00    lea    0xfaa(%rip),%rdi        # 2010 <_IO_stdin_used+0x10>
    1066:       89 c6                   mov    %eax,%esi
    1068:       31 c0                   xor    %eax,%eax
    106a:       e8 c1 ff ff ff          callq  1030 <printf@plt>
as you can see there are two calls of _Z6squarei,
but why? I marked function as pure, and use the same argument,
why gcc and clang can not remove the second call?