Skip to content

Commit 2a9f19f

Browse files
committed
Refactoring with shouldCastToInt(). Also include atomic pointers.
1 parent 57146da commit 2a9f19f

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 =
@@ -1399,13 +1401,22 @@ RValue AtomicInfo::convertAtomicTempToRValue(Address addr,
13991401
LVal.getBaseInfo(), TBAAAccessInfo()));
14001402
}
14011403

1404+
static bool shouldCastToInt(llvm::Type *ValTy, bool CmpXchg) {
1405+
// TODO: Also pass through non-ieee FP types.
1406+
bool KeepType = (ValTy->isIntegerTy() || ValTy->isPointerTy() ||
1407+
(ValTy->isIEEELikeFPTy() && !CmpXchg));
1408+
return !KeepType;
1409+
}
1410+
14021411
RValue AtomicInfo::ConvertToValueOrAtomic(llvm::Value *Val,
14031412
AggValueSlot ResultSlot,
14041413
SourceLocation Loc, bool AsValue,
1405-
bool CastFP) const {
1414+
bool CmpXchg) const {
14061415
// Try not to in some easy cases.
1407-
assert((Val->getType()->isIntegerTy() || Val->getType()->isIEEELikeFPTy()) &&
1408-
"Expected integer or floating point value");
1416+
assert((Val->getType()->isIntegerTy() || Val->getType()->isPointerTy() ||
1417+
Val->getType()->isIEEELikeFPTy()) &&
1418+
"Expected integer, pointer or floating point value when converting "
1419+
"result.");
14091420
if (getEvaluationKind() == TEK_Scalar &&
14101421
(((!LVal.isBitField() ||
14111422
LVal.getBitFieldInfo().Size == ValueSizeInBits) &&
@@ -1414,13 +1425,11 @@ RValue AtomicInfo::ConvertToValueOrAtomic(llvm::Value *Val,
14141425
auto *ValTy = AsValue
14151426
? CGF.ConvertTypeForMem(ValueTy)
14161427
: getAtomicAddress().getElementType();
1417-
if (ValTy->isIntegerTy() || (!CastFP && ValTy->isIEEELikeFPTy())) {
1428+
if (!shouldCastToInt(ValTy, CmpXchg)) {
14181429
assert((!ValTy->isIntegerTy() || Val->getType() == ValTy) &&
14191430
"Different integer types.");
14201431
return RValue::get(CGF.EmitFromMemory(Val, ValueTy));
1421-
} else if (ValTy->isPointerTy())
1422-
return RValue::get(CGF.Builder.CreateIntToPtr(Val, ValTy));
1423-
else if (llvm::CastInst::isBitCastable(Val->getType(), ValTy))
1432+
} else if (llvm::CastInst::isBitCastable(Val->getType(), ValTy))
14241433
return RValue::get(CGF.Builder.CreateBitCast(Val, ValTy));
14251434
}
14261435

@@ -1457,10 +1466,10 @@ void AtomicInfo::EmitAtomicLoadLibcall(llvm::Value *AddForLoaded,
14571466
}
14581467

14591468
llvm::Value *AtomicInfo::EmitAtomicLoadOp(llvm::AtomicOrdering AO,
1460-
bool IsVolatile, bool CastFP) {
1469+
bool IsVolatile, bool CmpXchg) {
14611470
// Okay, we're doing this natively.
14621471
Address Addr = getAtomicAddress();
1463-
if (!(Addr.getElementType()->isIEEELikeFPTy() && !CastFP))
1472+
if (shouldCastToInt(Addr.getElementType(), CmpXchg))
14641473
Addr = castToAtomicIntPointer(Addr);
14651474
llvm::LoadInst *Load = CGF.Builder.CreateLoad(Addr, "atomic-load");
14661475
Load->setAtomic(AO);
@@ -1521,16 +1530,15 @@ RValue AtomicInfo::EmitAtomicLoad(AggValueSlot ResultSlot, SourceLocation Loc,
15211530
}
15221531

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

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

15301539
// Okay, turn that back into the original value or atomic (for non-simple
15311540
// lvalues) type.
1532-
return ConvertToValueOrAtomic(Load, ResultSlot, Loc, AsValue,
1533-
/*CastFP=*/false);
1541+
return ConvertToValueOrAtomic(Load, ResultSlot, Loc, AsValue);
15341542
}
15351543

15361544
/// Emit a load from an l-value of atomic type. Note that the r-value
@@ -1599,20 +1607,17 @@ llvm::Value *AtomicInfo::getScalarRValValueOrNull(RValue RVal) const {
15991607
return nullptr;
16001608
}
16011609

1602-
llvm::Value *AtomicInfo::convertRValueToInt(RValue RVal, bool CastFP) const {
1610+
llvm::Value *AtomicInfo::convertRValueToInt(RValue RVal, bool CmpXchg) const {
16031611
// If we've got a scalar value of the right size, try to avoid going
16041612
// through memory. Floats get casted if needed by AtomicExpandPass.
16051613
if (llvm::Value *Value = getScalarRValValueOrNull(RVal)) {
1606-
if (isa<llvm::IntegerType>(Value->getType()) ||
1607-
(!CastFP && Value->getType()->isIEEELikeFPTy()))
1614+
if (!shouldCastToInt(Value->getType(), CmpXchg))
16081615
return CGF.EmitToMemory(Value, ValueTy);
16091616
else {
16101617
llvm::IntegerType *InputIntTy = llvm::IntegerType::get(
16111618
CGF.getLLVMContext(),
16121619
LVal.isSimple() ? getValueSizeInBits() : getAtomicSizeInBits());
1613-
if (isa<llvm::PointerType>(Value->getType()))
1614-
return CGF.Builder.CreatePtrToInt(Value, InputIntTy);
1615-
else if (llvm::BitCastInst::isBitCastable(Value->getType(), InputIntTy))
1620+
if (llvm::BitCastInst::isBitCastable(Value->getType(), InputIntTy))
16161621
return CGF.Builder.CreateBitCast(Value, InputIntTy);
16171622
}
16181623
}
@@ -1685,13 +1690,14 @@ std::pair<RValue, llvm::Value *> AtomicInfo::EmitAtomicCompareExchange(
16851690

16861691
// If we've got a scalar value of the right size, try to avoid going
16871692
// through memory.
1688-
auto *ExpectedVal = convertRValueToInt(Expected);
1689-
auto *DesiredVal = convertRValueToInt(Desired);
1693+
auto *ExpectedVal = convertRValueToInt(Expected, /*CmpXchg=*/true);
1694+
auto *DesiredVal = convertRValueToInt(Desired, /*CmpXchg=*/true);
16901695
auto Res = EmitAtomicCompareExchangeOp(ExpectedVal, DesiredVal, Success,
16911696
Failure, IsWeak);
16921697
return std::make_pair(
16931698
ConvertToValueOrAtomic(Res.first, AggValueSlot::ignored(),
1694-
SourceLocation(), /*AsValue=*/false),
1699+
SourceLocation(), /*AsValue=*/false,
1700+
/*CmpXchg=*/true),
16951701
Res.second);
16961702
}
16971703

@@ -1785,7 +1791,7 @@ void AtomicInfo::EmitAtomicUpdateOp(
17851791
auto Failure = llvm::AtomicCmpXchgInst::getStrongestFailureOrdering(AO);
17861792

17871793
// Do the atomic load.
1788-
auto *OldVal = EmitAtomicLoadOp(Failure, IsVolatile);
1794+
auto *OldVal = EmitAtomicLoadOp(Failure, IsVolatile, /*CmpXchg=*/true);
17891795
// For non-simple lvalues perform compare-and-swap procedure.
17901796
auto *ContBB = CGF.createBasicBlock("atomic_cont");
17911797
auto *ExitBB = CGF.createBasicBlock("atomic_exit");
@@ -1801,7 +1807,8 @@ void AtomicInfo::EmitAtomicUpdateOp(
18011807
CGF.Builder.CreateStore(PHI, NewAtomicIntAddr);
18021808
}
18031809
auto OldRVal = ConvertToValueOrAtomic(PHI, AggValueSlot::ignored(),
1804-
SourceLocation(), /*AsValue=*/false);
1810+
SourceLocation(), /*AsValue=*/false,
1811+
/*CmpXchg=*/true);
18051812
EmitAtomicUpdateValue(CGF, *this, OldRVal, UpdateOp, NewAtomicAddr);
18061813
auto *DesiredVal = CGF.Builder.CreateLoad(NewAtomicIntAddr);
18071814
// Try to write new value using cmpxchg operation.
@@ -1867,7 +1874,7 @@ void AtomicInfo::EmitAtomicUpdateOp(llvm::AtomicOrdering AO, RValue UpdateRVal,
18671874
auto Failure = llvm::AtomicCmpXchgInst::getStrongestFailureOrdering(AO);
18681875

18691876
// Do the atomic load.
1870-
auto *OldVal = EmitAtomicLoadOp(Failure, IsVolatile);
1877+
auto *OldVal = EmitAtomicLoadOp(Failure, IsVolatile, /*CmpXchg=*/true);
18711878
// For non-simple lvalues perform compare-and-swap procedure.
18721879
auto *ContBB = CGF.createBasicBlock("atomic_cont");
18731880
auto *ExitBB = CGF.createBasicBlock("atomic_exit");
@@ -1966,21 +1973,16 @@ void CodeGenFunction::EmitAtomicStore(RValue rvalue, LValue dest,
19661973
}
19671974

19681975
// Okay, we're doing this natively.
1969-
llvm::Value *ValToStore =
1970-
atomics.convertRValueToInt(rvalue, /*CastFP=*/false);
1976+
llvm::Value *ValToStore = atomics.convertRValueToInt(rvalue);
19711977

19721978
// Do the atomic store.
19731979
Address Addr = atomics.getAtomicAddress();
1974-
bool ShouldCastToInt = true;
19751980
if (llvm::Value *Value = atomics.getScalarRValValueOrNull(rvalue))
1976-
if (isa<llvm::IntegerType>(Value->getType()) ||
1977-
Value->getType()->isIEEELikeFPTy())
1978-
ShouldCastToInt = false;
1979-
if (ShouldCastToInt) {
1980-
Addr = atomics.castToAtomicIntPointer(Addr);
1981-
ValToStore = Builder.CreateIntCast(ValToStore, Addr.getElementType(),
1982-
/*isSigned=*/false);
1983-
}
1981+
if (shouldCastToInt(Value->getType(), /*CmpXchg=*/false)) {
1982+
Addr = atomics.castToAtomicIntPointer(Addr);
1983+
ValToStore = Builder.CreateIntCast(ValToStore, Addr.getElementType(),
1984+
/*isSigned=*/false);
1985+
}
19841986
llvm::StoreInst *store = Builder.CreateStore(ValToStore, Addr);
19851987

19861988
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)