Skip to content

Commit c47687d

Browse files
authored
Add an isStrict flag to SIL pointer_to_address. (#3529)
Strict aliasing only applies to memory operations that use strict addresses. The optimizer needs to be aware of this flag. Uses of raw addresses should not have their address substituted with a strict address. Also add Builtin.LoadRaw which will be used by raw pointer loads.
1 parent 5564f94 commit c47687d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+366
-207
lines changed

docs/SIL.rst

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3700,9 +3700,9 @@ pointer_to_address
37003700
``````````````````
37013701
::
37023702

3703-
sil-instruction ::= 'pointer_to_address' sil-operand 'to' sil-type
3703+
sil-instruction ::= 'pointer_to_address' sil-operand 'to' ('[' 'strict' ']')? sil-type
37043704

3705-
%1 = pointer_to_address %0 : $Builtin.RawPointer to $*T
3705+
%1 = pointer_to_address %0 : $Builtin.RawPointer to [strict] $*T
37063706
// %1 will be of type $*T
37073707

37083708
Creates an address value corresponding to the ``Builtin.RawPointer`` value
@@ -3713,6 +3713,14 @@ other than its original address type or `layout compatible types`_. It is
37133713
also undefined behavior to cast a ``RawPointer`` from a heap object to any
37143714
address type.
37153715

3716+
The ``strict`` flag indicates whether the returned address adheres to
3717+
strict aliasing. If true, then the type of each memory access
3718+
dependent on this address must be consistent with the memory's bound
3719+
type. A memory access from an address that is not strict cannot have
3720+
its address substituted with a strict address, even if other nearby
3721+
memory accesses at the same location are strict.
3722+
3723+
37163724
unchecked_ref_cast
37173725
``````````````````
37183726
::

include/swift/AST/Builtins.def

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,11 @@ BUILTIN_SIL_OPERATION(Unpin, "unpin", Special)
177177
/// Load has type (Builtin.RawPointer) -> T
178178
BUILTIN_SIL_OPERATION(Load, "load", Special)
179179

180+
/// LoadRaw has type (Builtin.RawPointer) -> T
181+
/// This is a load of T from raw memory.
182+
/// It's address does not adhere to strict aliasing.
183+
BUILTIN_SIL_OPERATION(LoadRaw, "loadRaw", Special)
184+
180185
/// Take has type (Builtin.RawPointer) -> T
181186
BUILTIN_SIL_OPERATION(Take, "take", Special)
182187

include/swift/SIL/SILBuilder.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -548,9 +548,9 @@ class SILBuilder {
548548
}
549549

550550
PointerToAddressInst *createPointerToAddress(SILLocation Loc, SILValue Op,
551-
SILType Ty) {
551+
SILType Ty, bool isStrict) {
552552
return insert(new (F.getModule()) PointerToAddressInst(
553-
getSILDebugLocation(Loc), Op, Ty));
553+
getSILDebugLocation(Loc), Op, Ty, isStrict));
554554
}
555555

556556
UncheckedRefCastInst *createUncheckedRefCast(SILLocation Loc, SILValue Op,

include/swift/SIL/SILCloner.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -845,7 +845,8 @@ SILCloner<ImplClass>::visitPointerToAddressInst(PointerToAddressInst *Inst) {
845845
doPostProcess(Inst,
846846
getBuilder().createPointerToAddress(getOpLocation(Inst->getLoc()),
847847
getOpValue(Inst->getOperand()),
848-
getOpType(Inst->getType())));
848+
getOpType(Inst->getType()),
849+
Inst->isStrict()));
849850
}
850851

851852
template<typename ImplClass>

include/swift/SIL/SILInstruction.h

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2131,8 +2131,17 @@ class PointerToAddressInst
21312131
{
21322132
friend class SILBuilder;
21332133

2134-
PointerToAddressInst(SILDebugLocation DebugLoc, SILValue Operand, SILType Ty)
2135-
: UnaryInstructionBase(DebugLoc, Operand, Ty) {}
2134+
bool IsStrict;
2135+
2136+
PointerToAddressInst(SILDebugLocation DebugLoc, SILValue Operand, SILType Ty,
2137+
bool IsStrict)
2138+
: UnaryInstructionBase(DebugLoc, Operand, Ty), IsStrict(IsStrict) {}
2139+
2140+
public:
2141+
/// Whether the returned address adheres to strict aliasing.
2142+
/// If true, then the type of each memory access dependent on
2143+
/// this address must be consistent with the memory's bound type.
2144+
bool isStrict() const { return IsStrict; }
21362145
};
21372146

21382147
/// Convert a heap object reference to a different type without any runtime

