Skip to content

Commit af4a82e

Browse files
authored
[SandboxIR] Implement PossiblyNonNegInst (#106149)
This patch implements sandboxir::PossiblyNonNegInst mirroring llvm::PossiblyNonNegInst.
1 parent 31204b4 commit af4a82e

File tree

4 files changed

+98
-0
lines changed

4 files changed

+98
-0
lines changed

llvm/include/llvm/SandboxIR/SandboxIR.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ class CatchReturnInst;
137137
class CleanupReturnInst;
138138
class GetElementPtrInst;
139139
class CastInst;
140+
class PossiblyNonNegInst;
140141
class PtrToIntInst;
141142
class BitCastInst;
142143
class AllocaInst;
@@ -2762,6 +2763,28 @@ class CastInst : public UnaryInstruction {
27622763
Type *getDestTy() const { return cast<llvm::CastInst>(Val)->getDestTy(); }
27632764
};
27642765

2766+
/// Instruction that can have a nneg flag (zext/uitofp).
2767+
class PossiblyNonNegInst : public CastInst {
2768+
public:
2769+
bool hasNonNeg() const {
2770+
return cast<llvm::PossiblyNonNegInst>(Val)->hasNonNeg();
2771+
}
2772+
void setNonNeg(bool B);
2773+
/// For isa/dyn_cast.
2774+
static bool classof(const Value *From) {
2775+
if (auto *I = dyn_cast<Instruction>(From)) {
2776+
switch (I->getOpcode()) {
2777+
case Opcode::ZExt:
2778+
case Opcode::UIToFP:
2779+
return true;
2780+
default:
2781+
return false;
2782+
}
2783+
}
2784+
return false;
2785+
}
2786+
};
2787+
27652788
// Helper class to simplify stamping out CastInst subclasses.
27662789
template <Instruction::Opcode Op> class CastInstImpl : public CastInst {
27672790
public:

llvm/lib/SandboxIR/SandboxIR.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1991,6 +1991,13 @@ bool CastInst::classof(const Value *From) {
19911991
return From->getSubclassID() == ClassID::Cast;
19921992
}
19931993

1994+
void PossiblyNonNegInst::setNonNeg(bool B) {
1995+
Ctx.getTracker()
1996+
.emplaceIfTracking<GenericSetter<&PossiblyNonNegInst::hasNonNeg,
1997+
&PossiblyNonNegInst::setNonNeg>>(this);
1998+
cast<llvm::PossiblyNonNegInst>(Val)->setNonNeg(B);
1999+
}
2000+
19942001
Value *InsertElementInst::create(Value *Vec, Value *NewElt, Value *Idx,
19952002
Instruction *InsertBefore, Context &Ctx,
19962003
const Twine &Name) {

llvm/unittests/SandboxIR/SandboxIRTest.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3682,6 +3682,48 @@ define void @foo(i32 %arg, float %farg, double %darg, ptr %ptr) {
36823682
}
36833683
}
36843684

3685+
TEST_F(SandboxIRTest, PossiblyNonNegInst) {
3686+
parseIR(C, R"IR(
3687+
define void @foo(i32 %arg, float %farg, double %darg, ptr %ptr) {
3688+
%zext = zext i32 %arg to i64
3689+
%uitofp = uitofp i32 %arg to float
3690+
3691+
%sext = sext i32 %arg to i64
3692+
%fptoui = fptoui float %farg to i32
3693+
%fptosi = fptosi float %farg to i32
3694+
%fpext = fpext float %farg to double
3695+
%ptrtoint = ptrtoint ptr %ptr to i32
3696+
%inttoptr = inttoptr i32 %arg to ptr
3697+
%sitofp = sitofp i32 %arg to float
3698+
%trunc = trunc i32 %arg to i16
3699+
%fptrunc = fptrunc double %darg to float
3700+
%bitcast = bitcast i32 %arg to float
3701+
%addrspacecast = addrspacecast ptr %ptr to ptr addrspace(1)
3702+
ret void
3703+
}
3704+
)IR");
3705+
Function &LLVMF = *M->getFunction("foo");
3706+
sandboxir::Context Ctx(C);
3707+
sandboxir::Function *F = Ctx.createFunction(&LLVMF);
3708+
auto *BB = &*F->begin();
3709+
auto It = BB->begin();
3710+
auto *PNNI0 = cast<sandboxir::PossiblyNonNegInst>(&*It++);
3711+
auto *PNNI1 = cast<sandboxir::PossiblyNonNegInst>(&*It++);
3712+
for (auto ItE = BB->end(); It != ItE; ++It)
3713+
EXPECT_FALSE(isa<sandboxir::PossiblyNonNegInst>(&*It++));
3714+
3715+
for (auto *PNNI : {PNNI0, PNNI1}) {
3716+
// Check setNonNeg(), hasNonNeg().
3717+
auto OrigNonNeg = PNNI->hasNonNeg();
3718+
auto NewNonNeg = true;
3719+
EXPECT_NE(NewNonNeg, OrigNonNeg);
3720+
PNNI->setNonNeg(NewNonNeg);
3721+
EXPECT_EQ(PNNI->hasNonNeg(), NewNonNeg);
3722+
PNNI->setNonNeg(OrigNonNeg);
3723+
EXPECT_EQ(PNNI->hasNonNeg(), OrigNonNeg);
3724+
}
3725+
}
3726+
36853727
/// CastInst's subclasses are very similar so we can use a common test function
36863728
/// for them.
36873729
template <typename SubclassT, sandboxir::Instruction::Opcode OpcodeT>

llvm/unittests/SandboxIR/TrackerTest.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1014,6 +1014,32 @@ define void @foo(i8 %arg0, i8 %arg1) {
10141014
EXPECT_EQ(PDI->isDisjoint(), OrigIsDisjoint);
10151015
}
10161016

1017+
TEST_F(TrackerTest, PossiblyNonNegInstSetters) {
1018+
parseIR(C, R"IR(
1019+
define void @foo(i32 %arg) {
1020+
%zext = zext i32 %arg to i64
1021+
ret void
1022+
}
1023+
)IR");
1024+
Function &LLVMF = *M->getFunction("foo");
1025+
sandboxir::Context Ctx(C);
1026+
1027+
auto &F = *Ctx.createFunction(&LLVMF);
1028+
auto *BB = &*F.begin();
1029+
auto It = BB->begin();
1030+
auto *PNNI = cast<sandboxir::PossiblyNonNegInst>(&*It++);
1031+
1032+
// Check setNonNeg().
1033+
auto OrigNonNeg = PNNI->hasNonNeg();
1034+
auto NewNonNeg = true;
1035+
EXPECT_NE(NewNonNeg, OrigNonNeg);
1036+
Ctx.save();
1037+
PNNI->setNonNeg(NewNonNeg);
1038+
EXPECT_EQ(PNNI->hasNonNeg(), NewNonNeg);
1039+
Ctx.revert();
1040+
EXPECT_EQ(PNNI->hasNonNeg(), OrigNonNeg);
1041+
}
1042+
10171043
TEST_F(TrackerTest, AtomicRMWSetters) {
10181044
parseIR(C, R"IR(
10191045
define void @foo(ptr %ptr, i8 %arg) {

0 commit comments

Comments
 (0)