Prazek created this revision.
This code was wrongly devirtualized before:
A* a = new A;
a->foo();
A* b = new(a) B;
if (a == b)
b->foo();
Now we insert barrier before comparing dynamic pointers.
https://reviews.llvm.org/D32378
Files:
lib/CodeGen/CGExprScalar.cpp
test/CodeGenCXX/strict-vtable-pointers.cpp
Index: test/CodeGenCXX/strict-vtable-pointers.cpp
===================================================================
--- test/CodeGenCXX/strict-vtable-pointers.cpp
+++ test/CodeGenCXX/strict-vtable-pointers.cpp
@@ -237,6 +237,62 @@
take(u.h);
}
+// CHECK-NEW-LABEL: define void @_Z7comparev()
+void compare() {
+ A *a = new A;
+ a->foo();
+ // CHECK-NEW: call i8* @llvm.invariant.group.barrier(i8*
+ A *b = new (a) B;
+
+ // CHECK-NEW: %[[a:.*]] = call i8* @llvm.invariant.group.barrier(i8*
+ // CHECK-NEW: %[[a2:.*]] = bitcast i8* %[[a]] to %struct.A*
+ // CHECK-NEW: %[[b:.*]] = call i8* @llvm.invariant.group.barrier(i8*
+ // CHECK-NEW: %[[b2:.*]] = bitcast i8* %[[b]] to %struct.A*
+ // CHECK-NEW: %cmp = icmp eq %struct.A* %[[a2]], %[[b2]]
+ if (a == b)
+ b->foo();
+}
+
+// CHECK-NEW-LABEL: compare2
+bool compare2(A *a, A *a2) {
+ // CHECK-NEW: %[[a:.*]] = call i8* @llvm.invariant.group.barrier(i8*
+ // CHECK-NEW: %[[a2:.*]] = bitcast i8* %[[a]] to %struct.A*
+ // CHECK-NEW: %[[b:.*]] = call i8* @llvm.invariant.group.barrier(i8*
+ // CHECK-NEW: %[[b2:.*]] = bitcast i8* %[[b]] to %struct.A*
+ // CHECK-NEW: %cmp = icmp ult %struct.A* %[[a2]], %[[b2]]
+ return a < a2;
+}
+// CHECK-NEW-LABEL: compareIntPointers
+bool compareIntPointers(int *a, int *b) {
+ // CHECK-NEW-NOT: call i8* @llvm.invariant.group.barrier
+ return a == b;
+}
+
+struct HoldingOtherVirtuals {
+ B b;
+};
+
+// There is no need to add barriers for comparision of pointer to classes
+// that are not dynamic.
+// CHECK-NEW-LABEL: compare5
+bool compare5(HoldingOtherVirtuals *a, HoldingOtherVirtuals *b) {
+ // CHECK-NEW-NOT: call i8* @llvm.invariant.group.barrier
+ return a == b;
+}
+
+struct X;
+// We have to also introduce the barriers if comparing pointers to incomplete
+// objects
+// CHECK-NEW-LABEL: define zeroext i1 @_Z8compare4P1XS0_
+bool compare4(X *x, X *x2) {
+ // CHECK-NEW: %[[x:.*]] = call i8* @llvm.invariant.group.barrier(i8*
+ // CHECK-NEW: %[[xp:.*]] = bitcast i8* %[[x]] to %struct.X*
+ // CHECK-NEW: %[[x2:.*]] = call i8* @llvm.invariant.group.barrier(i8*
+ // CHECK-NEW: %[[x2p:.*]] = bitcast i8* %[[x2]] to %struct.X*
+ // CHECK-NEW: %cmp = icmp eq %struct.X* %[[xp]], %[[x2p]]
+ return x == x2;
+}
+
/** DTORS **/
// CHECK-DTORS-LABEL: define linkonce_odr void @_ZN10StaticBaseD2Ev(
// CHECK-DTORS-NOT: call i8* @llvm.invariant.group.barrier(
Index: lib/CodeGen/CGExprScalar.cpp
===================================================================
--- lib/CodeGen/CGExprScalar.cpp
+++ lib/CodeGen/CGExprScalar.cpp
@@ -1698,7 +1698,7 @@
}
case CK_IntToOCLSampler:
- return CGF.CGM.createOpenCLIntToSamplerConversion(E, CGF);
+ return CGF.CGM.createOpenCLIntToSamplerConversion(E, CGF);
} // end of switch
@@ -3062,8 +3062,20 @@
Result = Builder.CreateFCmp(FCmpOpc, LHS, RHS, "cmp");
} else if (LHSTy->hasSignedIntegerRepresentation()) {
Result = Builder.CreateICmp(SICmpOpc, LHS, RHS, "cmp");
- } else {
- // Unsigned integers and pointers.
+ } else { // Unsigned integers and pointers.
+ if (CGF.CGM.getCodeGenOpts().StrictVTablePointers &&
+ CGF.CGM.getCodeGenOpts().OptimizationLevel > 0) {
+ // Based on comparisons of pointers to dynamic objects, the optimizer
+ // can replace one pointer with another. This might result in
+ // replacing pointer after barrier to pointer before barrier,
+ // resulting in invalid devirtualization.
+ if (auto *RD = LHSTy->getPointeeCXXRecordDecl())
+ if (!RD->isCompleteDefinition() || RD->isDynamicClass())
+ LHS = Builder.CreateInvariantGroupBarrier(LHS);
+ if (auto *RD = RHSTy->getPointeeCXXRecordDecl())
+ if (!RD->isCompleteDefinition() || RD->isDynamicClass())
+ RHS = Builder.CreateInvariantGroupBarrier(RHS);
+ }
Result = Builder.CreateICmp(UICmpOpc, LHS, RHS, "cmp");
}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits