Skip to content

Commit 36fe181

Browse files
committed
Always produce canonical form when combining metadata
1 parent 914c502 commit 36fe181

File tree

7 files changed

+95
-30
lines changed

7 files changed

+95
-30
lines changed

llvm/include/llvm/IR/Instructions.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -393,9 +393,6 @@ class StoreInst : public Instruction {
393393
return getPointerOperandType()->getPointerAddressSpace();
394394
}
395395

396-
/// Get capturing behavior of the value operand, based on !captures metadata.
397-
CaptureComponents getCaptureComponents() const;
398-
399396
// Methods for support type inquiry through isa, cast, and dyn_cast:
400397
static bool classof(const Instruction *I) {
401398
return I->getOpcode() == Instruction::Store;

llvm/include/llvm/IR/Metadata.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141

4242
namespace llvm {
4343

44+
enum class CaptureComponents : uint8_t;
4445
class Module;
4546
class ModuleSlotTracker;
4647
class raw_ostream;
@@ -1480,6 +1481,13 @@ class MDNode : public Metadata {
14801481
LLVM_ABI static MDNode *getMergedCallsiteMetadata(MDNode *A, MDNode *B);
14811482
LLVM_ABI static MDNode *getMergedCalleeTypeMetadata(const MDNode *A,
14821483
const MDNode *B);
1484+
1485+
/// Convert !captures metadata to CaptureComponents. MD may be nullptr.
1486+
LLVM_ABI static CaptureComponents toCaptureComponents(const MDNode *MD);
1487+
/// Convert CaptureComponents to !captures metadata. The return value may be
1488+
/// nullptr.
1489+
LLVM_ABI static MDNode *fromCaptureComponents(LLVMContext &Ctx,
1490+
CaptureComponents CC);
14831491
};
14841492

14851493
/// Tuple of metadata.

llvm/lib/Analysis/CaptureTracking.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,8 @@ UseCaptureInfo llvm::DetermineUseCaptureKind(const Use &U, const Value *Base) {
321321
case Instruction::Store:
322322
// Stored the pointer - conservatively assume it may be captured.
323323
if (U.getOperandNo() == 0)
324-
return cast<StoreInst>(I)->getCaptureComponents();
324+
return MDNode::toCaptureComponents(
325+
I->getMetadata(LLVMContext::MD_captures));
325326

326327
// Volatile stores make the address observable.
327328
if (cast<StoreInst>(I)->isVolatile())

llvm/lib/IR/Instructions.cpp

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1390,24 +1390,6 @@ StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile, Align Align,
13901390
AssertOK();
13911391
}
13921392

1393-
CaptureComponents StoreInst::getCaptureComponents() const {
1394-
const MDNode *MD = getMetadata(LLVMContext::MD_captures);
1395-
if (!MD)
1396-
return CaptureComponents::All;
1397-
1398-
CaptureComponents CC = CaptureComponents::None;
1399-
for (Metadata *Op : MD->operands()) {
1400-
CaptureComponents Component =
1401-
StringSwitch<CaptureComponents>(cast<MDString>(Op)->getString())
1402-
.Case("address", CaptureComponents::Address)
1403-
.Case("address_is_null", CaptureComponents::AddressIsNull)
1404-
.Case("provenance", CaptureComponents::Provenance)
1405-
.Case("read_provenance", CaptureComponents::ReadProvenance);
1406-
CC |= Component;
1407-
}
1408-
return CC;
1409-
}
1410-
14111393
//===----------------------------------------------------------------------===//
14121394
// AtomicCmpXchgInst Implementation
14131395
//===----------------------------------------------------------------------===//

llvm/lib/IR/Metadata.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
#include "llvm/Support/Casting.h"
4949
#include "llvm/Support/ErrorHandling.h"
5050
#include "llvm/Support/MathExtras.h"
51+
#include "llvm/Support/ModRef.h"
5152
#include <cassert>
5253
#include <cstddef>
5354
#include <cstdint>
@@ -1435,6 +1436,40 @@ MDNode *MDNode::getMostGenericAlignmentOrDereferenceable(MDNode *A, MDNode *B) {
14351436
return B;
14361437
}
14371438

1439+
CaptureComponents MDNode::toCaptureComponents(const MDNode *MD) {
1440+
if (!MD)
1441+
return CaptureComponents::All;
1442+
1443+
CaptureComponents CC = CaptureComponents::None;
1444+
for (Metadata *Op : MD->operands()) {
1445+
CaptureComponents Component =
1446+
StringSwitch<CaptureComponents>(cast<MDString>(Op)->getString())
1447+
.Case("address", CaptureComponents::Address)
1448+
.Case("address_is_null", CaptureComponents::AddressIsNull)
1449+
.Case("provenance", CaptureComponents::Provenance)
1450+
.Case("read_provenance", CaptureComponents::ReadProvenance);
1451+
CC |= Component;
1452+
}
1453+
return CC;
1454+
}
1455+
1456+
MDNode *MDNode::fromCaptureComponents(LLVMContext &Ctx, CaptureComponents CC) {
1457+
assert(!capturesNothing(CC) && "Can't encode captures(none)");
1458+
if (capturesAll(CC))
1459+
return nullptr;
1460+
1461+
SmallVector<Metadata *> Components;
1462+
if (capturesAddressIsNullOnly(CC))
1463+
Components.push_back(MDString::get(Ctx, "address_is_null"));
1464+
else if (capturesAddress(CC))
1465+
Components.push_back(MDString::get(Ctx, "address"));
1466+
if (capturesReadProvenanceOnly(CC))
1467+
Components.push_back(MDString::get(Ctx, "read_provenance"));
1468+
else if (capturesFullProvenance(CC))
1469+
Components.push_back(MDString::get(Ctx, "provenance"));
1470+
return MDNode::get(Ctx, Components);
1471+
}
1472+
14381473
//===----------------------------------------------------------------------===//
14391474
// NamedMDNode implementation.
14401475
//

llvm/lib/Transforms/Utils/Local.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3026,7 +3026,10 @@ static void combineMetadata(Instruction *K, const Instruction *J,
30263026
K->setMetadata(Kind, JMD);
30273027
break;
30283028
case LLVMContext::MD_captures:
3029-
K->setMetadata(Kind, JMD ? MDNode::concatenate(JMD, KMD) : nullptr);
3029+
K->setMetadata(
3030+
Kind, MDNode::fromCaptureComponents(
3031+
K->getContext(), MDNode::toCaptureComponents(JMD) |
3032+
MDNode::toCaptureComponents(KMD)));
30303033
break;
30313034
}
30323035
}

llvm/test/Transforms/SimplifyCFG/hoist-with-metadata.ll

Lines changed: 46 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -469,7 +469,7 @@ out:
469469
define void @hoist_captures_overlap(i1 %c, ptr %x, ptr %y) {
470470
; CHECK-LABEL: @hoist_captures_overlap(
471471
; CHECK-NEXT: if:
472-
; CHECK-NEXT: store ptr [[X:%.*]], ptr [[Y:%.*]], align 8, !captures [[META11:![0-9]+]]
472+
; CHECK-NEXT: store ptr [[X:%.*]], ptr [[Y:%.*]], align 8, !captures [[META10]]
473473
; CHECK-NEXT: ret void
474474
;
475475
if:
@@ -487,12 +487,52 @@ out:
487487
ret void
488488
}
489489

490-
; We could also omit the attribute in this case, as it provides no additional
491-
; information.
490+
define void @hoist_captures_subsume1(i1 %c, ptr %x, ptr %y) {
491+
; CHECK-LABEL: @hoist_captures_subsume1(
492+
; CHECK-NEXT: if:
493+
; CHECK-NEXT: store ptr [[X:%.*]], ptr [[Y:%.*]], align 8, !captures [[META9]]
494+
; CHECK-NEXT: ret void
495+
;
496+
if:
497+
br i1 %c, label %then, label %else
498+
499+
then:
500+
store ptr %x, ptr %y, !captures !{!"address_is_null"}
501+
br label %out
502+
503+
else:
504+
store ptr %x, ptr %y, !captures !{!"address"}
505+
br label %out
506+
507+
out:
508+
ret void
509+
}
510+
511+
define void @hoist_captures_subsume2(i1 %c, ptr %x, ptr %y) {
512+
; CHECK-LABEL: @hoist_captures_subsume2(
513+
; CHECK-NEXT: if:
514+
; CHECK-NEXT: store ptr [[X:%.*]], ptr [[Y:%.*]], align 8, !captures [[META11:![0-9]+]]
515+
; CHECK-NEXT: ret void
516+
;
517+
if:
518+
br i1 %c, label %then, label %else
519+
520+
then:
521+
store ptr %x, ptr %y, !captures !{!"provenance"}
522+
br label %out
523+
524+
else:
525+
store ptr %x, ptr %y, !captures !{!"read_provenance"}
526+
br label %out
527+
528+
out:
529+
ret void
530+
}
531+
492532
define void @hoist_captures_full_set(i1 %c, ptr %x, ptr %y) {
493533
; CHECK-LABEL: @hoist_captures_full_set(
494534
; CHECK-NEXT: if:
495-
; CHECK-NEXT: store ptr [[X:%.*]], ptr [[Y:%.*]], align 8, !captures [[META12:![0-9]+]]
535+
; CHECK-NEXT: store ptr [[X:%.*]], ptr [[Y:%.*]], align 8
496536
; CHECK-NEXT: ret void
497537
;
498538
if:
@@ -574,7 +614,6 @@ out:
574614
; CHECK: [[META7]] = !{i32 5, i32 6}
575615
; CHECK: [[META8]] = !{i32 4, i32 5}
576616
; CHECK: [[META9]] = !{!"address"}
577-
; CHECK: [[META10]] = !{!"read_provenance", !"address"}
578-
; CHECK: [[META11]] = !{!"address", !"read_provenance"}
579-
; CHECK: [[META12]] = !{!"provenance", !"address"}
617+
; CHECK: [[META10]] = !{!"address", !"read_provenance"}
618+
; CHECK: [[META11]] = !{!"provenance"}
580619
;.

0 commit comments

Comments
 (0)