lib/AST/Builtins.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1473,6 +1473,7 @@ ValueDecl *swift::getBuiltinValueDecl(ASTContext &Context, Identifier Id) {
14731473
return getRefCountingOperation(Context, Id);
14741474

14751475
case BuiltinValueKind::Load:
1476+
case BuiltinValueKind::LoadRaw:
14761477
case BuiltinValueKind::Take:
14771478
if (!Types.empty()) return nullptr;
14781479
return getLoadOperation(Context, Id);

lib/IRGen/IRGenSIL.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3735,6 +3735,7 @@ void IRGenSILFunction::visitAddressToPointerInst(swift::AddressToPointerInst *i)
37353735
setLoweredExplosion(i, to);
37363736
}
37373737

3738+
// Ignores the isStrict flag because Swift TBAA is not lowered into LLVM IR.
37383739
void IRGenSILFunction::visitPointerToAddressInst(swift::PointerToAddressInst *i)
37393740
{
37403741
Explosion from = getLoweredExplosion(i->getOperand());

lib/Parse/ParseSIL.cpp

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2001,7 +2001,6 @@ bool SILParser::parseSILInstruction(SILBasicBlock *BB, SILBuilder &B) {
20012001
case ValueKind::UncheckedBitwiseCastInst:
20022002
case ValueKind::UpcastInst:
20032003
case ValueKind::AddressToPointerInst:
2004-
case ValueKind::PointerToAddressInst:
20052004
case ValueKind::BridgeObjectToRefInst:
20062005
case ValueKind::BridgeObjectToWordInst:
20072006
case ValueKind::RefToRawPointerInst:
@@ -2056,9 +2055,6 @@ bool SILParser::parseSILInstruction(SILBasicBlock *BB, SILBuilder &B) {
20562055
case ValueKind::AddressToPointerInst:
20572056
ResultVal = B.createAddressToPointer(InstLoc, Val, Ty);
20582057
break;
2059-
case ValueKind::PointerToAddressInst:
2060-
ResultVal = B.createPointerToAddress(InstLoc, Val, Ty);
2061-
break;
20622058
case ValueKind::BridgeObjectToRefInst:
20632059
ResultVal = B.createBridgeObjectToRef(InstLoc, Val, Ty);
20642060
break;
@@ -2107,7 +2103,27 @@ bool SILParser::parseSILInstruction(SILBasicBlock *BB, SILBuilder &B) {
21072103
}
21082104
break;
21092105
}
2110-
2106+
case ValueKind::PointerToAddressInst: {
2107+
SILType Ty;
2108+
Identifier ToToken;
2109+
SourceLoc ToLoc;
2110+
bool isStrict = false;
2111+
if (parseTypedValueRef(Val, B) ||
2112+
parseSILIdentifier(ToToken, ToLoc,
2113+
diag::expected_tok_in_sil_instr, "to") ||
2114+
parseSILOptional(isStrict, *this, "strict") ||
2115+
parseSILType(Ty) ||
2116+
parseSILDebugLocation(InstLoc, B))
2117+
return true;
2118+
2119+
if (ToToken.str() != "to") {
2120+
P.diagnose(ToLoc, diag::expected_tok_in_sil_instr, "to");
2121+
return true;
2122+
}
2123+
2124+
ResultVal = B.createPointerToAddress(InstLoc, Val, Ty, isStrict);
2125+
break;
2126+
}
21112127
case ValueKind::RefToBridgeObjectInst: {
21122128
SILValue BitsVal;
21132129
if (parseTypedValueRef(Val, B) ||

lib/SIL/SILInstruction.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -517,7 +517,7 @@ namespace {
517517
}
518518

519519
bool visitPointerToAddressInst(PointerToAddressInst *RHS) {
520-
return true;
520+
return cast<PointerToAddressInst>(LHS)->isStrict() == RHS->isStrict();
521521
}
522522

523523
bool visitRefToRawPointerInst(RefToRawPointerInst *RHS) {

lib/SIL/SILPrinter.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1079,7 +1079,10 @@ class SILPrinter : public SILVisitor<SILPrinter> {
10791079
printUncheckedConversionInst(CI, CI->getOperand(), "address_to_pointer");
10801080
}
10811081
void visitPointerToAddressInst(PointerToAddressInst *CI) {
1082-
printUncheckedConversionInst(CI, CI->getOperand(), "pointer_to_address");
1082+
*this << "pointer_to_address " << getIDAndType(CI->getOperand()) << " to ";
1083+
if (CI->isStrict())
1084+
*this << "[strict] ";
1085+
*this << CI->getType();
10831086
}
10841087
void visitUncheckedRefCastInst(UncheckedRefCastInst *CI) {
10851088
printUncheckedConversionInst(CI, CI->getOperand(), "unchecked_ref_cast");

0 commit comments

Comments
 (0)