r186490 - Propagate alignment for _Complex

JF Bastien jfb at google.com
Wed Jul 17 18:14:57 PDT 2013


Thanks. I'm not near a computer, I'll add a triple to the test later this
evening.
 On Jul 17, 2013 6:08 PM, "Richard Smith" <richard at metafoo.co.uk> wrote:

> On Wed, Jul 17, 2013 at 5:45 PM, JF Bastien <jfb at google.com> wrote:
>
>> The issue seems to be that i386 sets double alignment at 32-bits, and
>> that's used in ASTContext.cpp (case Type::Complex) to determine a _Complex
>> double's alignment. I'm not sure if that's the right thing to do: the C
>> standard says "alignment requirements as an array type containing exactly
>> two elements of the corresponding real type", and I can't figure out if
>> arrays have extra alignment requirements compared to their base type.
>>
>
> C11 6.5.3.4p3: "The _Alignof operator yields the alignment requirement of
> its operand type. [...] When applied to an array
> type, the result is the alignment requirement of the element type."
>
>
>> A simple workaround is to run the test with a specific triple, say
>> x86-64-unknown-unknown. Should I commit such a change, until the above can
>> be resolved?
>>
>
> Adding a triple to the test is correct regardless of i386-specific
> behavior: there's no reason to think that the alignment of double should be
> 8 for all targets.
>
>
>> On Wed, Jul 17, 2013 at 5:05 PM, Quentin Colombet <qcolombet at apple.com>wrote:
>>
>>> Hi jfb,
>>>
>>> This breaks a buildbot:
>>> http://lab.llvm.org:8013/builders/clang-i386-darwin11-RA/builds/1255
>>>
>>> ******************** TEST 'Clang :: CodeGen/volatile-complex.c' FAILED ********************
>>> Script:
>>> --
>>> /Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/build.clang-i386-darwin11-RA/clang-build/Release+Asserts/bin/clang -cc1 -internal-isystem /Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/build.clang-i386-darwin11-RA/clang-build/Release+Asserts/bin/../lib/clang/3.4/include -emit-llvm /Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/build.clang-i386-darwin11-RA/clang.src/test/CodeGen/volatile-complex.c -o - | FileCheck /Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/build.clang-i386-darwin11-RA/clang.src/test/CodeGen/volatile-complex.c
>>> --
>>> Exit Code: 1
>>> Command Output (stderr):
>>> --
>>> /Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/build.clang-i386-darwin11-RA/clang.src/test/CodeGen/volatile-complex.c:25:17: error: expected string not found in input
>>>  // CHECK-NEXT: load volatile double* getelementptr inbounds ({ double, double }* @cd, i32 0, i32 1), align 8
>>>                 ^
>>> <stdin>:26:2: note: scanning from here
>>>  %cd.imag = load volatile double* getelementptr inbounds ({ double, double }* @cd, i32 0, i32 1), align 4
>>>  ^
>>> <stdin>:26:13: note: possible intended match here
>>>  %cd.imag = load volatile double* getelementptr inbounds ({ double, double }* @cd, i32 0, i32 1), align 4
>>>             ^
>>> --
>>>
>>> ********************
>>>
>>> Could you have a look please?
>>>
>>> Thanks,
>>>
>>>  -Quentin
>>>
>>> On Jul 16, 2013, at 10:57 PM, JF Bastien <jfb at google.com> wrote:
>>>
>>> Author: jfb
>>> Date: Wed Jul 17 00:57:42 2013
>>> New Revision: 186490
>>>
>>> URL: http://llvm.org/viewvc/llvm-project?rev=186490&view=rev
>>> Log:
>>> Propagate alignment for _Complex
>>>
>>> _Complex load/store didn't have their alignment set properly, which was
>>> visible when GCC's torture tests use volatile _Complex.
>>>
>>> Update some existing tests to check for alignment, and add a new test
>>> which also has over-aligned volatile _Complex (since the imaginary part
>>> shouldn't be overaligned, only the real part).
>>>
>>> Added:
>>>    cfe/trunk/test/CodeGen/volatile-complex.c   (with props)
>>> Modified:
>>>    cfe/trunk/lib/CodeGen/CGExprComplex.cpp
>>>    cfe/trunk/test/CodeGen/volatile-1.c
>>>    cfe/trunk/test/CodeGen/volatile-2.c
>>>
>>> Modified: cfe/trunk/lib/CodeGen/CGExprComplex.cpp
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprComplex.cpp?rev=186490&r1=186489&r2=186490&view=diff
>>>
>>> ==============================================================================
>>> --- cfe/trunk/lib/CodeGen/CGExprComplex.cpp (original)
>>> +++ cfe/trunk/lib/CodeGen/CGExprComplex.cpp Wed Jul 17 00:57:42 2013
>>> @@ -18,6 +18,7 @@
>>> #include "llvm/ADT/SmallString.h"
>>> #include "llvm/IR/Constants.h"
>>> #include "llvm/IR/Function.h"
>>> +#include <algorithm>
>>> using namespace clang;
>>> using namespace CodeGen;
>>>
>>> @@ -297,19 +298,26 @@ ComplexPairTy ComplexExprEmitter::EmitLo
>>>
>>>   llvm::Value *SrcPtr = lvalue.getAddress();
>>>   bool isVolatile = lvalue.isVolatileQualified();
>>> +  unsigned AlignR = lvalue.getAlignment().getQuantity();
>>> +  ASTContext &C = CGF.getContext();
>>> +  QualType ComplexTy = lvalue.getType();
>>> +  unsigned ComplexAlign =
>>> C.getTypeAlignInChars(ComplexTy).getQuantity();
>>> +  unsigned AlignI = std::min(AlignR, ComplexAlign);
>>>
>>>   llvm::Value *Real=0, *Imag=0;
>>>
>>>   if (!IgnoreReal || isVolatile) {
>>>     llvm::Value *RealP = Builder.CreateStructGEP(SrcPtr, 0,
>>>                                                  SrcPtr->getName() +
>>> ".realp");
>>> -    Real = Builder.CreateLoad(RealP, isVolatile, SrcPtr->getName() +
>>> ".real");
>>> +    Real = Builder.CreateAlignedLoad(RealP, AlignR, isVolatile,
>>> +                                     SrcPtr->getName() + ".real");
>>>   }
>>>
>>>   if (!IgnoreImag || isVolatile) {
>>>     llvm::Value *ImagP = Builder.CreateStructGEP(SrcPtr, 1,
>>>                                                  SrcPtr->getName() +
>>> ".imagp");
>>> -    Imag = Builder.CreateLoad(ImagP, isVolatile, SrcPtr->getName() +
>>> ".imag");
>>> +    Imag = Builder.CreateAlignedLoad(ImagP, AlignI, isVolatile,
>>> +                                     SrcPtr->getName() + ".imag");
>>>   }
>>>   return ComplexPairTy(Real, Imag);
>>> }
>>> @@ -325,10 +333,16 @@ void ComplexExprEmitter::EmitStoreOfComp
>>>   llvm::Value *Ptr = lvalue.getAddress();
>>>   llvm::Value *RealPtr = Builder.CreateStructGEP(Ptr, 0, "real");
>>>   llvm::Value *ImagPtr = Builder.CreateStructGEP(Ptr, 1, "imag");
>>> -
>>> -  // TODO: alignment
>>> -  Builder.CreateStore(Val.first, RealPtr, lvalue.isVolatileQualified());
>>> -  Builder.CreateStore(Val.second, ImagPtr,
>>> lvalue.isVolatileQualified());
>>> +  unsigned AlignR = lvalue.getAlignment().getQuantity();
>>> +  ASTContext &C = CGF.getContext();
>>> +  QualType ComplexTy = lvalue.getType();
>>> +  unsigned ComplexAlign =
>>> C.getTypeAlignInChars(ComplexTy).getQuantity();
>>> +  unsigned AlignI = std::min(AlignR, ComplexAlign);
>>> +
>>> +  Builder.CreateAlignedStore(Val.first, RealPtr, AlignR,
>>> +                             lvalue.isVolatileQualified());
>>> +  Builder.CreateAlignedStore(Val.second, ImagPtr, AlignI,
>>> +                             lvalue.isVolatileQualified());
>>> }
>>>
>>>
>>>
>>> Modified: cfe/trunk/test/CodeGen/volatile-1.c
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/volatile-1.c?rev=186490&r1=186489&r2=186490&view=diff
>>>
>>> ==============================================================================
>>> --- cfe/trunk/test/CodeGen/volatile-1.c (original)
>>> +++ cfe/trunk/test/CodeGen/volatile-1.c Wed Jul 17 00:57:42 2013
>>> @@ -26,45 +26,45 @@ int printf(const char *, ...);
>>> void test() {
>>>   // CHECK: load volatile [[INT]]* @i
>>>   i;
>>> -  // CHECK-NEXT: load volatile [[INT]]* getelementptr inbounds
>>> ([[CINT]]* @ci, i32 0, i32 0)
>>> -  // CHECK-NEXT: load volatile [[INT]]* getelementptr inbounds
>>> ([[CINT]]* @ci, i32 0, i32 1)
>>> +  // CHECK-NEXT: load volatile [[INT]]* getelementptr inbounds
>>> ([[CINT]]* @ci, i32 0, i32 0), align 4
>>> +  // CHECK-NEXT: load volatile [[INT]]* getelementptr inbounds
>>> ([[CINT]]* @ci, i32 0, i32 1), align 4
>>>   // CHECK-NEXT: sitofp [[INT]]
>>>   (float)(ci);
>>> -  // CHECK-NEXT: load volatile [[INT]]* getelementptr inbounds
>>> ([[CINT]]* @ci, i32 0, i32 0)
>>> -  // CHECK-NEXT: load volatile [[INT]]* getelementptr inbounds
>>> ([[CINT]]* @ci, i32 0, i32 1)
>>> +  // CHECK-NEXT: load volatile [[INT]]* getelementptr inbounds
>>> ([[CINT]]* @ci, i32 0, i32 0), align 4
>>> +  // CHECK-NEXT: load volatile [[INT]]* getelementptr inbounds
>>> ([[CINT]]* @ci, i32 0, i32 1), align 4
>>>   (void)ci;
>>>   // CHECK-NEXT: bitcast
>>>   // CHECK-NEXT: memcpy
>>>   (void)a;
>>> -  // CHECK-NEXT: [[R:%.*]] = load volatile [[INT]]* getelementptr
>>> inbounds ([[CINT]]* @ci, i32 0, i32 0)
>>> -  // CHECK-NEXT: [[I:%.*]] = load volatile [[INT]]* getelementptr
>>> inbounds ([[CINT]]* @ci, i32 0, i32 1)
>>> -  // CHECK-NEXT: store volatile [[INT]] [[R]], [[INT]]* getelementptr
>>> inbounds ([[CINT]]* @ci, i32 0, i32 0)
>>> -  // CHECK-NEXT: store volatile [[INT]] [[I]], [[INT]]* getelementptr
>>> inbounds ([[CINT]]* @ci, i32 0, i32 1)
>>> +  // CHECK-NEXT: [[R:%.*]] = load volatile [[INT]]* getelementptr
>>> inbounds ([[CINT]]* @ci, i32 0, i32 0), align 4
>>> +  // CHECK-NEXT: [[I:%.*]] = load volatile [[INT]]* getelementptr
>>> inbounds ([[CINT]]* @ci, i32 0, i32 1), align 4
>>> +  // CHECK-NEXT: store volatile [[INT]] [[R]], [[INT]]* getelementptr
>>> inbounds ([[CINT]]* @ci, i32 0, i32 0), align 4
>>> +  // CHECK-NEXT: store volatile [[INT]] [[I]], [[INT]]* getelementptr
>>> inbounds ([[CINT]]* @ci, i32 0, i32 1), align 4
>>>   (void)(ci=ci);
>>>   // CHECK-NEXT: [[T:%.*]] = load volatile [[INT]]* @j
>>>   // CHECK-NEXT: store volatile [[INT]] [[T]], [[INT]]* @i
>>>   (void)(i=j);
>>> -  // CHECK-NEXT: [[R1:%.*]] = load volatile [[INT]]* getelementptr
>>> inbounds ([[CINT]]* @ci, i32 0, i32 0)
>>> -  // CHECK-NEXT: [[I1:%.*]] = load volatile [[INT]]* getelementptr
>>> inbounds ([[CINT]]* @ci, i32 0, i32 1)
>>> -  // CHECK-NEXT: [[R2:%.*]] = load volatile [[INT]]* getelementptr
>>> inbounds ([[CINT]]* @ci, i32 0, i32 0)
>>> -  // CHECK-NEXT: [[I2:%.*]] = load volatile [[INT]]* getelementptr
>>> inbounds ([[CINT]]* @ci, i32 0, i32 1)
>>> +  // CHECK-NEXT: [[R1:%.*]] = load volatile [[INT]]* getelementptr
>>> inbounds ([[CINT]]* @ci, i32 0, i32 0), align 4
>>> +  // CHECK-NEXT: [[I1:%.*]] = load volatile [[INT]]* getelementptr
>>> inbounds ([[CINT]]* @ci, i32 0, i32 1), align 4
>>> +  // CHECK-NEXT: [[R2:%.*]] = load volatile [[INT]]* getelementptr
>>> inbounds ([[CINT]]* @ci, i32 0, i32 0), align 4
>>> +  // CHECK-NEXT: [[I2:%.*]] = load volatile [[INT]]* getelementptr
>>> inbounds ([[CINT]]* @ci, i32 0, i32 1), align 4
>>>   // Not sure why they're ordered this way.
>>>   // CHECK-NEXT: [[R:%.*]] = add [[INT]] [[R2]], [[R1]]
>>>   // CHECK-NEXT: [[I:%.*]] = add [[INT]] [[I2]], [[I1]]
>>> -  // CHECK-NEXT: store volatile [[INT]] [[R]], [[INT]]* getelementptr
>>> inbounds ([[CINT]]* @ci, i32 0, i32 0)
>>> -  // CHECK-NEXT: store volatile [[INT]] [[I]], [[INT]]* getelementptr
>>> inbounds ([[CINT]]* @ci, i32 0, i32 1)
>>> +  // CHECK-NEXT: store volatile [[INT]] [[R]], [[INT]]* getelementptr
>>> inbounds ([[CINT]]* @ci, i32 0, i32 0), align 4
>>> +  // CHECK-NEXT: store volatile [[INT]] [[I]], [[INT]]* getelementptr
>>> inbounds ([[CINT]]* @ci, i32 0, i32 1), align 4
>>>   ci+=ci;
>>>
>>> -  // CHECK-NEXT: [[R1:%.*]] = load volatile [[INT]]* getelementptr
>>> inbounds ([[CINT]]* @ci, i32 0, i32 0)
>>> -  // CHECK-NEXT: [[I1:%.*]] = load volatile [[INT]]* getelementptr
>>> inbounds ([[CINT]]* @ci, i32 0, i32 1)
>>> -  // CHECK-NEXT: [[R2:%.*]] = load volatile [[INT]]* getelementptr
>>> inbounds ([[CINT]]* @ci, i32 0, i32 0)
>>> -  // CHECK-NEXT: [[I2:%.*]] = load volatile [[INT]]* getelementptr
>>> inbounds ([[CINT]]* @ci, i32 0, i32 1)
>>> +  // CHECK-NEXT: [[R1:%.*]] = load volatile [[INT]]* getelementptr
>>> inbounds ([[CINT]]* @ci, i32 0, i32 0), align 4
>>> +  // CHECK-NEXT: [[I1:%.*]] = load volatile [[INT]]* getelementptr
>>> inbounds ([[CINT]]* @ci, i32 0, i32 1), align 4
>>> +  // CHECK-NEXT: [[R2:%.*]] = load volatile [[INT]]* getelementptr
>>> inbounds ([[CINT]]* @ci, i32 0, i32 0), align 4
>>> +  // CHECK-NEXT: [[I2:%.*]] = load volatile [[INT]]* getelementptr
>>> inbounds ([[CINT]]* @ci, i32 0, i32 1), align 4
>>>   // CHECK-NEXT: [[R:%.*]] = add [[INT]] [[R2]], [[R1]]
>>>   // CHECK-NEXT: [[I:%.*]] = add [[INT]] [[I2]], [[I1]]
>>> -  // CHECK-NEXT: store volatile [[INT]] [[R]], [[INT]]* getelementptr
>>> inbounds ([[CINT]]* @ci, i32 0, i32 0)
>>> -  // CHECK-NEXT: store volatile [[INT]] [[I]], [[INT]]* getelementptr
>>> inbounds ([[CINT]]* @ci, i32 0, i32 1)
>>> -  // CHECK-NEXT: [[R2:%.*]] = load volatile [[INT]]* getelementptr
>>> inbounds ([[CINT]]* @ci, i32 0, i32 0)
>>> -  // CHECK-NEXT: [[I2:%.*]] = load volatile [[INT]]* getelementptr
>>> inbounds ([[CINT]]* @ci, i32 0, i32 1)
>>> +  // CHECK-NEXT: store volatile [[INT]] [[R]], [[INT]]* getelementptr
>>> inbounds ([[CINT]]* @ci, i32 0, i32 0), align 4
>>> +  // CHECK-NEXT: store volatile [[INT]] [[I]], [[INT]]* getelementptr
>>> inbounds ([[CINT]]* @ci, i32 0, i32 1), align 4
>>> +  // CHECK-NEXT: [[R2:%.*]] = load volatile [[INT]]* getelementptr
>>> inbounds ([[CINT]]* @ci, i32 0, i32 0), align 4
>>> +  // CHECK-NEXT: [[I2:%.*]] = load volatile [[INT]]* getelementptr
>>> inbounds ([[CINT]]* @ci, i32 0, i32 1), align 4
>>>   // These additions can be elided
>>>   // CHECK-NEXT: add [[INT]] [[R]], [[R2]]
>>>   // CHECK-NEXT: add [[INT]] [[I]], [[I2]]
>>>
>>> Modified: cfe/trunk/test/CodeGen/volatile-2.c
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/volatile-2.c?rev=186490&r1=186489&r2=186490&view=diff
>>>
>>> ==============================================================================
>>> --- cfe/trunk/test/CodeGen/volatile-2.c (original)
>>> +++ cfe/trunk/test/CodeGen/volatile-2.c Wed Jul 17 00:57:42 2013
>>> @@ -3,8 +3,8 @@
>>> void test0() {
>>>   // CHECK: define void @test0()
>>>   // CHECK:      [[F:%.*]] = alloca float
>>> -  // CHECK-NEXT: [[REAL:%.*]] = load volatile float* getelementptr
>>> inbounds ({ float, float }* @test0_v, i32 0, i32 0)
>>> -  // CHECK-NEXT: load volatile float* getelementptr inbounds ({{.*}}
>>> @test0_v, i32 0, i32 1)
>>> +  // CHECK-NEXT: [[REAL:%.*]] = load volatile float* getelementptr
>>> inbounds ({ float, float }* @test0_v, i32 0, i32 0), align 4
>>> +  // CHECK-NEXT: load volatile float* getelementptr inbounds ({{.*}}
>>> @test0_v, i32 0, i32 1), align 4
>>>   // CHECK-NEXT: store float [[REAL]], float* [[F]], align 4
>>>   // CHECK-NEXT: ret void
>>>   extern volatile _Complex float test0_v;
>>> @@ -13,10 +13,10 @@ void test0() {
>>>
>>> void test1() {
>>>   // CHECK: define void @test1()
>>> -  // CHECK:      [[REAL:%.*]] = load volatile float* getelementptr
>>> inbounds ({{.*}} @test1_v, i32 0, i32 0)
>>> -  // CHECK-NEXT: [[IMAG:%.*]] = load volatile float* getelementptr
>>> inbounds ({{.*}} @test1_v, i32 0, i32 1)
>>> -  // CHECK-NEXT: store volatile float [[REAL]], float* getelementptr
>>> inbounds ({{.*}} @test1_v, i32 0, i32 0)
>>> -  // CHECK-NEXT: store volatile float [[IMAG]], float* getelementptr
>>> inbounds ({{.*}} @test1_v, i32 0, i32 1)
>>> +  // CHECK:      [[REAL:%.*]] = load volatile float* getelementptr
>>> inbounds ({{.*}} @test1_v, i32 0, i32 0), align 4
>>> +  // CHECK-NEXT: [[IMAG:%.*]] = load volatile float* getelementptr
>>> inbounds ({{.*}} @test1_v, i32 0, i32 1), align 4
>>> +  // CHECK-NEXT: store volatile float [[REAL]], float* getelementptr
>>> inbounds ({{.*}} @test1_v, i32 0, i32 0), align 4
>>> +  // CHECK-NEXT: store volatile float [[IMAG]], float* getelementptr
>>> inbounds ({{.*}} @test1_v, i32 0, i32 1), align 4
>>>   // CHECK-NEXT: ret void
>>>   extern volatile _Complex float test1_v;
>>>   test1_v = test1_v;
>>>
>>> Added: cfe/trunk/test/CodeGen/volatile-complex.c
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/volatile-complex.c?rev=186490&view=auto
>>>
>>> ==============================================================================
>>> --- cfe/trunk/test/CodeGen/volatile-complex.c (added)
>>> +++ cfe/trunk/test/CodeGen/volatile-complex.c Wed Jul 17 00:57:42 2013
>>> @@ -0,0 +1,63 @@
>>> +// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s
>>> +
>>> +volatile _Complex float cf;
>>> +volatile _Complex double cd;
>>> +volatile _Complex float cf32 __attribute__((aligned(32)));
>>> +volatile _Complex double cd32 __attribute__((aligned(32)));
>>> +
>>> +
>>> +// CHECK: define void @test_cf()
>>> +// CHECK-NEXT: entry:
>>> +void test_cf() {
>>> +  // CHECK-NEXT: load volatile float* getelementptr inbounds ({ float,
>>> float }* @cf, i32 0, i32 0), align 4
>>> +  // CHECK-NEXT: load volatile float* getelementptr inbounds ({ float,
>>> float }* @cf, i32 0, i32 1), align 4
>>> +  (void)(cf);
>>> +  // CHECK-NEXT: [[R:%.*]] = load volatile float* getelementptr
>>> inbounds ({ float, float }* @cf, i32 0, i32 0), align 4
>>> +  // CHECK-NEXT: [[I:%.*]] = load volatile float* getelementptr
>>> inbounds ({ float, float }* @cf, i32 0, i32 1), align 4
>>> +  // CHECK-NEXT: store volatile float [[R]], float* getelementptr
>>> inbounds ({ float, float }* @cf, i32 0, i32 0), align 4
>>> +  // CHECK-NEXT: store volatile float [[I]], float* getelementptr
>>> inbounds ({ float, float }* @cf, i32 0, i32 1), align 4
>>> +  (void)(cf=cf);
>>> +  // CHECK-NEXT: ret void
>>> +}
>>> +
>>> +// CHECK: define void @test_cd()
>>> +// CHECK-NEXT: entry:
>>> +void test_cd() {
>>> +  // CHECK-NEXT: load volatile double* getelementptr inbounds ({
>>> double, double }* @cd, i32 0, i32 0), align 8
>>> +  // CHECK-NEXT: load volatile double* getelementptr inbounds ({
>>> double, double }* @cd, i32 0, i32 1), align 8
>>> +  (void)(cd);
>>> +  // CHECK-NEXT: [[R:%.*]] = load volatile double* getelementptr
>>> inbounds ({ double, double }* @cd, i32 0, i32 0), align 8
>>> +  // CHECK-NEXT: [[I:%.*]] = load volatile double* getelementptr
>>> inbounds ({ double, double }* @cd, i32 0, i32 1), align 8
>>> +  // CHECK-NEXT: store volatile double [[R]], double* getelementptr
>>> inbounds ({ double, double }* @cd, i32 0, i32 0), align 8
>>> +  // CHECK-NEXT: store volatile double [[I]], double* getelementptr
>>> inbounds ({ double, double }* @cd, i32 0, i32 1), align 8
>>> +  (void)(cd=cd);
>>> +  // CHECK-NEXT: ret void
>>> +}
>>> +
>>> +// CHECK: define void @test_cf32()
>>> +// CHECK-NEXT: entry:
>>> +void test_cf32() {
>>> +  // CHECK-NEXT: load volatile float* getelementptr inbounds ({ float,
>>> float }* @cf32, i32 0, i32 0), align 32
>>> +  // CHECK-NEXT: load volatile float* getelementptr inbounds ({ float,
>>> float }* @cf32, i32 0, i32 1), align 4
>>> +  (void)(cf32);
>>> +  // CHECK-NEXT: [[R:%.*]] = load volatile float* getelementptr
>>> inbounds ({ float, float }* @cf32, i32 0, i32 0), align 32
>>> +  // CHECK-NEXT: [[I:%.*]] = load volatile float* getelementptr
>>> inbounds ({ float, float }* @cf32, i32 0, i32 1), align 4
>>> +  // CHECK-NEXT: store volatile float [[R]], float* getelementptr
>>> inbounds ({ float, float }* @cf32, i32 0, i32 0), align 32
>>> +  // CHECK-NEXT: store volatile float [[I]], float* getelementptr
>>> inbounds ({ float, float }* @cf32, i32 0, i32 1), align 4
>>> +  (void)(cf32=cf32);
>>> +  // CHECK-NEXT: ret void
>>> +}
>>> +
>>> +// CHECK: define void @test_cd32()
>>> +// CHECK-NEXT: entry:
>>> +void test_cd32() {
>>> +  // CHECK-NEXT: load volatile double* getelementptr inbounds ({
>>> double, double }* @cd32, i32 0, i32 0), align 32
>>> +  // CHECK-NEXT: load volatile double* getelementptr inbounds ({
>>> double, double }* @cd32, i32 0, i32 1), align 8
>>> +  (void)(cd32);
>>> +  // CHECK-NEXT: [[R:%.*]] = load volatile double* getelementptr
>>> inbounds ({ double, double }* @cd32, i32 0, i32 0), align 32
>>> +  // CHECK-NEXT: [[I:%.*]] = load volatile double* getelementptr
>>> inbounds ({ double, double }* @cd32, i32 0, i32 1), align 8
>>> +  // CHECK-NEXT: store volatile double [[R]], double* getelementptr
>>> inbounds ({ double, double }* @cd32, i32 0, i32 0), align 32
>>> +  // CHECK-NEXT: store volatile double [[I]], double* getelementptr
>>> inbounds ({ double, double }* @cd32, i32 0, i32 1), align 8
>>> +  (void)(cd32=cd32);
>>> +  // CHECK-NEXT: ret void
>>> +}
>>>
>>> Propchange: cfe/trunk/test/CodeGen/volatile-complex.c
>>>
>>> ------------------------------------------------------------------------------
>>>    svn:eol-style = LF
>>>
>>>
>>> _______________________________________________
>>> cfe-commits mailing list
>>> cfe-commits at cs.uiuc.edu
>>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>>>
>>>
>>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130717/51450df6/attachment.html>


More information about the cfe-commits mailing list