Author: Umesh Kalappa Date: 2023-09-23T19:40:24+05:30 New Revision: 2641d9b2807ded4b712f4dca809d63c138c91361
URL: https://github.com/llvm/llvm-project/commit/2641d9b2807ded4b712f4dca809d63c138c91361 DIFF: https://github.com/llvm/llvm-project/commit/2641d9b2807ded4b712f4dca809d63c138c91361.diff LOG: Propagate the volatile qualifier of exp to store /load operations . This changes to address the PR : 55207 We update the volatility on the LValue by looking at the LHS cast operation qualifier and propagate the RValue volatile-ness from the CGF data structure . Reviewed By: rjmccall Differential Revision: https://reviews.llvm.org/D157890 Added: clang/test/CodeGen/volatile.cpp Modified: clang/include/clang/AST/Expr.h clang/lib/CodeGen/CGExpr.cpp clang/lib/CodeGen/CGExprComplex.cpp clang/lib/CodeGen/CGExprScalar.cpp Removed: ################################################################################ diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index fe20a84216d1f11..1c717b520dd87c6 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -3608,6 +3608,19 @@ class CastExpr : public Expr { return FPOptionsOverride(); } + /// Return + // True : if this conversion changes the volatile-ness of a gl-value. + // Qualification conversions on gl-values currently use CK_NoOp, but + // it's important to recognize volatile-changing conversions in + // clients code generation that normally eagerly peephole loads. Note + // that the query is answering for this specific node; Sema may + // produce multiple cast nodes for any particular conversion sequence. + // False : Otherwise. + bool changesVolatileQualification() const { + return (isGLValue() && (getType().isVolatileQualified() != + getSubExpr()->getType().isVolatileQualified())); + } + static const FieldDecl *getTargetFieldForToUnionCast(QualType unionType, QualType opType); static const FieldDecl *getTargetFieldForToUnionCast(const RecordDecl *RD, diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 76bbeba468db643..86239d5e89fcc4d 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -4802,6 +4802,9 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) { // bound and change the IR type. // FIXME: Once pointee types are removed from IR, remove this. LValue LV = EmitLValue(E->getSubExpr()); + // Propagate the volatile qualifer to LValue, if exist in E. + if (E->changesVolatileQualification()) + LV.getQuals() = E->getType().getQualifiers(); if (LV.isSimple()) { Address V = LV.getAddress(*this); if (V.isValid()) { diff --git a/clang/lib/CodeGen/CGExprComplex.cpp b/clang/lib/CodeGen/CGExprComplex.cpp index 2dd1a991ec97199..f3cbd1d0451ebe4 100644 --- a/clang/lib/CodeGen/CGExprComplex.cpp +++ b/clang/lib/CodeGen/CGExprComplex.cpp @@ -177,11 +177,15 @@ class ComplexExprEmitter ComplexPairTy VisitImplicitCastExpr(ImplicitCastExpr *E) { // Unlike for scalars, we don't have to worry about function->ptr demotion // here. + if (E->changesVolatileQualification()) + return EmitLoadOfLValue(E); return EmitCast(E->getCastKind(), E->getSubExpr(), E->getType()); } ComplexPairTy VisitCastExpr(CastExpr *E) { if (const auto *ECE = dyn_cast<ExplicitCastExpr>(E)) CGF.CGM.EmitExplicitCastExprType(ECE, &CGF); + if (E->changesVolatileQualification()) + return EmitLoadOfLValue(E); return EmitCast(E->getCastKind(), E->getSubExpr(), E->getType()); } ComplexPairTy VisitCallExpr(const CallExpr *E); diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index a71b7057bb523a9..d76ce15b41ac570 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -2225,7 +2225,9 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) { return Visit(const_cast<Expr*>(E)); case CK_NoOp: { - llvm::Value *V = Visit(const_cast<Expr *>(E)); + llvm::Value *V = CE->changesVolatileQualification() + ? EmitLoadOfLValue(CE) + : Visit(const_cast<Expr *>(E)); if (V) { // CK_NoOp can model a pointer qualification conversion, which can remove // an array bound and change the IR type. diff --git a/clang/test/CodeGen/volatile.cpp b/clang/test/CodeGen/volatile.cpp new file mode 100644 index 000000000000000..38724659ad8a355 --- /dev/null +++ b/clang/test/CodeGen/volatile.cpp @@ -0,0 +1,43 @@ +// RUN: %clang_cc1 -O2 -triple=x86_64-unknown-linux-gnu -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK +struct agg +{ +int a ; +int b ; +} t; +struct agg a; +int vt=10; +_Complex float cf; +int volatile vol =10; +void f0() { + const_cast<volatile _Complex float &>(cf) = const_cast<volatile _Complex float&>(cf) + 1; +// CHECK: %cf.real = load volatile float, ptr @cf +// CHECK: %cf.imag = load volatile float, ptr getelementptr +// CHECK: %add.r = fadd float %cf.real, 1.000000e+00 +// CHECK: %add.i = fadd float %cf.imag, 0.000000e+00 +// CHECK: store volatile float %add.r +// CHECK: store volatile float %add.i, ptr getelementptr + static_cast<volatile _Complex float &>(cf) = static_cast<volatile _Complex float&>(cf) + 1; +// CHECK: %cf.real1 = load volatile float, ptr @cf +// CHECK: %cf.imag2 = load volatile float, ptr getelementptr +// CHECK: %add.r3 = fadd float %cf.real1, 1.000000e+00 +// CHECK: %add.i4 = fadd float %cf.imag2, 0.000000e+00 +// CHECK: store volatile float %add.r3, ptr @cf +// CHECK: store volatile float %add.i4, ptr getelementptr + const_cast<volatile int &>(a.a) = const_cast<volatile int &>(t.a) ; +// CHECK: %0 = load volatile i32, ptr @t +// CHECK: store volatile i32 %0, ptr @a + static_cast<volatile int &>(a.b) = static_cast<volatile int &>(t.a) ; +// CHECK: %1 = load volatile i32, ptr @t +// CHECK: store volatile i32 %1, ptr getelementptr + const_cast<volatile int&>(vt) = const_cast<volatile int&>(vt) + 1; +// CHECK: %2 = load volatile i32, ptr @vt +// CHECK: %add = add nsw i32 %2, 1 +// CHECK: store volatile i32 %add, ptr @vt + static_cast<volatile int&>(vt) = static_cast<volatile int&>(vt) + 1; +// CHECK: %3 = load volatile i32, ptr @vt +// CHECK: %add5 = add nsw i32 %3, 1 +// CHECK: store volatile i32 %add5, ptr @vt + vt = const_cast<int&>(vol); +// %4 = load i32, ptr @vol +// store i32 %4, ptr @vt +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits