/// performing such an operation can be performed without a libcall.
bool CodeGenFunction::typeIsSuitableForInlineAtomic(QualType Ty,
bool IsVolatile) const {
+ // The operation must be volatile for us to make it atomic.
+ if (!IsVolatile)
+ return false;
+ // The -fms-volatile flag must be passed for us to adopt this behavior.
+ if (!CGM.getCodeGenOpts().MSVolatile)
+ return false;
+
// An atomic is inline if we don't need to use a libcall (e.g. it is builtin).
- bool AtomicIsInline = getContext().getTargetInfo().hasBuiltinAtomic(
- getContext().getTypeSize(Ty), getContext().getTypeAlign(Ty));
- return CGM.getCodeGenOpts().MSVolatile && IsVolatile && AtomicIsInline;
+ if (!getContext().getTargetInfo().hasBuiltinAtomic(
+ getContext().getTypeSize(Ty), getContext().getTypeAlign(Ty)))
+ return false;
+
+ // MSVC doesn't seem to do this for types wider than a pointer.
+ if (getContext().getTypeSize(Ty) >
+ getContext().getTypeSize(getContext().getIntPtrType()))
+ return false;
+ return true;
}
RValue CodeGenFunction::EmitAtomicLoad(LValue LV, SourceLocation SL,
void test8(volatile double *p, volatile double *q) {
*p = *q;
// CHECK-LABEL: @test8
- // CHECK: load atomic volatile {{.*}} acquire
- // CHECK: store atomic volatile {{.*}}, {{.*}} release
+ // CHECK: load volatile {{.*}}
+ // CHECK: store volatile {{.*}}, {{.*}}
}
void test9(volatile baz *p, baz *q) {
*p = *q;
// CHECK-LABEL: @test9
// CHECK: store atomic volatile {{.*}}, {{.*}} release
}
+void test10(volatile long long *p, volatile long long *q) {
+ *p = *q;
+ // CHECK-LABEL: @test10
+ // CHECK: load volatile {{.*}}
+ // CHECK: store volatile {{.*}}, {{.*}}
+}
+void test11(volatile float *p, volatile float *q) {
+ *p = *q;
+ // CHECK-LABEL: @test11
+ // CHECK: load atomic volatile {{.*}} acquire
+ // CHECK: store atomic volatile {{.*}}, {{.*}} release
+}