Bug 1724997

Summary: gcc: optimization breaks guile scm_bytevector_ieee_single_set! function on ppc64le
Product: Red Hat Enterprise Linux 8 Reporter: Tomas Korbar <tkorbar>
Component: gccAssignee: Marek Polacek <mpolacek>
gcc sub component: system-version QA Contact: qe-baseos-tools-bugs
Status: CLOSED NOTABUG Docs Contact:
Severity: unspecified    
Priority: unspecified CC: ahajkova, fweimer, jakub, law, mlichvar, ohudlick
Version: 8.1   
Target Milestone: rc   
Target Release: 8.0   
Hardware: ppc64le   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2019-07-17 12:33:38 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On:    
Bug Blocks: 1641042    
Attachments:
Description Flags
Reproducer of bug in guile
none
patch with workaround
none
Rpm of patched guile
none
Instructions executed by code with bug
none
Instructions executed by code without bug none

Description Tomas Korbar 2019-06-28 08:46:28 UTC
Created attachment 1585494 [details]
Reproducer of bug in guile

Description of problem:
If float_to_foreign_endianness function, from file libguile/bytevectors.c, is compiled with optimalization, then it breaks guiles scm_bytevector_ieee_single_set! function if used with big endianess argument.

Version-Release number of selected component (if applicable):
guile-2.0.14-7.el8.ppc64le
gcc-8.3.1-4.4.el8.ppc64le

How reproducible:
Always

Steps to Reproduce:
1. # dnf install guile
Note:  this guile is compiled with standard -O2 optimilization from '%configure' rpm macro
2. $ guile ./reproducer

Actual results:
#vu8(0 0 0 0 0 0 0 0)

Expected results:
#vu8(64 72 245 195 0 0 0 0)

Additional info:
When i build guile with patch which i will add to attachments the function started working as expected. For disabling optimilization i used '#pragma GCC optimize("O0")'. This problem occurs only on ppc64le architecture.

Comment 1 Tomas Korbar 2019-06-28 08:52:16 UTC
Created attachment 1585498 [details]
patch with workaround

This patch forces gcc to not optimalize float_to_foreign_endianness function.

Comment 2 Tomas Korbar 2019-06-28 12:32:50 UTC
Created attachment 1585617 [details]
Rpm of patched guile

I'm adding rpm of patched guile just to prove that workaround is working. Feel free to reach me if you will need anything else.

Comment 3 Marek Polacek 2019-07-02 16:03:14 UTC
Have you tried -fsanitize=undefined and/or -fsanitize=address?

Comment 4 Tomas Korbar 2019-07-08 08:17:48 UTC
Hi Marek,
After your suggestion i tried and it found some leaks. Although i do not think they are related to this issue, i was little surprised when i ran guile through valgrind and the problem disappeared. So i will further investigate those leaks and then tell you my conclusions.

Comment 5 Tomas Korbar 2019-07-10 09:14:16 UTC
So after further investigation of leaks i can say that they are not related to this problem.
I recorded assembly instructions around code which were executed by non-optimalized and optimalized code.
I do not really know anything about assembly so i hope it will be of more use to you than to me.

Comment 6 Tomas Korbar 2019-07-10 09:24:38 UTC
Created attachment 1589046 [details]
Instructions executed by code with bug

I scripted gdb to log assembly instructions and this is the output of code which causes bug.

Comment 7 Tomas Korbar 2019-07-10 09:28:55 UTC
Created attachment 1589047 [details]
Instructions executed by code without bug

These are instructions executed by non-optimalized code.

Comment 8 Marek Polacek 2019-07-16 16:04:04 UTC
Tomas, trying to reproduce this, I see:

# rpm -q gcc guile
gcc-8.3.1-4.4.el8.ppc64le
guile-2.0.14-7.el8.ppc64le

# guile ./reproducer 
;;; note: auto-compilation is enabled, set GUILE_AUTO_COMPILE=0
;;;       or pass the --no-auto-compile argument to disable.
;;; compiling /root/./reproducer
;;; compiled /root/.cache/guile/ccache/2.0-LE-8-2.0/root/reproducer.go
#vu8(64 72 245 195 0 0 0 0)

Which is the expected result.  What's up with that?

Comment 9 Tomas Korbar 2019-07-17 12:33:38 UTC
Hi Marek,
I suppose you used bare metal machine.
I did that now as well and the bug does not occur there. I'm sorry that i did not try it before.
It seems that this issue is caused by virtualization.
Thanks for your help anyway.