Skip to content

Commit 0b4ee03

Browse files
committed
Refactoring with shouldCastToInt(). Also include atomic pointers.
1 parent 546dc22 commit 0b4ee03

File tree

2 files changed

+44
-45
lines changed

2 files changed

+44
-45
lines changed

clang/lib/CodeGen/CGAtomic.cpp

Lines changed: 41 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -197,11 +197,11 @@ namespace {
197197
llvm::Value *getScalarRValValueOrNull(RValue RVal) const;
198198

199199
/// Converts an rvalue to integer value if needed.
200-
llvm::Value *convertRValueToInt(RValue RVal, bool CastFP = true) const;
200+
llvm::Value *convertRValueToInt(RValue RVal, bool CmpXchg = false) const;
201201

202202
RValue ConvertToValueOrAtomic(llvm::Value *IntVal, AggValueSlot ResultSlot,
203203
SourceLocation Loc, bool AsValue,
204-
bool CastFP = true) const;
204+
bool CmpXchg = false) const;
205205

206206
/// Copy an atomic r-value into atomic-layout memory.
207207
void emitCopyIntoMemory(RValue rvalue) const;
@@ -264,15 +264,17 @@ namespace {
264264
llvm::AtomicOrdering AO, bool IsVolatile);
265265
/// Emits atomic load as LLVM instruction.
266266
llvm::Value *EmitAtomicLoadOp(llvm::AtomicOrdering AO, bool IsVolatile,
267-
bool CastFP = true);
267+
bool CmpXchg = false);
268268
/// Emits atomic compare-and-exchange op as a libcall.
269269
llvm::Value *EmitAtomicCompareExchangeLibcall(
270270
llvm::Value *ExpectedAddr, llvm::Value *DesiredAddr,
271271
llvm::AtomicOrdering Success =
272272
llvm::AtomicOrdering::SequentiallyConsistent,
273273
llvm::AtomicOrdering Failure =
274274
llvm::AtomicOrdering::SequentiallyConsistent);
275-
/// Emits atomic compare-and-exchange op as LLVM instruction.
275+
/// Emits atomic compare-and-exchange op as LLVM instruction. Operands
276+
/// must be of integer or pointer type, so float must be casted.
277+
/// TODO: this could change - see comment in AtomicExpandPass.cpp.
276278
std::pair<llvm::Value *, llvm::Value *> EmitAtomicCompareExchangeOp(
277279
llvm::Value *ExpectedVal, llvm::Value *DesiredVal,
278280
llvm::AtomicOrdering Success =
@@ -1401,13 +1403,22 @@ RValue AtomicInfo::convertAtomicTempToRValue(Address addr,
14011403
LVal.getBaseInfo(), TBAAAccessInfo()));
14021404
}
14031405

