[LLVMbugs] [Bug 4210] New: optimisation breaks AES code from MySQL

bugzilla-daemon at cs.uiuc.edu bugzilla-daemon at cs.uiuc.edu
Wed May 13 03:48:39 PDT 2009


           Summary: optimisation breaks AES code from MySQL
           Product: clang
           Version: unspecified
          Platform: Macintosh
        OS/Version: MacOS X
            Status: NEW
          Severity: normal
          Priority: P2
         Component: LLVM Codegen
        AssignedTo: unassignedclangbugs at nondot.org
        ReportedBy: df at sun.com
                CC: llvmbugs at cs.uiuc.edu

Created an attachment (id=2993)
 --> (http://llvm.org/bugs/attachment.cgi?id=2993)
standalone test case

When building MySQL 5.0 with clang (at least for a Mac OS X x86_64 target),
turning on optimisation (-O1 or above) breaks AES encryption/decryption
functionality as compared to a build without optimisation (-O0).

The attached standalone test case was extracted from the MySQL 5.0 code base.
I'm sorry that it is still quite large, I've not had much luck with extracting
the individual bit that is optimised badly, but I have reduced it to one code
path in one function that shows the problem.

To compile:

clang -o rijndael_test_O0  rijndael_bug.c -O0
clang -o rijndael_test_O1  rijndael_bug.c -O0
clang -o rijndael_test_O1V rijndael_bug.c -O0 -DVOLATILE=volatile

The output of rijndael_test_O0 is as follows:

39 25 cc 14 d7 5 ef 4e e9 c7 fb cd 40 22 ed 29 

The output of rijndael_test_O1 is as follows:

39 25 cc 14 d7 5 ef 4e e9 c7 fb d1 40 22 ed 29 

Note that the 12th byte is different.

The output of rijndael_test_O1V is the same as rijndael_test_O0:

39 25 cc 14 d7 5 ef 4e e9 c7 fb cd 40 22 ed 29 

The difference between O1 and O1V is that a "volatile" statement is added to
the variable declaration in the rijndaelEncrypt function. In fact it seems to
be sufficient to declare *one* of these variables volatile to make the problem
go away.

I have inserted one comment into the source:
    /* Value of t1 will be different depending on optimisation */

At this location, a value t1 is computed as follows:
    t1= (Te0[(s1 >> 24)  ] ^
         Te1[(s2 >> 16) & 0xff] ^
         Te2[(s3 >>     8) & 0xff] ^
         Te3[(s0         ) & 0xff] ^

The result of this calculation is different when optimisation is turned on. I
wasn't able to reproduce this with the snippet on its own.

The full version of the rijndaelEncrypt function in the MySQL code base has an
alternate code path that can be enabled with -DFULL_UNROLL. I removed this
codepath from the test case because it does not exhibit the problem.

Configure bugmail: http://llvm.org/bugs/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.

More information about the llvm-bugs mailing list