Exemplo n.º 1
0
TEST(InstTest, Fold) {
  InstContext IC;

  Inst *I1 = IC.getConst(llvm::APInt(64, 0));
  Inst *I2 = IC.getConst(llvm::APInt(64, 0));

  ASSERT_EQ(I2, I1);

  Inst *I3 = IC.getConst(llvm::APInt(64, 1));
  Inst *I4 = IC.getConst(llvm::APInt(32, 0));

  ASSERT_NE(I3, I1);
  ASSERT_NE(I4, I1);
  ASSERT_NE(I4, I3);

  Inst *I1AI3 = IC.getInst(Inst::Add, 64, {I1, I3});
  Inst *I3AI1 = IC.getInst(Inst::Add, 64, {I3, I1});

  ASSERT_EQ(I1AI3, I3AI1);

  Inst *I1SI3 = IC.getInst(Inst::Sub, 64, {I1, I3});
  Inst *I3SI1 = IC.getInst(Inst::Sub, 64, {I3, I1});

  ASSERT_NE(I1SI3, I3SI1);
}
Exemplo n.º 2
0
TEST(InterpreterTests, KnownBits) {
  InstContext IC;

  Inst *I1 = IC.getConst(llvm::APInt(64, 5));

  souper::ValueCache C;
  auto KB = souper::findKnownBits(I1, C);
  ASSERT_EQ(KB.One, 5);
  ASSERT_EQ(KB.Zero, ~5);

  Inst *I2 = IC.getInst(Inst::Var, 64, {});
  Inst *I3 = IC.getConst(llvm::APInt(64, 0xFF));
  Inst *I4 = IC.getInst(Inst::And, 64, {I2, I3});
  KB = souper::findKnownBits(I4, C, /*PartialEval=*/false);
  ASSERT_EQ(KB.One, 0);
  ASSERT_EQ(KB.Zero, ~0xFF);

  Inst *I5 = IC.getInst(Inst::Or, 64, {I2, I1});
  KB = souper::findKnownBits(I5, C, /*PartialEval=*/false);
  ASSERT_EQ(KB.One, 5);
  ASSERT_EQ(KB.Zero, 0);

  Inst *I6 = IC.getInst(Inst::Shl, 64, {I2, I1});
  KB = souper::findKnownBits(I6, C, /*PartialEval=*/false);
  ASSERT_EQ(KB.One, 0);
  ASSERT_EQ(KB.Zero, 31);
}
Exemplo n.º 3
0
TEST(InterpreterTests, KnownBits) {
  InstContext IC;

  Inst *I1 = IC.getConst(llvm::APInt(64, 5));

  souper::ConcreteInterpreter CI;
  auto KB = souper::KnownBitsAnalysis().findKnownBits(I1, CI);
  ASSERT_EQ(KB.One, 5);
  ASSERT_EQ(KB.Zero, ~5);

  Inst *I2 = IC.getInst(Inst::ReservedConst, 64, {});
  Inst *I3 = IC.getConst(llvm::APInt(64, 0xFF));
  Inst *I4 = IC.getInst(Inst::And, 64, {I2, I3});
  KB = souper::KnownBitsAnalysis().findKnownBits(I4, CI);
  ASSERT_EQ(KB.One, 0);
  ASSERT_EQ(KB.Zero, ~0xFF);

  Inst *I5 = IC.getInst(Inst::Or, 64, {I2, I1});
  KB = souper::KnownBitsAnalysis().findKnownBits(I5, CI);
  ASSERT_EQ(KB.One, 5);
  ASSERT_EQ(KB.Zero, 0);

  Inst *I6 = IC.getInst(Inst::Shl, 64, {I2, I1});
  KB = souper::KnownBitsAnalysis().findKnownBits(I6, CI);
  ASSERT_EQ(KB.One, 0);
  ASSERT_EQ(KB.Zero, 31);
}
Exemplo n.º 4
0
TEST(InstTest, Print) {
  InstContext IC;

  std::string Str;
  llvm::raw_string_ostream SS(Str);

  Inst *I1 = IC.getConst(llvm::APInt(64, 1));
  Inst *I2 = IC.getConst(llvm::APInt(64, 2));
  Inst *I3 = IC.getConst(llvm::APInt(64, 3));

  Inst *I1AI2 = IC.getInst(Inst::Add, 64, {I1, I2});
  Inst *I1AI2MI3 = IC.getInst(Inst::Mul, 64, {I1AI2, I3});
  ReplacementContext Context;

  EXPECT_EQ("%1", Context.printInst(I1AI2MI3, SS, /*printNames=*/false));
  EXPECT_EQ("%0:i64 = add 1:i64, 2:i64\n"
            "%1:i64 = mul 3:i64, %0\n", SS.str());
}
Exemplo n.º 5
0
// Checks that ConcreteInterpreter only caches during construction, otherwise not
TEST(InterpreterTests, ConcreteCache) {
  InstContext IC;

  Inst *I1 = IC.getConst(llvm::APInt(8, 0xFF));
  Inst *I2 = IC.getInst(Inst::Var, 8, {});
  Inst *I3 = IC.getInst(Inst::Or, 8, {I1, I2});

  ValueCache InputValues = {{I2, APInt(8, 0x00)}};
  souper::ConcreteInterpreter CI(InputValues);
  auto Val = CI.evaluateInst(I3);
  ASSERT_TRUE(Val.hasValue());

  ASSERT_EQ(Val.getValue(), APInt(8, 0xFF));

  // We want to ensure that evaluateInst call is *really* being evaluated
  // instead of just returning the result from the cache; so let's change what
  // I1 was pointing to, to see that.
  *I1 = *IC.getConst(llvm::APInt(8, 0x0F));
  Val = CI.evaluateInst(I3);
  ASSERT_TRUE(Val.hasValue());

  // We would have got 0xFF if evaluateInst had returned result from cache.
  ASSERT_EQ(Val.getValue(), APInt(8, 0x0F, true));
}
Exemplo n.º 6
0
TEST(InterpreterTests, ConstantRange) {
  InstContext IC;

  Inst *I1 = IC.getConst(llvm::APInt(64, 5));

  souper::ValueCache C;
  auto CR = souper::findConstantRange(I1, C, /*PartialEval=*/false);
  ASSERT_EQ(CR.getLower(), 5);
  ASSERT_EQ(CR.getUpper(), 6);

  Inst *I2 = IC.getInst(Inst::Var, 64, {});
  Inst *I3 = IC.getConst(llvm::APInt(64, 0xFF));
  Inst *I4 = IC.getInst(Inst::And, 64, {I2, I3});
  CR = souper::findConstantRange(I4, C, /*PartialEval=*/false);
  ASSERT_EQ(CR.getLower(), 0);
  ASSERT_EQ(CR.getUpper(), 0xFF + 1);

  Inst *I5 = IC.getInst(Inst::Add, 64, {I4, I1});
  CR = souper::findConstantRange(I5, C, /*PartialEval=*/false);
  ASSERT_EQ(CR.getLower(), 5);
  ASSERT_EQ(CR.getUpper(), 0xFF + 5 + 1);
}
Exemplo n.º 7
0
TEST(InterpreterTests, ConstantRange) {
  InstContext IC;

  Inst *I1 = IC.getConst(llvm::APInt(64, 5));

  souper::ConcreteInterpreter CI;
  auto CR = souper::ConstantRangeAnalysis().findConstantRange(I1, CI);
  ASSERT_EQ(CR.getLower(), 5);
  ASSERT_EQ(CR.getUpper(), 6);

  Inst *I2 = IC.getInst(Inst::ReservedConst, 64, {});
  Inst *I3 = IC.getConst(llvm::APInt(64, 0xFF));
  Inst *I4 = IC.getInst(Inst::And, 64, {I2, I3});
  CR = souper::ConstantRangeAnalysis().findConstantRange(I4, CI);
  ASSERT_EQ(CR.getLower(), 0);
  ASSERT_EQ(CR.getUpper(), 0xFF + 1);

  Inst *I5 = IC.getInst(Inst::Add, 64, {I4, I1});
  CR = souper::ConstantRangeAnalysis().findConstantRange(I5, CI);
  ASSERT_EQ(CR.getLower(), 5);
  ASSERT_EQ(CR.getUpper(), 0xFF + 5 + 1);
}