diff options
author | Reid Kleckner <reid@kleckner.net> | 2013-04-30 20:15:14 +0000 |
---|---|---|
committer | Reid Kleckner <reid@kleckner.net> | 2013-04-30 20:15:14 +0000 |
commit | 3d2f000df9311bfccb6d2ac350be3d3efa5a412b (patch) | |
tree | 5a1b96031f88223113f0d68cbffb1602ed178fdd /test | |
parent | c7d77b25a37acad689ae5c318fdf80fde92983f0 (diff) |
[ms-cxxabi] Implement member pointer comparisons
Summary:
Like Itanium, comparisons are basically bitwise comparisons of the two
values, with an exception for null member function pointers. If two
function pointers are null, only the function pointer field matters for
comparison purposes. The rest of the bits can be arbitrary. We take
advantage of this in isZeroInitializable(), and it may matter once we
start emitting conversions.
Reviewers: rjmccall
CC: cfe-commits
Differential Revision: http://llvm-reviews.chandlerc.com/D695
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@180800 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test')
-rw-r--r-- | test/CodeGenCXX/microsoft-abi-member-pointers.cpp | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/test/CodeGenCXX/microsoft-abi-member-pointers.cpp b/test/CodeGenCXX/microsoft-abi-member-pointers.cpp index 203f0639fe..292f9d2c69 100644 --- a/test/CodeGenCXX/microsoft-abi-member-pointers.cpp +++ b/test/CodeGenCXX/microsoft-abi-member-pointers.cpp @@ -222,3 +222,91 @@ void callMemberPointerVirtualBase(Virtual *o, void (Virtual::*memptr)()) { // CHECK: ret void // CHECK: } } + +bool compareSingleFunctionMemptr(void (Single::*l)(), void (Single::*r)()) { + return l == r; +// Should only be one comparison here. +// CHECK: define zeroext i1 @"\01?compareSingleFunctionMemptr@@YA_NP8Single@@AEXXZ0@Z"{{.*}} { +// CHECK-NOT: icmp +// CHECK: %[[r:.*]] = icmp eq +// CHECK-NOT: icmp +// CHECK: ret i1 %[[r]] +// CHECK: } +} + +bool compareNeqSingleFunctionMemptr(void (Single::*l)(), void (Single::*r)()) { + return l != r; +// Should only be one comparison here. +// CHECK: define zeroext i1 @"\01?compareNeqSingleFunctionMemptr@@YA_NP8Single@@AEXXZ0@Z"{{.*}} { +// CHECK-NOT: icmp +// CHECK: %[[r:.*]] = icmp ne +// CHECK-NOT: icmp +// CHECK: ret i1 %[[r]] +// CHECK: } +} + +bool unspecFuncMemptrEq(void (Unspecified::*l)(), void (Unspecified::*r)()) { + return l == r; +// CHECK: define zeroext i1 @"\01?unspecFuncMemptrEq@@YA_NP8Unspecified@@AEXXZ0@Z"{{.*}} { +// CHECK: %[[lhs0:.*]] = extractvalue { i8*, i32, i32, i32 } %[[l:.*]], 0 +// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[r:.*]], 0 +// CHECK: %[[cmp0:.*]] = icmp eq i8* %[[lhs0]], %{{.*}} +// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[l]], 1 +// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[r]], 1 +// CHECK: %[[cmp1:.*]] = icmp eq i32 +// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[l]], 2 +// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[r]], 2 +// CHECK: %[[cmp2:.*]] = icmp eq i32 +// CHECK: %[[res12:.*]] = and i1 %[[cmp1]], %[[cmp2]] +// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[l]], 3 +// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[r]], 3 +// CHECK: %[[cmp3:.*]] = icmp eq i32 +// CHECK: %[[res123:.*]] = and i1 %[[res12]], %[[cmp3]] +// CHECK: %[[iszero:.*]] = icmp eq i8* %[[lhs0]], null +// CHECK: %[[bits_or_null:.*]] = or i1 %[[res123]], %[[iszero]] +// CHECK: %{{.*}} = and i1 %[[bits_or_null]], %[[cmp0]] +// CHECK: ret i1 %{{.*}} +// CHECK: } +} + +bool unspecFuncMemptrNeq(void (Unspecified::*l)(), void (Unspecified::*r)()) { + return l != r; +// CHECK: define zeroext i1 @"\01?unspecFuncMemptrNeq@@YA_NP8Unspecified@@AEXXZ0@Z"{{.*}} { +// CHECK: %[[lhs0:.*]] = extractvalue { i8*, i32, i32, i32 } %[[l:.*]], 0 +// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[r:.*]], 0 +// CHECK: %[[cmp0:.*]] = icmp ne i8* %[[lhs0]], %{{.*}} +// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[l]], 1 +// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[r]], 1 +// CHECK: %[[cmp1:.*]] = icmp ne i32 +// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[l]], 2 +// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[r]], 2 +// CHECK: %[[cmp2:.*]] = icmp ne i32 +// CHECK: %[[res12:.*]] = or i1 %[[cmp1]], %[[cmp2]] +// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[l]], 3 +// CHECK: %{{.*}} = extractvalue { i8*, i32, i32, i32 } %[[r]], 3 +// CHECK: %[[cmp3:.*]] = icmp ne i32 +// CHECK: %[[res123:.*]] = or i1 %[[res12]], %[[cmp3]] +// CHECK: %[[iszero:.*]] = icmp ne i8* %[[lhs0]], null +// CHECK: %[[bits_or_null:.*]] = and i1 %[[res123]], %[[iszero]] +// CHECK: %{{.*}} = or i1 %[[bits_or_null]], %[[cmp0]] +// CHECK: ret i1 %{{.*}} +// CHECK: } +} + +bool unspecDataMemptrEq(int Unspecified::*l, int Unspecified::*r) { + return l == r; +// CHECK: define zeroext i1 @"\01?unspecDataMemptrEq@@YA_NPQUnspecified@@H0@Z"{{.*}} { +// CHECK: extractvalue { i32, i32, i32 } %{{.*}}, 0 +// CHECK: extractvalue { i32, i32, i32 } %{{.*}}, 0 +// CHECK: icmp eq i32 +// CHECK: extractvalue { i32, i32, i32 } %{{.*}}, 1 +// CHECK: extractvalue { i32, i32, i32 } %{{.*}}, 1 +// CHECK: icmp eq i32 +// CHECK: extractvalue { i32, i32, i32 } %{{.*}}, 2 +// CHECK: extractvalue { i32, i32, i32 } %{{.*}}, 2 +// CHECK: icmp eq i32 +// CHECK: and i1 +// CHECK: and i1 +// CHECK: ret i1 +// CHECK: } +} |