Skip to content

Commit

Permalink
[PR40778][Sema] Adjust addr space of operands in builtin operators.
Browse files Browse the repository at this point in the history
Adjust address space for references and pointer operands of builtin operators.

Currently this change only fixes addr space in assignment (= and |=) operator,
that is needed for the test case reported in the bug. Wider support for all
other operations will follow.

Differential Revision: https://reviews.llvm.org/D58719

llvm-svn: 355608
  • Loading branch information
Anastasia Stulova committed Mar 7, 2019
1 parent 95817d3 commit 27e5c21
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 5 deletions.
19 changes: 14 additions & 5 deletions clang/lib/Sema/SemaOverload.cpp
Expand Up @@ -7659,6 +7659,12 @@ BuiltinCandidateTypeSet::AddTypesConvertedFrom(QualType Ty,
}
}
}
/// Helper function for adjusting address spaces for the pointer or reference
/// operands of builtin operators depending on the argument.
static QualType AdjustAddressSpaceForBuiltinOperandType(Sema &S, QualType T,
Expr *Arg) {
return S.Context.getAddrSpaceQualType(T, Arg->getType().getAddressSpace());
}

/// Helper function for AddBuiltinOperatorCandidates() that adds
/// the volatile- and non-volatile-qualified assignment operators for the
Expand All @@ -7670,15 +7676,17 @@ static void AddBuiltinAssignmentOperatorCandidates(Sema &S,
QualType ParamTypes[2];

// T& operator=(T&, T)
ParamTypes[0] = S.Context.getLValueReferenceType(T);
ParamTypes[0] = S.Context.getLValueReferenceType(
AdjustAddressSpaceForBuiltinOperandType(S, T, Args[0]));
ParamTypes[1] = T;
S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet,
/*IsAssignmentOperator=*/true);

if (!S.Context.getCanonicalType(T).isVolatileQualified()) {
// volatile T& operator=(volatile T&, T)
ParamTypes[0]
= S.Context.getLValueReferenceType(S.Context.getVolatileType(T));
ParamTypes[0] = S.Context.getLValueReferenceType(
AdjustAddressSpaceForBuiltinOperandType(S, S.Context.getVolatileType(T),
Args[0]));
ParamTypes[1] = T;
S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet,
/*IsAssignmentOperator=*/true);
Expand Down Expand Up @@ -8573,8 +8581,9 @@ class BuiltinOperatorOverloadBuilder {
ParamTypes[1] = ArithmeticTypes[Right];

// Add this built-in operator as a candidate (VQ is empty).
ParamTypes[0] =
S.Context.getLValueReferenceType(ArithmeticTypes[Left]);
ParamTypes[0] = S.Context.getLValueReferenceType(
AdjustAddressSpaceForBuiltinOperandType(S, ArithmeticTypes[Left],
Args[0]));
S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet);
if (VisibleTypeConversionsQuals.hasVolatile()) {
// Add this built-in operator as a candidate (VQ is 'volatile').
Expand Down
46 changes: 46 additions & 0 deletions clang/test/CodeGenOpenCLCXX/addrspace-operators.cl
@@ -0,0 +1,46 @@
//RUN: %clang_cc1 %s -triple spir -cl-std=c++ -emit-llvm -O0 -o - | FileCheck %s

enum E {
a,
b,
};

class C {
public:
void Assign(E e) { me = e; }
void OrAssign(E e) { mi |= e; }
E me;
int mi;
};

__global E globE;
//CHECK-LABEL: define spir_func void @_Z3barv()
void bar() {
C c;
//CHECK: addrspacecast %class.C* %c to %class.C addrspace(4)*
//CHECK: call void @_ZNU3AS41C6AssignE1E(%class.C addrspace(4)* %{{[0-9]+}}, i32 0)
c.Assign(a);
//CHECK: addrspacecast %class.C* %c to %class.C addrspace(4)*
//CHECK: call void @_ZNU3AS41C8OrAssignE1E(%class.C addrspace(4)* %{{[0-9]+}}, i32 0)
c.OrAssign(a);

E e;
// CHECK: store i32 1, i32* %e
e = b;
// CHECK: store i32 0, i32 addrspace(1)* @globE
globE = a;
// FIXME: Sema fails here because it thinks the types are incompatible.
//e = b;
//globE = a;
}

//CHECK: define linkonce_odr void @_ZNU3AS41C6AssignE1E(%class.C addrspace(4)* %this, i32 %e)
//CHECK: [[E:%[0-9]+]] = load i32, i32* %e.addr
//CHECK: %me = getelementptr inbounds %class.C, %class.C addrspace(4)* %this1, i32 0, i32 0
//CHECK: store i32 [[E]], i32 addrspace(4)* %me

//CHECK define linkonce_odr void @_ZNU3AS41C8OrAssignE1E(%class.C addrspace(4)* %this, i32 %e)
//CHECK: [[E:%[0-9]+]] = load i32, i32* %e.addr
//CHECK: %mi = getelementptr inbounds %class.C, %class.C addrspace(4)* %this1, i32 0, i32 1
//CHECK: [[MI:%[0-9]+]] = load i32, i32 addrspace(4)* %mi
//CHECK: %or = or i32 [[MI]], [[E]]

0 comments on commit 27e5c21

Please sign in to comment.