Skip to content

Commit 47ca5e8

Browse files
[Instrumentor] Add instruction flags to NumericIO (llvm#200709)
1 parent f5c08d6 commit 47ca5e8

7 files changed

Lines changed: 363 additions & 293 deletions

File tree

llvm/include/llvm/Transforms/IPO/Instrumentor.h

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1088,14 +1088,15 @@ struct CastIO final
10881088
/// Instrumentation opportunity for numeric operations. This includes Add, FAdd,
10891089
/// Sub, FSub, Mul, FMul, UDiv, FDiv, SDiv, URem, SRem, FRem, Shl, LShr, AShr,
10901090
/// And, Or, Xor, and FNeg.
1091-
struct NumericIO : public InstructionIO<
1092-
Instruction::Add, Instruction::FAdd, Instruction::Sub,
1093-
Instruction::FSub, Instruction::Mul, Instruction::FMul,
1094-
Instruction::UDiv, Instruction::FDiv, Instruction::SDiv,
1095-
Instruction::URem, Instruction::SRem, Instruction::FRem,
1096-
Instruction::Shl, Instruction::LShr, Instruction::AShr,
1097-
Instruction::And, Instruction::Or, Instruction::Xor,
1098-
Instruction::FNeg> {
1091+
struct NumericIO final
1092+
: public InstructionIO<
1093+
Instruction::Add, Instruction::FAdd, Instruction::Sub,
1094+
Instruction::FSub, Instruction::Mul, Instruction::FMul,
1095+
Instruction::UDiv, Instruction::FDiv, Instruction::SDiv,
1096+
Instruction::URem, Instruction::SRem, Instruction::FRem,
1097+
Instruction::Shl, Instruction::LShr, Instruction::AShr,
1098+
Instruction::And, Instruction::Or, Instruction::Xor,
1099+
Instruction::FNeg> {
10991100
NumericIO(InstrumentationLocation::KindTy Kind) : InstructionIO(Kind) {}
11001101

11011102
enum ConfigKind {
@@ -1106,6 +1107,7 @@ struct NumericIO : public InstructionIO<
11061107
ReplaceResult,
11071108
PassLeft,
11081109
PassRight,
1110+
PassFlags,
11091111
PassId,
11101112
NumConfig,
11111113
};
@@ -1122,6 +1124,8 @@ struct NumericIO : public InstructionIO<
11221124
InstrumentorIRBuilderTy &IIRB);
11231125
static Value *getRight(Value &V, Type &Ty, InstrumentationConfig &IConf,
11241126
InstrumentorIRBuilderTy &IIRB);
1127+
static Value *getFlags(Value &V, Type &Ty, InstrumentationConfig &IConf,
1128+
InstrumentorIRBuilderTy &IIRB);
11251129

11261130
static void populate(InstrumentationConfig &IConf,
11271131
InstrumentorIRBuilderTy &IIRB) {

llvm/lib/Transforms/IPO/Instrumentor.cpp

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1705,6 +1705,61 @@ Value *NumericIO::getRight(Value &V, Type &Ty, InstrumentationConfig &IConf,
17051705
return PoisonValue::get(&Ty);
17061706
}
17071707

1708+
// NumericIO flag bitmask values.
1709+
enum NumericFlags : uint64_t {
1710+
NUMERIC_FLAG_NONE = 0,
1711+
NUMERIC_FLAG_NO_SIGNED_WRAP = 1 << 0,
1712+
NUMERIC_FLAG_NO_UNSIGNED_WRAP = 1 << 1,
1713+
NUMERIC_FLAG_HAS_NO_NANS = 1 << 2,
1714+
NUMERIC_FLAG_HAS_NO_INFS = 1 << 3,
1715+
NUMERIC_FLAG_HAS_NO_SIGNED_ZEROS = 1 << 4,
1716+
NUMERIC_FLAG_IS_DISJOINT = 1 << 5,
1717+
NUMERIC_FLAG_IS_EXACT = 1 << 6,
1718+
};
1719+
1720+
Value *NumericIO::getFlags(Value &V, Type &Ty, InstrumentationConfig &IConf,
1721+
InstrumentorIRBuilderTy &IIRB) {
1722+
auto &I = cast<Instruction>(V);
1723+
uint64_t Flag = NUMERIC_FLAG_NONE;
1724+
1725+
switch (I.getOpcode()) {
1726+
case Instruction::Add:
1727+
case Instruction::Sub:
1728+
case Instruction::Mul:
1729+
case Instruction::Shl:
1730+
if (I.hasNoSignedWrap())
1731+
Flag |= NUMERIC_FLAG_NO_SIGNED_WRAP;
1732+
if (I.hasNoUnsignedWrap())
1733+
Flag |= NUMERIC_FLAG_NO_UNSIGNED_WRAP;
1734+
break;
1735+
case Instruction::FAdd:
1736+
case Instruction::FSub:
1737+
case Instruction::FMul:
1738+
case Instruction::FDiv:
1739+
case Instruction::FNeg:
1740+
if (I.hasNoNaNs())
1741+
Flag |= NUMERIC_FLAG_HAS_NO_NANS;
1742+
if (I.hasNoInfs())
1743+
Flag |= NUMERIC_FLAG_HAS_NO_INFS;
1744+
if (I.hasNoSignedZeros())
1745+
Flag |= NUMERIC_FLAG_HAS_NO_SIGNED_ZEROS;
1746+
break;
1747+
case Instruction::AShr:
1748+
case Instruction::LShr:
1749+
case Instruction::SDiv:
1750+
case Instruction::UDiv:
1751+
if (I.isExact())
1752+
Flag |= NUMERIC_FLAG_IS_EXACT;
1753+
break;
1754+
}
1755+
1756+
if (auto *DI = dyn_cast<PossiblyDisjointInst>(&V))
1757+
if (DI->isDisjoint())
1758+
Flag |= NUMERIC_FLAG_IS_DISJOINT;
1759+
1760+
return getCI(&Ty, Flag);
1761+
}
1762+
17081763
void NumericIO::init(InstrumentationConfig &IConf,
17091764
InstrumentorIRBuilderTy &IIRB, ConfigTy *UserConfig) {
17101765
if (UserConfig)
@@ -1714,7 +1769,7 @@ void NumericIO::init(InstrumentationConfig &IConf,
17141769
IRTArg::POTENTIALLY_INDIRECT |
17151770
(Config.has(PassSize) ? IRTArg::INDIRECT_HAS_SIZE : IRTArg::NONE);
17161771
if (Config.has(PassTypeId))
1717-
IRTArgs.push_back(IRTArg(IIRB.Int64Ty, "type_id",
1772+
IRTArgs.push_back(IRTArg(IIRB.Int32Ty, "type_id",
17181773
"The operation's type id.", IRTArg::NONE,
17191774
getTypeId));
17201775
if (Config.has(PassSize))
@@ -1737,6 +1792,11 @@ void NumericIO::init(InstrumentationConfig &IConf,
17371792
IRTArg(IIRB.Int64Ty, "result", "Result of the operation.",
17381793
IRTArg::REPLACABLE | ValArgOpts, getValue,
17391794
Config.has(ReplaceResult) ? replaceValue : nullptr));
1795+
if (Config.has(PassFlags))
1796+
IRTArgs.push_back(
1797+
IRTArg(IIRB.Int64Ty, "flags",
1798+
"A bitmask value signaling which instruction flags are present.",
1799+
IRTArg::NONE, getFlags));
17401800
addCommonArgs(IConf, IIRB.Ctx, Config.has(PassId));
17411801
IConf.addChoice(*this, IIRB.Ctx);
17421802
}

llvm/test/Instrumentation/Instrumentor/default_config.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,8 @@
238238
"left.description": "The operation's left operand.",
239239
"right": true,
240240
"right.description": "The operation's right operand. This value is poison for unary operations.",
241+
"flags": true,
242+
"flags.description": "A bitmask value signaling which instruction flags are present.",
241243
"id": true,
242244
"id.description": "A unique ID associated with the given instrumentor call"
243245
}
@@ -351,6 +353,8 @@
351353
"result": true,
352354
"result.replace": true,
353355
"result.description": "Result of the operation.",
356+
"flags": true,
357+
"flags.description": "A bitmask value signaling which instruction flags are present.",
354358
"id": true,
355359
"id.description": "A unique ID associated with the given instrumentor call"
356360
}

llvm/test/Instrumentation/Instrumentor/module_and_globals.ll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,17 +56,17 @@ entry:
5656
; CHECK-NEXT: [[TMP28:%.*]] = trunc i64 [[TMP27]] to i32
5757
; CHECK-NEXT: [[TMP29:%.*]] = zext i32 [[TMP14]] to i64
5858
; CHECK-NEXT: [[TMP30:%.*]] = zext i32 [[TMP25]] to i64
59-
; CHECK-NEXT: call void @__instrumentor_pre_numeric(i64 12, i32 4, i32 14, i64 [[TMP29]], i64 [[TMP30]], i32 12) #[[ATTR0]]
59+
; CHECK-NEXT: call void @__instrumentor_pre_numeric(i32 12, i32 4, i32 14, i64 [[TMP29]], i64 [[TMP30]], i64 1, i32 12) #[[ATTR0]]
6060
; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP14]], [[TMP25]]
6161
; CHECK-NEXT: [[TMP17:%.*]] = zext i32 [[ADD]] to i64
62-
; CHECK-NEXT: [[TMP18:%.*]] = call i64 @__instrumentor_post_numeric(i64 12, i32 4, i32 14, i64 [[TMP29]], i64 [[TMP30]], i64 [[TMP17]], i32 -12) #[[ATTR0]]
62+
; CHECK-NEXT: [[TMP18:%.*]] = call i64 @__instrumentor_post_numeric(i32 12, i32 4, i32 14, i64 [[TMP29]], i64 [[TMP30]], i64 [[TMP17]], i64 1, i32 -12) #[[ATTR0]]
6363
; CHECK-NEXT: [[TMP19:%.*]] = trunc i64 [[TMP18]] to i32
6464
; CHECK-NEXT: [[TMP20:%.*]] = zext i32 [[TMP19]] to i64
6565
; CHECK-NEXT: [[TMP24:%.*]] = zext i32 [[TMP28]] to i64
66-
; CHECK-NEXT: call void @__instrumentor_pre_numeric(i64 12, i32 4, i32 14, i64 [[TMP20]], i64 [[TMP24]], i32 13) #[[ATTR0]]
66+
; CHECK-NEXT: call void @__instrumentor_pre_numeric(i32 12, i32 4, i32 14, i64 [[TMP20]], i64 [[TMP24]], i64 1, i32 13) #[[ATTR0]]
6767
; CHECK-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP19]], [[TMP28]]
6868
; CHECK-NEXT: [[TMP22:%.*]] = zext i32 [[ADD3]] to i64
69-
; CHECK-NEXT: [[TMP23:%.*]] = call i64 @__instrumentor_post_numeric(i64 12, i32 4, i32 14, i64 [[TMP20]], i64 [[TMP24]], i64 [[TMP22]], i32 -13) #[[ATTR0]]
69+
; CHECK-NEXT: [[TMP23:%.*]] = call i64 @__instrumentor_post_numeric(i32 12, i32 4, i32 14, i64 [[TMP20]], i64 [[TMP24]], i64 [[TMP22]], i64 1, i32 -13) #[[ATTR0]]
7070
; CHECK-NEXT: [[ADD2:%.*]] = trunc i64 [[TMP23]] to i32
7171
; CHECK-NEXT: call void @__instrumentor_post_function(ptr @foo, ptr @__instrumentor_.str.5, i32 0, ptr null, i8 0, i32 -15) #[[ATTR0]]
7272
; CHECK-NEXT: ret i32 [[ADD2]]

0 commit comments

Comments
 (0)