Intel® C++ Compiler
Community support and assistance for creating C++ code that runs on platforms based on Intel® processors.

Unsafe optimization?

yshkolnikov
Beginner
487 Views
Two questions: does intel publish results of verification/compiler correctness testing for ICC?
Also, I'm looking at the assembly code generated by ICC (on OS X 10.6.4) and at least the following looks like an unsafe optimization (in the second compile) because it compiles away a volatile variable (VS2008 on windows, and gcc4.5 prerelease on OS X 10.6.4 conserve it at max optimization):
Test.cpp listing
const volatile int shift=13;
int main() {
int i=3;
if (i>shift) return 14;
else return 1;
}

First compile (-O0):
.globl _main
_main:
L_B1.1: # Preds L_B1.0
L____tag_value__main.1: #2.12
pushq %rbp #2.12
movq %rsp, %rbp #2.12
L____tag_value__main.2: #
subq $16, %rsp #2.12
movl $3, -16(%rbp) #3.8
movl _shift(%rip), %eax #4.9
movl -16(%rbp), %edx #4.7
cmpl %eax, %edx #4.9
jle L_B1.3 # Prob 50% #4.9
# LOE
L_B1.2: # Preds L_B1.1
movl $14, %eax #4.23
leave #4.23
L____tag_value__main.4: #
ret #4.23
L____tag_value__main.5: #
# LOE
L_B1.3: # Preds L_B1.1
movl $1, %eax #5.15
leave #5.15
L____tag_value__main.6: #
ret #5.15
.align 1
L____tag_value__main.7: #
# LOE
# mark_end;
.section __DATA, __data
# -- End _main

Second compile (-O3):
# -- Begin _main
# mark_begin;
.align 4
.globl _main
_main:
L_B1.1: # Preds L_B1.0
L____tag_value__main.1: #2.12
pushq %rbp #2.12
L____tag_value__main.2: #
movq %rsp, %rbp #2.12
L____tag_value__main.3: #
andq $-128, %rsp #2.12
subq $128, %rsp #2.12
movl $3, %edi #2.12
L____tag_value__main.5: #2.12
call ___intel_new_proc_init_T #2.12
L____tag_value__main.6: #
# LOE rbx r12 r13 r14 r15
L_B1.4: # Preds L_B1.1
stmxcsr (%rsp) #2.12
orl $32832, (%rsp) #2.12
ldmxcsr (%rsp) #2.12
movl $1, %eax #5.15
movq %rbp, %rsp #5.15
popq %rbp #5.15
L____tag_value__main.7: #
ret #5.15
.align 4
L____tag_value__main.9: #
# LOE
# mark_end;
.section __DATA, __data
# -- End _main
0 Kudos
7 Replies
TimP
Honored Contributor III
487 Views
If you're comparing icc and gcc, are you using equally aggressive options for both?
icc -O2 is roughly equivalent to gcc -O3 -ffast-math -fnocx-limited-range -funroll-loops --param max-unroll-times=2, so icc -O3 is more aggressive than any possibilities offered by the other compilers.
icl /fp:source -O1 is roughly equivalent to cl /fp:fast -O2.
I suppose if you are concerned about treatment of volatiles you would use something like icl /fp:strict /Qfp-speculation:strict.
0 Kudos
yshkolnikov
Beginner
487 Views
I just tried and it didn't work, still compiles out the volatile variable (with -O3 and both of the strict flags set).
0 Kudos
jimdempseyatthecove
Honored Contributor III
487 Views
>>Two questions: does intel publish results of verification/compiler correctness testing for ICC?
Also, I'm looking at the assembly code generated by ICC (on OS X 10.6.4) and at least the following looks like an unsafe optimization (in the second compile) because it compiles away a volatile variable (VS2008 on windows, and gcc4.5 prerelease on OS X 10.6.4 conserve it at max optimization):
Test.cpp listing
const volatile int shift=13;
int main() {
int i=3;
if (i>shift) return 14;
else return 1;
}
<<

Your "volatile" variable shift is also const, const trumps volatile (variable cannot change either by current thread or other thread on system). Therefore, it is subject to be optimized out of the test.

Jim Dempsey
0 Kudos
Brandon_H_Intel
Employee
487 Views
I don't think that saying const trumps volatile is really accurate. Certainly, in my Stroustrup C++ book there's an example of both being used together. Let me investigate this further.
0 Kudos
tydeman
Beginner
487 Views
The C standard in section 6.7.3 Type qualifiers has an example:
extern const volatile int real_time_clock;
and says it may be modifiable by hardware, but cannot be assigned to.
0 Kudos
jimdempseyatthecove
Honored Contributor III
487 Views
Thanks for the example. Your example also has extern linkage.

The sample code given by the OP had the const volatile int located within the scope of the function without extern. Further, this sample did not show the reference or address of being passed out of the function. If the reference or address of this variable is not passed out of the function then, perhapse, the assumption thatthe variableis immutable holds true. I would think this _specific_ situation is covered the the C++ specification.

Jim
0 Kudos
yshkolnikov
Beginner
487 Views
Just tried it. The extern qualifier doesn't make a difference. Volatiles need to be preserved because they can change their value at any time, even when executing the same function in which the volatile was defined.
0 Kudos
Reply