- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
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
Link Copied
7 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I just tried and it didn't work, still compiles out the volatile variable (with -O3 and both of the strict flags set).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
>>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
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
extern const volatile int real_time_clock;
and says it may be modifiable by hardware, but cannot be assigned to.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page