Skip to content
This repository was archived by the owner on Mar 28, 2020. It is now read-only.

Commit f384fbb

Browse files
author
Anastasia Stulova
committed
[PR40778][Sema] Adjust addr space of operands in builtin operators.
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 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@355608 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 3bef4a5 commit f384fbb

File tree

2 files changed

+60
-5
lines changed

2 files changed

+60
-5
lines changed

lib/Sema/SemaOverload.cpp

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7659,6 +7659,12 @@ BuiltinCandidateTypeSet::AddTypesConvertedFrom(QualType Ty,
76597659
}
76607660
}
76617661
}
7662+
/// Helper function for adjusting address spaces for the pointer or reference
7663+
/// operands of builtin operators depending on the argument.
7664+
static QualType AdjustAddressSpaceForBuiltinOperandType(Sema &S, QualType T,
7665+
Expr *Arg) {
7666+
return S.Context.getAddrSpaceQualType(T, Arg->getType().getAddressSpace());
7667+
}
76627668

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

76727678
// T& operator=(T&, T)
7673-
ParamTypes[0] = S.Context.getLValueReferenceType(T);
7679+
ParamTypes[0] = S.Context.getLValueReferenceType(
7680+
AdjustAddressSpaceForBuiltinOperandType(S, T, Args[0]));
76747681
ParamTypes[1] = T;
76757682
S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet,
76767683
/*IsAssignmentOperator=*/true);
76777684

76787685
if (!S.Context.getCanonicalType(T).isVolatileQualified()) {
76797686
// volatile T& operator=(volatile T&, T)
7680-
ParamTypes[0]
7681-
= S.Context.getLValueReferenceType(S.Context.getVolatileType(T));
7687+
ParamTypes[0] = S.Context.getLValueReferenceType(
7688+
AdjustAddressSpaceForBuiltinOperandType(S, S.Context.getVolatileType(T),
7689+
Args[0]));
76827690
ParamTypes[1] = T;
76837691
S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet,
76847692
/*IsAssignmentOperator=*/true);
@@ -8573,8 +8581,9 @@ class BuiltinOperatorOverloadBuilder {
85738581
ParamTypes[1] = ArithmeticTypes[Right];
85748582

85758583
// Add this built-in operator as a candidate (VQ is empty).
8576-
ParamTypes[0] =
8577-
S.Context.getLValueReferenceType(ArithmeticTypes[Left]);
8584+
ParamTypes[0] = S.Context.getLValueReferenceType(
8585+
AdjustAddressSpaceForBuiltinOperandType(S, ArithmeticTypes[Left],
8586+
Args[0]));
85788587
S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet);
85798588
if (VisibleTypeConversionsQuals.hasVolatile()) {
85808589
// Add this built-in operator as a candidate (VQ is 'volatile').
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
//RUN: %clang_cc1 %s -triple spir -cl-std=c++ -emit-llvm -O0 -o - | FileCheck %s
2+
3+
enum E {
4+
a,
5+
b,
6+
};
7+
8+
class C {
9+
public:
10+
void Assign(E e) { me = e; }
11+
void OrAssign(E e) { mi |= e; }
12+
E me;
13+
int mi;
14+
};
15+
16+
__global E globE;
17+
//CHECK-LABEL: define spir_func void @_Z3barv()
18+
void bar() {
19+
C c;
20+
//CHECK: addrspacecast %class.C* %c to %class.C addrspace(4)*
21+
//CHECK: call void @_ZNU3AS41C6AssignE1E(%class.C addrspace(4)* %{{[0-9]+}}, i32 0)
22+
c.Assign(a);
23+
//CHECK: addrspacecast %class.C* %c to %class.C addrspace(4)*
24+
//CHECK: call void @_ZNU3AS41C8OrAssignE1E(%class.C addrspace(4)* %{{[0-9]+}}, i32 0)
25+
c.OrAssign(a);
26+
27+
E e;
28+
// CHECK: store i32 1, i32* %e
29+
e = b;
30+
// CHECK: store i32 0, i32 addrspace(1)* @globE
31+
globE = a;
32+
// FIXME: Sema fails here because it thinks the types are incompatible.
33+
//e = b;
34+
//globE = a;
35+
}
36+
37+
//CHECK: define linkonce_odr void @_ZNU3AS41C6AssignE1E(%class.C addrspace(4)* %this, i32 %e)
38+
//CHECK: [[E:%[0-9]+]] = load i32, i32* %e.addr
39+
//CHECK: %me = getelementptr inbounds %class.C, %class.C addrspace(4)* %this1, i32 0, i32 0
40+
//CHECK: store i32 [[E]], i32 addrspace(4)* %me
41+
42+
//CHECK define linkonce_odr void @_ZNU3AS41C8OrAssignE1E(%class.C addrspace(4)* %this, i32 %e)
43+
//CHECK: [[E:%[0-9]+]] = load i32, i32* %e.addr
44+
//CHECK: %mi = getelementptr inbounds %class.C, %class.C addrspace(4)* %this1, i32 0, i32 1
45+
//CHECK: [[MI:%[0-9]+]] = load i32, i32 addrspace(4)* %mi
46+
//CHECK: %or = or i32 [[MI]], [[E]]

0 commit comments

Comments
 (0)