1406+
static bool shouldCastToInt(llvm::Type *ValTy, bool CmpXchg) {
1407+
// TODO: Also pass through non-ieee FP types.
1408+
bool KeepType = (ValTy->isIntegerTy() || ValTy->isPointerTy() ||
1409+
(ValTy->isIEEELikeFPTy() && !CmpXchg));
1410+
return !KeepType;
1411+
}
1412+
14041413
RValue AtomicInfo::ConvertToValueOrAtomic(llvm::Value *Val,
14051414
AggValueSlot ResultSlot,
14061415
SourceLocation Loc, bool AsValue,
1407-
bool CastFP) const {
1416+
bool CmpXchg) const {
14081417
// Try not to in some easy cases.
1409-
assert((Val->getType()->isIntegerTy() || Val->getType()->isIEEELikeFPTy()) &&
1410-
"Expected integer or floating point value");
1418+
assert((Val->getType()->isIntegerTy() || Val->getType()->isPointerTy() ||
1419+
Val->getType()->isIEEELikeFPTy()) &&
1420+
"Expected integer, pointer or floating point value when converting "
1421+
"result.");
14111422
if (getEvaluationKind() == TEK_Scalar &&
14121423
(((!LVal.isBitField() ||
14131424
LVal.getBitFieldInfo().Size == ValueSizeInBits) &&
@@ -1416,13 +1427,11 @@ RValue AtomicInfo::ConvertToValueOrAtomic(llvm::Value *Val,
14161427
auto *ValTy = AsValue
14171428
? CGF.ConvertTypeForMem(ValueTy)
14181429
: getAtomicAddress().getElementType();
1419-
if (ValTy->isIntegerTy() || (!CastFP && ValTy->isIEEELikeFPTy())) {
1430+
if (!shouldCastToInt(ValTy, CmpXchg)) {
14201431
assert((!ValTy->isIntegerTy() || Val->getType() == ValTy) &&
14211432
"Different integer types.");
14221433
return RValue::get(CGF.EmitFromMemory(Val, ValueTy));
1423-
} else if (ValTy->isPointerTy())
1424-
return RValue::get(CGF.Builder.CreateIntToPtr(Val, ValTy));
1425-
else if (llvm::CastInst::isBitCastable(Val->getType(), ValTy))
1434+
} else if (llvm::CastInst::isBitCastable(Val->getType(), ValTy))
14261435
return RValue::get(CGF.Builder.CreateBitCast(Val, ValTy));
14271436
}
14281437

@@ -1459,10 +1468,10 @@ void AtomicInfo::EmitAtomicLoadLibcall(llvm::Value *AddForLoaded,
14591468
}
14601469

14611470
llvm::Value *AtomicInfo::EmitAtomicLoadOp(llvm::AtomicOrdering AO,
1462-
bool IsVolatile, bool CastFP) {
1471+
bool IsVolatile, bool CmpXchg) {
14631472
// Okay, we're doing this natively.
14641473
Address Addr = getAtomicAddress();
1465-
if (!(Addr.getElementType()->isIEEELikeFPTy() && !CastFP))
1474+
if (shouldCastToInt(Addr.getElementType(), CmpXchg))
14661475
Addr = castToAtomicIntPointer(Addr);
14671476
llvm::LoadInst *Load = CGF.Builder.CreateLoad(Addr, "atomic-load");
14681477
Load->setAtomic(AO);
@@ -1523,16 +1532,15 @@ RValue AtomicInfo::EmitAtomicLoad(AggValueSlot ResultSlot, SourceLocation Loc,
15231532
}
15241533

15251534
// Okay, we're doing this natively.
1526-
auto *Load = EmitAtomicLoadOp(AO, IsVolatile, /*CastFP=*/false);
1535+
auto *Load = EmitAtomicLoadOp(AO, IsVolatile);
15271536

15281537
// If we're ignoring an aggregate return, don't do anything.
15291538
if (getEvaluationKind() == TEK_Aggregate && ResultSlot.isIgnored())
15301539
return RValue::getAggregate(Address::invalid(), false);
15311540

15321541
// Okay, turn that back into the original value or atomic (for non-simple
15331542
// lvalues) type.
1534-
return ConvertToValueOrAtomic(Load, ResultSlot, Loc, AsValue,
1535-
/*CastFP=*/false);
1543+
return ConvertToValueOrAtomic(Load, ResultSlot, Loc, AsValue);
15361544
}
15371545

15381546
/// Emit a load from an l-value of atomic type. Note that the r-value
@@ -1601,20 +1609,17 @@ llvm::Value *AtomicInfo::getScalarRValValueOrNull(RValue RVal) const {
16011609
return nullptr;
16021610
}
16031611

1604-
llvm::Value *AtomicInfo::convertRValueToInt(RValue RVal, bool CastFP) const {
1612+
llvm::Value *AtomicInfo::convertRValueToInt(RValue RVal, bool CmpXchg) const {
16051613
// If we've got a scalar value of the right size, try to avoid going
16061614
// through memory. Floats get casted if needed by AtomicExpandPass.
16071615
if (llvm::Value *Value = getScalarRValValueOrNull(RVal)) {
1608-
if (isa<llvm::IntegerType>(Value->getType()) ||
1609-
(!CastFP && Value->getType()->isIEEELikeFPTy()))
1616+
if (!shouldCastToInt(Value->getType(), CmpXchg))
16101617
return CGF.EmitToMemory(Value, ValueTy);
16111618
else {
16121619
llvm::IntegerType *InputIntTy = llvm::IntegerType::get(
16131620
CGF.getLLVMContext(),
16141621
LVal.isSimple() ? getValueSizeInBits() : getAtomicSizeInBits());
1615-
if (isa<llvm::PointerType>(Value->getType()))
1616-
return CGF.Builder.CreatePtrToInt(Value, InputIntTy);
1617-
else if (llvm::BitCastInst::isBitCastable(Value->getType(), InputIntTy))
1622+
if (llvm::BitCastInst::isBitCastable(Value->getType(), InputIntTy))
16181623
return CGF.Builder.CreateBitCast(Value, InputIntTy);
16191624
}
16201625
}
@@ -1687,13 +1692,14 @@ std::pair<RValue, llvm::Value *> AtomicInfo::EmitAtomicCompareExchange(
16871692

16881693
// If we've got a scalar value of the right size, try to avoid going
16891694
// through memory.
1690-
auto *ExpectedVal = convertRValueToInt(Expected);
1691-
auto *DesiredVal = convertRValueToInt(Desired);
1695+
auto *ExpectedVal = convertRValueToInt(Expected, /*CmpXchg=*/true);
1696+
auto *DesiredVal = convertRValueToInt(Desired, /*CmpXchg=*/true);
16921697
auto Res = EmitAtomicCompareExchangeOp(ExpectedVal, DesiredVal, Success,
16931698
Failure, IsWeak);
16941699
return std::make_pair(
16951700
ConvertToValueOrAtomic(Res.first, AggValueSlot::ignored(),
1696-
SourceLocation(), /*AsValue=*/false),
1701+
SourceLocation(), /*AsValue=*/false,
1702+
/*CmpXchg=*/true),
16971703
Res.second);
16981704
}
16991705

@@ -1787,7 +1793,7 @@ void AtomicInfo::EmitAtomicUpdateOp(
17871793
auto Failure = llvm::AtomicCmpXchgInst::getStrongestFailureOrdering(AO);
17881794

17891795
// Do the atomic load.
1790-
auto *OldVal = EmitAtomicLoadOp(Failure, IsVolatile);
1796+
auto *OldVal = EmitAtomicLoadOp(Failure, IsVolatile, /*CmpXchg=*/true);
17911797
// For non-simple lvalues perform compare-and-swap procedure.
17921798
auto *ContBB = CGF.createBasicBlock("atomic_cont");
17931799
auto *ExitBB = CGF.createBasicBlock("atomic_exit");
@@ -1803,7 +1809,8 @@ void AtomicInfo::EmitAtomicUpdateOp(
18031809
CGF.Builder.CreateStore(PHI, NewAtomicIntAddr);
18041810
}
18051811
auto OldRVal = ConvertToValueOrAtomic(PHI, AggValueSlot::ignored(),
1806-
SourceLocation(), /*AsValue=*/false);
1812+
SourceLocation(), /*AsValue=*/false,
1813+
/*CmpXchg=*/true);
18071814
EmitAtomicUpdateValue(CGF, *this, OldRVal, UpdateOp, NewAtomicAddr);
18081815
auto *DesiredVal = CGF.Builder.CreateLoad(NewAtomicIntAddr);
18091816
// Try to write new value using cmpxchg operation.
@@ -1869,7 +1876,7 @@ void AtomicInfo::EmitAtomicUpdateOp(llvm::AtomicOrdering AO, RValue UpdateRVal,
18691876
auto Failure = llvm::AtomicCmpXchgInst::getStrongestFailureOrdering(AO);
18701877

18711878
// Do the atomic load.
1872-
auto *OldVal = EmitAtomicLoadOp(Failure, IsVolatile);
1879+
auto *OldVal = EmitAtomicLoadOp(Failure, IsVolatile, /*CmpXchg=*/true);
18731880
// For non-simple lvalues perform compare-and-swap procedure.
18741881
auto *ContBB = CGF.createBasicBlock("atomic_cont");
18751882
auto *ExitBB = CGF.createBasicBlock("atomic_exit");
@@ -1969,21 +1976,16 @@ void CodeGenFunction::EmitAtomicStore(RValue rvalue, LValue dest,
19691976
}
19701977

19711978
// Okay, we're doing this natively.
1972-
llvm::Value *ValToStore =
1973-
atomics.convertRValueToInt(rvalue, /*CastFP=*/false);
1979+
llvm::Value *ValToStore = atomics.convertRValueToInt(rvalue);
19741980

19751981
// Do the atomic store.
19761982
Address Addr = atomics.getAtomicAddress();
1977-
bool ShouldCastToInt = true;
19781983
if (llvm::Value *Value = atomics.getScalarRValValueOrNull(rvalue))
1979-
if (isa<llvm::IntegerType>(Value->getType()) ||
1980-
Value->getType()->isIEEELikeFPTy())
1981-
ShouldCastToInt = false;
1982-
if (ShouldCastToInt) {
1983-
Addr = atomics.castToAtomicIntPointer(Addr);
1984-
ValToStore = Builder.CreateIntCast(ValToStore, Addr.getElementType(),
1985-
/*isSigned=*/false);
1986-
}
1984+
if (shouldCastToInt(Value->getType(), /*CmpXchg=*/false)) {
1985+
Addr = atomics.castToAtomicIntPointer(Addr);
1986+
ValToStore = Builder.CreateIntCast(ValToStore, Addr.getElementType(),
1987+
/*isSigned=*/false);
1988+
}
19871989
llvm::StoreInst *store = Builder.CreateStore(ValToStore, Addr);
19881990

19891991
if (AO == llvm::AtomicOrdering::Acquire)

clang/test/CodeGen/atomic.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -134,14 +134,11 @@ static _Atomic float glob_flt = 0.0f;
134134

135135
void force_global_uses(void) {
136136
(void)glob_pointer;
137-
// CHECK: %[[LOCAL_INT:.+]] = load atomic i32, ptr @[[GLOB_POINTER]] seq_cst
138-
// CHECK-NEXT: inttoptr i32 %[[LOCAL_INT]] to ptr
137+
// CHECK: load atomic ptr, ptr @[[GLOB_POINTER]] seq_cst
139138
(void)glob_pointer_from_int;
140-
// CHECK: %[[LOCAL_INT_2:.+]] = load atomic i32, ptr @[[GLOB_POINTER_FROM_INT]] seq_cst
141-
// CHECK-NEXT: inttoptr i32 %[[LOCAL_INT_2]] to ptr
139+
// CHECK-NEXT: load atomic ptr, ptr @[[GLOB_POINTER_FROM_INT]] seq_cst
142140
(void)nonstatic_glob_pointer_from_int;
143-
// CHECK: %[[LOCAL_INT_3:.+]] = load atomic i32, ptr @[[NONSTATIC_GLOB_POINTER_FROM_INT]] seq_cst
144-
// CHECK-NEXT: inttoptr i32 %[[LOCAL_INT_3]] to ptr
141+
// CHECK-NEXT: load atomic ptr, ptr @[[NONSTATIC_GLOB_POINTER_FROM_INT]] seq_cst
145142
(void)glob_int;
146143
// CHECK: load atomic i32, ptr @[[GLOB_INT]] seq_cst
147144
(void)glob_flt;

0 commit comments

Comments
 (0)