1*df49d1bbSPeter Collingbourne //===- WholeProgramDevirt.cpp - Unit tests for whole-program devirt -------===// 2*df49d1bbSPeter Collingbourne // 3*df49d1bbSPeter Collingbourne // The LLVM Compiler Infrastructure 4*df49d1bbSPeter Collingbourne // 5*df49d1bbSPeter Collingbourne // This file is distributed under the University of Illinois Open Source 6*df49d1bbSPeter Collingbourne // License. See LICENSE.TXT for details. 7*df49d1bbSPeter Collingbourne // 8*df49d1bbSPeter Collingbourne //===----------------------------------------------------------------------===// 9*df49d1bbSPeter Collingbourne 10*df49d1bbSPeter Collingbourne #include "llvm/Transforms/IPO/WholeProgramDevirt.h" 11*df49d1bbSPeter Collingbourne #include "gtest/gtest.h" 12*df49d1bbSPeter Collingbourne 13*df49d1bbSPeter Collingbourne using namespace llvm; 14*df49d1bbSPeter Collingbourne using namespace wholeprogramdevirt; 15*df49d1bbSPeter Collingbourne 16*df49d1bbSPeter Collingbourne TEST(WholeProgramDevirt, findLowestOffset) { 17*df49d1bbSPeter Collingbourne VTableBits VT1; 18*df49d1bbSPeter Collingbourne VT1.ObjectSize = 8; 19*df49d1bbSPeter Collingbourne VT1.Before.BytesUsed = {1 << 0}; 20*df49d1bbSPeter Collingbourne VT1.After.BytesUsed = {1 << 1}; 21*df49d1bbSPeter Collingbourne 22*df49d1bbSPeter Collingbourne VTableBits VT2; 23*df49d1bbSPeter Collingbourne VT2.ObjectSize = 8; 24*df49d1bbSPeter Collingbourne VT2.Before.BytesUsed = {1 << 1}; 25*df49d1bbSPeter Collingbourne VT2.After.BytesUsed = {1 << 0}; 26*df49d1bbSPeter Collingbourne 27*df49d1bbSPeter Collingbourne BitSetInfo BS1{&VT1, 0}; 28*df49d1bbSPeter Collingbourne BitSetInfo BS2{&VT2, 0}; 29*df49d1bbSPeter Collingbourne VirtualCallTarget Targets[] = { 30*df49d1bbSPeter Collingbourne {&BS1, /*IsBigEndian=*/false}, 31*df49d1bbSPeter Collingbourne {&BS2, /*IsBigEndian=*/false}, 32*df49d1bbSPeter Collingbourne }; 33*df49d1bbSPeter Collingbourne 34*df49d1bbSPeter Collingbourne EXPECT_EQ(2ull, findLowestOffset(Targets, /*IsAfter=*/false, 1)); 35*df49d1bbSPeter Collingbourne EXPECT_EQ(66ull, findLowestOffset(Targets, /*IsAfter=*/true, 1)); 36*df49d1bbSPeter Collingbourne 37*df49d1bbSPeter Collingbourne EXPECT_EQ(8ull, findLowestOffset(Targets, /*IsAfter=*/false, 8)); 38*df49d1bbSPeter Collingbourne EXPECT_EQ(72ull, findLowestOffset(Targets, /*IsAfter=*/true, 8)); 39*df49d1bbSPeter Collingbourne 40*df49d1bbSPeter Collingbourne BS1.Offset = 4; 41*df49d1bbSPeter Collingbourne EXPECT_EQ(33ull, findLowestOffset(Targets, /*IsAfter=*/false, 1)); 42*df49d1bbSPeter Collingbourne EXPECT_EQ(65ull, findLowestOffset(Targets, /*IsAfter=*/true, 1)); 43*df49d1bbSPeter Collingbourne 44*df49d1bbSPeter Collingbourne EXPECT_EQ(40ull, findLowestOffset(Targets, /*IsAfter=*/false, 8)); 45*df49d1bbSPeter Collingbourne EXPECT_EQ(72ull, findLowestOffset(Targets, /*IsAfter=*/true, 8)); 46*df49d1bbSPeter Collingbourne 47*df49d1bbSPeter Collingbourne BS1.Offset = 8; 48*df49d1bbSPeter Collingbourne BS2.Offset = 8; 49*df49d1bbSPeter Collingbourne EXPECT_EQ(66ull, findLowestOffset(Targets, /*IsAfter=*/false, 1)); 50*df49d1bbSPeter Collingbourne EXPECT_EQ(2ull, findLowestOffset(Targets, /*IsAfter=*/true, 1)); 51*df49d1bbSPeter Collingbourne 52*df49d1bbSPeter Collingbourne EXPECT_EQ(72ull, findLowestOffset(Targets, /*IsAfter=*/false, 8)); 53*df49d1bbSPeter Collingbourne EXPECT_EQ(8ull, findLowestOffset(Targets, /*IsAfter=*/true, 8)); 54*df49d1bbSPeter Collingbourne 55*df49d1bbSPeter Collingbourne VT1.After.BytesUsed = {0xff, 0, 0, 0, 0xff}; 56*df49d1bbSPeter Collingbourne VT2.After.BytesUsed = {0xff, 1, 0, 0, 0}; 57*df49d1bbSPeter Collingbourne EXPECT_EQ(16ull, findLowestOffset(Targets, /*IsAfter=*/true, 16)); 58*df49d1bbSPeter Collingbourne EXPECT_EQ(40ull, findLowestOffset(Targets, /*IsAfter=*/true, 32)); 59*df49d1bbSPeter Collingbourne } 60*df49d1bbSPeter Collingbourne 61*df49d1bbSPeter Collingbourne TEST(WholeProgramDevirt, setReturnValues) { 62*df49d1bbSPeter Collingbourne VTableBits VT1; 63*df49d1bbSPeter Collingbourne VT1.ObjectSize = 8; 64*df49d1bbSPeter Collingbourne 65*df49d1bbSPeter Collingbourne VTableBits VT2; 66*df49d1bbSPeter Collingbourne VT2.ObjectSize = 8; 67*df49d1bbSPeter Collingbourne 68*df49d1bbSPeter Collingbourne BitSetInfo BS1{&VT1, 0}; 69*df49d1bbSPeter Collingbourne BitSetInfo BS2{&VT2, 0}; 70*df49d1bbSPeter Collingbourne VirtualCallTarget Targets[] = { 71*df49d1bbSPeter Collingbourne {&BS1, /*IsBigEndian=*/false}, 72*df49d1bbSPeter Collingbourne {&BS2, /*IsBigEndian=*/false}, 73*df49d1bbSPeter Collingbourne }; 74*df49d1bbSPeter Collingbourne 75*df49d1bbSPeter Collingbourne BS1.Offset = 4; 76*df49d1bbSPeter Collingbourne BS2.Offset = 4; 77*df49d1bbSPeter Collingbourne 78*df49d1bbSPeter Collingbourne int64_t OffsetByte; 79*df49d1bbSPeter Collingbourne uint64_t OffsetBit; 80*df49d1bbSPeter Collingbourne 81*df49d1bbSPeter Collingbourne Targets[0].RetVal = 1; 82*df49d1bbSPeter Collingbourne Targets[1].RetVal = 0; 83*df49d1bbSPeter Collingbourne setBeforeReturnValues(Targets, 32, 1, OffsetByte, OffsetBit); 84*df49d1bbSPeter Collingbourne EXPECT_EQ(-5ll, OffsetByte); 85*df49d1bbSPeter Collingbourne EXPECT_EQ(0ull, OffsetBit); 86*df49d1bbSPeter Collingbourne EXPECT_EQ(std::vector<uint8_t>{1}, VT1.Before.Bytes); 87*df49d1bbSPeter Collingbourne EXPECT_EQ(std::vector<uint8_t>{1}, VT1.Before.BytesUsed); 88*df49d1bbSPeter Collingbourne EXPECT_EQ(std::vector<uint8_t>{0}, VT2.Before.Bytes); 89*df49d1bbSPeter Collingbourne EXPECT_EQ(std::vector<uint8_t>{1}, VT2.Before.BytesUsed); 90*df49d1bbSPeter Collingbourne 91*df49d1bbSPeter Collingbourne Targets[0].RetVal = 0; 92*df49d1bbSPeter Collingbourne Targets[1].RetVal = 1; 93*df49d1bbSPeter Collingbourne setBeforeReturnValues(Targets, 39, 1, OffsetByte, OffsetBit); 94*df49d1bbSPeter Collingbourne EXPECT_EQ(-5ll, OffsetByte); 95*df49d1bbSPeter Collingbourne EXPECT_EQ(7ull, OffsetBit); 96*df49d1bbSPeter Collingbourne EXPECT_EQ(std::vector<uint8_t>{1}, VT1.Before.Bytes); 97*df49d1bbSPeter Collingbourne EXPECT_EQ(std::vector<uint8_t>{0x81}, VT1.Before.BytesUsed); 98*df49d1bbSPeter Collingbourne EXPECT_EQ(std::vector<uint8_t>{0x80}, VT2.Before.Bytes); 99*df49d1bbSPeter Collingbourne EXPECT_EQ(std::vector<uint8_t>{0x81}, VT2.Before.BytesUsed); 100*df49d1bbSPeter Collingbourne 101*df49d1bbSPeter Collingbourne Targets[0].RetVal = 12; 102*df49d1bbSPeter Collingbourne Targets[1].RetVal = 34; 103*df49d1bbSPeter Collingbourne setBeforeReturnValues(Targets, 40, 8, OffsetByte, OffsetBit); 104*df49d1bbSPeter Collingbourne EXPECT_EQ(-6ll, OffsetByte); 105*df49d1bbSPeter Collingbourne EXPECT_EQ(0ull, OffsetBit); 106*df49d1bbSPeter Collingbourne EXPECT_EQ((std::vector<uint8_t>{1, 12}), VT1.Before.Bytes); 107*df49d1bbSPeter Collingbourne EXPECT_EQ((std::vector<uint8_t>{0x81, 0xff}), VT1.Before.BytesUsed); 108*df49d1bbSPeter Collingbourne EXPECT_EQ((std::vector<uint8_t>{0x80, 34}), VT2.Before.Bytes); 109*df49d1bbSPeter Collingbourne EXPECT_EQ((std::vector<uint8_t>{0x81, 0xff}), VT2.Before.BytesUsed); 110*df49d1bbSPeter Collingbourne 111*df49d1bbSPeter Collingbourne Targets[0].RetVal = 56; 112*df49d1bbSPeter Collingbourne Targets[1].RetVal = 78; 113*df49d1bbSPeter Collingbourne setBeforeReturnValues(Targets, 48, 16, OffsetByte, OffsetBit); 114*df49d1bbSPeter Collingbourne EXPECT_EQ(-8ll, OffsetByte); 115*df49d1bbSPeter Collingbourne EXPECT_EQ(0ull, OffsetBit); 116*df49d1bbSPeter Collingbourne EXPECT_EQ((std::vector<uint8_t>{1, 12, 0, 56}), VT1.Before.Bytes); 117*df49d1bbSPeter Collingbourne EXPECT_EQ((std::vector<uint8_t>{0x81, 0xff, 0xff, 0xff}), 118*df49d1bbSPeter Collingbourne VT1.Before.BytesUsed); 119*df49d1bbSPeter Collingbourne EXPECT_EQ((std::vector<uint8_t>{0x80, 34, 0, 78}), VT2.Before.Bytes); 120*df49d1bbSPeter Collingbourne EXPECT_EQ((std::vector<uint8_t>{0x81, 0xff, 0xff, 0xff}), 121*df49d1bbSPeter Collingbourne VT2.Before.BytesUsed); 122*df49d1bbSPeter Collingbourne 123*df49d1bbSPeter Collingbourne Targets[0].RetVal = 1; 124*df49d1bbSPeter Collingbourne Targets[1].RetVal = 0; 125*df49d1bbSPeter Collingbourne setAfterReturnValues(Targets, 32, 1, OffsetByte, OffsetBit); 126*df49d1bbSPeter Collingbourne EXPECT_EQ(4ll, OffsetByte); 127*df49d1bbSPeter Collingbourne EXPECT_EQ(0ull, OffsetBit); 128*df49d1bbSPeter Collingbourne EXPECT_EQ(std::vector<uint8_t>{1}, VT1.After.Bytes); 129*df49d1bbSPeter Collingbourne EXPECT_EQ(std::vector<uint8_t>{1}, VT1.After.BytesUsed); 130*df49d1bbSPeter Collingbourne EXPECT_EQ(std::vector<uint8_t>{0}, VT2.After.Bytes); 131*df49d1bbSPeter Collingbourne EXPECT_EQ(std::vector<uint8_t>{1}, VT2.After.BytesUsed); 132*df49d1bbSPeter Collingbourne 133*df49d1bbSPeter Collingbourne Targets[0].RetVal = 0; 134*df49d1bbSPeter Collingbourne Targets[1].RetVal = 1; 135*df49d1bbSPeter Collingbourne setAfterReturnValues(Targets, 39, 1, OffsetByte, OffsetBit); 136*df49d1bbSPeter Collingbourne EXPECT_EQ(4ll, OffsetByte); 137*df49d1bbSPeter Collingbourne EXPECT_EQ(7ull, OffsetBit); 138*df49d1bbSPeter Collingbourne EXPECT_EQ(std::vector<uint8_t>{1}, VT1.After.Bytes); 139*df49d1bbSPeter Collingbourne EXPECT_EQ(std::vector<uint8_t>{0x81}, VT1.After.BytesUsed); 140*df49d1bbSPeter Collingbourne EXPECT_EQ(std::vector<uint8_t>{0x80}, VT2.After.Bytes); 141*df49d1bbSPeter Collingbourne EXPECT_EQ(std::vector<uint8_t>{0x81}, VT2.After.BytesUsed); 142*df49d1bbSPeter Collingbourne 143*df49d1bbSPeter Collingbourne Targets[0].RetVal = 12; 144*df49d1bbSPeter Collingbourne Targets[1].RetVal = 34; 145*df49d1bbSPeter Collingbourne setAfterReturnValues(Targets, 40, 8, OffsetByte, OffsetBit); 146*df49d1bbSPeter Collingbourne EXPECT_EQ(5ll, OffsetByte); 147*df49d1bbSPeter Collingbourne EXPECT_EQ(0ull, OffsetBit); 148*df49d1bbSPeter Collingbourne EXPECT_EQ((std::vector<uint8_t>{1, 12}), VT1.After.Bytes); 149*df49d1bbSPeter Collingbourne EXPECT_EQ((std::vector<uint8_t>{0x81, 0xff}), VT1.After.BytesUsed); 150*df49d1bbSPeter Collingbourne EXPECT_EQ((std::vector<uint8_t>{0x80, 34}), VT2.After.Bytes); 151*df49d1bbSPeter Collingbourne EXPECT_EQ((std::vector<uint8_t>{0x81, 0xff}), VT2.After.BytesUsed); 152*df49d1bbSPeter Collingbourne 153*df49d1bbSPeter Collingbourne Targets[0].RetVal = 56; 154*df49d1bbSPeter Collingbourne Targets[1].RetVal = 78; 155*df49d1bbSPeter Collingbourne setAfterReturnValues(Targets, 48, 16, OffsetByte, OffsetBit); 156*df49d1bbSPeter Collingbourne EXPECT_EQ(6ll, OffsetByte); 157*df49d1bbSPeter Collingbourne EXPECT_EQ(0ull, OffsetBit); 158*df49d1bbSPeter Collingbourne EXPECT_EQ((std::vector<uint8_t>{1, 12, 56, 0}), VT1.After.Bytes); 159*df49d1bbSPeter Collingbourne EXPECT_EQ((std::vector<uint8_t>{0x81, 0xff, 0xff, 0xff}), 160*df49d1bbSPeter Collingbourne VT1.After.BytesUsed); 161*df49d1bbSPeter Collingbourne EXPECT_EQ((std::vector<uint8_t>{0x80, 34, 78, 0}), VT2.After.Bytes); 162*df49d1bbSPeter Collingbourne EXPECT_EQ((std::vector<uint8_t>{0x81, 0xff, 0xff, 0xff}), 163*df49d1bbSPeter Collingbourne VT2.After.BytesUsed); 164*df49d1bbSPeter Collingbourne } 165