diff --git a/clang/lib/CodeGen/CGAtomic.cpp b/clang/lib/CodeGen/CGAtomic.cpp index 672e82f8dcc3e..0af3cd07b13a0 100644 --- a/clang/lib/CodeGen/CGAtomic.cpp +++ b/clang/lib/CodeGen/CGAtomic.cpp @@ -590,6 +590,7 @@ static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr *E, Address Dest, llvm::LoadInst *Load = CGF.Builder.CreateLoad(Ptr); Load->setAtomic(Order, Scope); Load->setVolatile(E->isVolatile()); + CGF.maybeAttachRangeForLoad(Load, E->getValueType(), E->getExprLoc()); CGF.Builder.CreateStore(Load, Dest); return; } diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 62eaff4e6a978..52960a976152a 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -1919,6 +1919,20 @@ llvm::MDNode *CodeGenFunction::getRangeForLoadFromType(QualType Ty) { return MDHelper.createRange(Min, End); } +void CodeGenFunction::maybeAttachRangeForLoad(llvm::LoadInst *Load, QualType Ty, + SourceLocation Loc) { + if (EmitScalarRangeCheck(Load, Ty, Loc)) { + // In order to prevent the optimizer from throwing away the check, don't + // attach range metadata to the load. + } else if (CGM.getCodeGenOpts().OptimizationLevel > 0) { + if (llvm::MDNode *RangeInfo = getRangeForLoadFromType(Ty)) { + Load->setMetadata(llvm::LLVMContext::MD_range, RangeInfo); + Load->setMetadata(llvm::LLVMContext::MD_noundef, + llvm::MDNode::get(CGM.getLLVMContext(), {})); + } + } +} + bool CodeGenFunction::EmitScalarRangeCheck(llvm::Value *Value, QualType Ty, SourceLocation Loc) { bool HasBoolCheck = SanOpts.has(SanitizerKind::Bool); @@ -2037,15 +2051,7 @@ llvm::Value *CodeGenFunction::EmitLoadOfScalar(Address Addr, bool Volatile, CGM.DecorateInstructionWithTBAA(Load, TBAAInfo); - if (EmitScalarRangeCheck(Load, Ty, Loc)) { - // In order to prevent the optimizer from throwing away the check, don't - // attach range metadata to the load. - } else if (CGM.getCodeGenOpts().OptimizationLevel > 0) - if (llvm::MDNode *RangeInfo = getRangeForLoadFromType(Ty)) { - Load->setMetadata(llvm::LLVMContext::MD_range, RangeInfo); - Load->setMetadata(llvm::LLVMContext::MD_noundef, - llvm::MDNode::get(getLLVMContext(), {})); - } + maybeAttachRangeForLoad(Load, Ty, Loc); return EmitFromMemory(Load, Ty); } diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index a398ba55dcdc7..1da54888a3e78 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -5306,6 +5306,9 @@ class CodeGenFunction : public CodeGenTypeCache { unsigned NumElementsDst, const llvm::Twine &Name = ""); + void maybeAttachRangeForLoad(llvm::LoadInst *Load, QualType Ty, + SourceLocation Loc); + private: // Emits a convergence_loop instruction for the given |BB|, with |ParentToken| // as it's parent convergence instr. diff --git a/clang/test/CodeGen/atomic-ops-load.c b/clang/test/CodeGen/atomic-ops-load.c new file mode 100644 index 0000000000000..778a7ebdc2618 --- /dev/null +++ b/clang/test/CodeGen/atomic-ops-load.c @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -triple riscv64 -O1 -emit-llvm %s -o - | FileCheck %s +#include + +extern bool t1; +bool test1(void) { +// CHECK-LABEL: define{{.*}} i1 @test1 +// CHECK: load atomic i8, ptr @t1 monotonic, align 1, !range ![[$WS_RANGE:[0-9]*]], !noundef !{{[0-9]+}} +// CHECK-NEXT: trunc nuw i8 %{{.*}} to i1 +// CHECK-NEXT: ret i1 %{{.*}} + return __atomic_load_n(&t1, __ATOMIC_RELAXED); +}