summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Analysis/BasicAliasAnalysis.cpp16
-rw-r--r--llvm/lib/Analysis/ConstantFolding.cpp9
-rw-r--r--llvm/lib/Analysis/ValueTracking.cpp21
-rw-r--r--llvm/lib/CodeGen/CodeGenPrepare.cpp1
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/FastISel.cpp1
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp1
-rw-r--r--llvm/lib/IR/Value.cpp3
-rw-r--r--llvm/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp2
8 files changed, 34 insertions, 20 deletions
diff --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
index 0167751d2fd..883462a6fcb 100644
--- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp
+++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
@@ -431,13 +431,15 @@ bool BasicAAResult::DecomposeGEPExpression(const Value *V,
const GEPOperator *GEPOp = dyn_cast<GEPOperator>(Op);
if (!GEPOp) {
if (auto CS = ImmutableCallSite(V)) {
- // Note: getArgumentAliasingToReturnedPointer keeps it in sync with
- // CaptureTracking, which is needed for correctness. This is because
- // some intrinsics like launder.invariant.group returns pointers that
- // are aliasing it's argument, which is known to CaptureTracking.
- // If AliasAnalysis does not use the same information, it could assume
- // that pointer returned from launder does not alias it's argument
- // because launder could not return it if the pointer was not captured.
+ // CaptureTracking can know about special capturing properties of some
+ // intrinsics like launder.invariant.group, that can't be expressed with
+ // the attributes, but have properties like returning aliasing pointer.
+ // Because some analysis may assume that nocaptured pointer is not
+ // returned from some special intrinsic (because function would have to
+ // be marked with returns attribute), it is crucial to use this function
+ // because it should be in sync with CaptureTracking. Not using it may
+ // cause weird miscompilations where 2 aliasing pointers are assumed to
+ // noalias.
if (auto *RP = getArgumentAliasingToReturnedPointer(CS)) {
V = RP;
continue;
diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index 08c571f664e..38e018f6db0 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -1393,6 +1393,7 @@ bool llvm::canConstantFoldCallTo(ImmutableCallSite CS, const Function *F) {
case Intrinsic::fmuladd:
case Intrinsic::copysign:
case Intrinsic::launder_invariant_group:
+ case Intrinsic::strip_invariant_group:
case Intrinsic::round:
case Intrinsic::masked_load:
case Intrinsic::sadd_with_overflow:
@@ -1596,14 +1597,16 @@ Constant *ConstantFoldScalarCall(StringRef Name, unsigned IntrinsicID, Type *Ty,
return Constant::getNullValue(Ty);
if (IntrinsicID == Intrinsic::bswap ||
IntrinsicID == Intrinsic::bitreverse ||
- IntrinsicID == Intrinsic::launder_invariant_group)
+ IntrinsicID == Intrinsic::launder_invariant_group ||
+ IntrinsicID == Intrinsic::strip_invariant_group)
return Operands[0];
}
if (isa<ConstantPointerNull>(Operands[0]) &&
Operands[0]->getType()->getPointerAddressSpace() == 0) {
- // launder(null) == null iff in addrspace 0
- if (IntrinsicID == Intrinsic::launder_invariant_group)
+ // launder(null) == null == strip(null) iff in addrspace 0
+ if (IntrinsicID == Intrinsic::launder_invariant_group ||
+ IntrinsicID == Intrinsic::strip_invariant_group)
return Operands[0];
return nullptr;
}
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 12002de7928..16a3c7c6175 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -3404,8 +3404,9 @@ const Value *llvm::getArgumentAliasingToReturnedPointer(ImmutableCallSite CS) {
}
bool llvm::isIntrinsicReturningPointerAliasingArgumentWithoutCapturing(
- ImmutableCallSite CS) {
- return CS.getIntrinsicID() == Intrinsic::launder_invariant_group;
+ ImmutableCallSite CS) {
+ return CS.getIntrinsicID() == Intrinsic::launder_invariant_group ||
+ CS.getIntrinsicID() == Intrinsic::strip_invariant_group;
}
/// \p PN defines a loop-variant pointer to an object. Check if the
@@ -3454,13 +3455,15 @@ Value *llvm::GetUnderlyingObject(Value *V, const DataLayout &DL,
return V;
} else {
if (auto CS = CallSite(V)) {
- // Note: getArgumentAliasingToReturnedPointer keeps it in sync with
- // CaptureTracking, which is needed for correctness. This is because
- // some intrinsics like launder.invariant.group returns pointers that
- // are aliasing it's argument, which is known to CaptureTracking.
- // If AliasAnalysis does not use the same information, it could assume
- // that pointer returned from launder does not alias it's argument
- // because launder could not return it if the pointer was not captured.
+ // CaptureTracking can know about special capturing properties of some
+ // intrinsics like launder.invariant.group, that can't be expressed with
+ // the attributes, but have properties like returning aliasing pointer.
+ // Because some analysis may assume that nocaptured pointer is not
+ // returned from some special intrinsic (because function would have to
+ // be marked with returns attribute), it is crucial to use this function
+ // because it should be in sync with CaptureTracking. Not using it may
+ // cause weird miscompilations where 2 aliasing pointers are assumed to
+ // noalias.
if (auto *RP = getArgumentAliasingToReturnedPointer(CS)) {
V = RP;
continue;
diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp
index 743acc5af30..0418de0f658 100644
--- a/llvm/lib/CodeGen/CodeGenPrepare.cpp
+++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp
@@ -1702,6 +1702,7 @@ bool CodeGenPrepare::optimizeCallInst(CallInst *CI, bool &ModifiedDT) {
return true;
}
case Intrinsic::launder_invariant_group:
+ case Intrinsic::strip_invariant_group:
II->replaceAllUsesWith(II->getArgOperand(0));
II->eraseFromParent();
return true;
diff --git a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
index 173c8bdfeab..e4a9d557d38 100644
--- a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
@@ -1437,6 +1437,7 @@ bool FastISel::selectIntrinsicCall(const IntrinsicInst *II) {
return true;
}
case Intrinsic::launder_invariant_group:
+ case Intrinsic::strip_invariant_group:
case Intrinsic::expect: {
unsigned ResultReg = getRegForValue(II->getArgOperand(0));
if (!ResultReg)
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 74c50d2a246..e29cf2f4587 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -5768,6 +5768,7 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {
case Intrinsic::annotation:
case Intrinsic::ptr_annotation:
case Intrinsic::launder_invariant_group:
+ case Intrinsic::strip_invariant_group:
// Drop the intrinsic, but forward the value
setValue(&I, getValue(I.getOperand(0)));
return nullptr;
diff --git a/llvm/lib/IR/Value.cpp b/llvm/lib/IR/Value.cpp
index 69a84d72cac..295d6ecf0db 100644
--- a/llvm/lib/IR/Value.cpp
+++ b/llvm/lib/IR/Value.cpp
@@ -521,7 +521,8 @@ static const Value *stripPointerCastsAndOffsets(const Value *V) {
// but it can't be marked with returned attribute, that's why it needs
// special case.
if (StripKind == PSK_ZeroIndicesAndAliasesAndInvariantGroups &&
- CS.getIntrinsicID() == Intrinsic::launder_invariant_group) {
+ (CS.getIntrinsicID() == Intrinsic::launder_invariant_group ||
+ CS.getIntrinsicID() == Intrinsic::strip_invariant_group)) {
V = CS.getArgOperand(0);
continue;
}
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp b/llvm/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp
index ffe34831623..688e1ba8349 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp
@@ -457,6 +457,7 @@ static bool isCallPromotable(CallInst *CI) {
case Intrinsic::invariant_start:
case Intrinsic::invariant_end:
case Intrinsic::launder_invariant_group:
+ case Intrinsic::strip_invariant_group:
case Intrinsic::objectsize:
return true;
default:
@@ -882,6 +883,7 @@ bool AMDGPUPromoteAlloca::handleAlloca(AllocaInst &I, bool SufficientLDS) {
case Intrinsic::invariant_start:
case Intrinsic::invariant_end:
case Intrinsic::launder_invariant_group:
+ case Intrinsic::strip_invariant_group:
Intr->eraseFromParent();
// FIXME: I think the invariant marker should still theoretically apply,
// but the intrinsics need to be changed to accept pointers with any
OpenPOWER on IntegriCloud