mirror of
https://github.com/intel/llvm.git
synced 2026-01-24 17:01:00 +08:00
Fixes #131476. For `x86_64` it folds ``` movzbl t1(%rip), %eax andb $1, %al ``` into ``` movzbl t1(%rip), %eax ``` when run: `clang -S atomic-ops-load.c -o atomic-ops-load.s -O1 --target=x86_64`. But for riscv replaces: ``` lb a0, %lo(t1)(a0) andi a0, a0, 1 ``` with ``` lb a0, %lo(t1)(a0) zext.b a0, a0 ``` when run: `clang -S atomic-ops-load.c -o atomic-ops-load.s -O1 --target=riscv64`.
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -5309,6 +5309,9 @@ public:
|
||||
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.
|
||||
|
||||
11
clang/test/CodeGen/atomic-ops-load.c
Normal file
11
clang/test/CodeGen/atomic-ops-load.c
Normal file
@@ -0,0 +1,11 @@
|
||||
// RUN: %clang_cc1 -triple riscv64 -O1 -emit-llvm %s -o - | FileCheck %s
|
||||
#include <stdbool.h>
|
||||
|
||||
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);
|
||||
}
|
||||
Reference in New Issue
Block a user