File: Immediates.cpp

package info (click to toggle)
llvm-toolchain-20 1%3A20.1.6-1~exp1
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 2,111,304 kB
  • sloc: cpp: 7,438,677; ansic: 1,393,822; asm: 1,012,926; python: 241,650; f90: 86,635; objc: 75,479; lisp: 42,144; pascal: 17,286; sh: 10,027; ml: 5,082; perl: 4,730; awk: 3,523; makefile: 3,349; javascript: 2,251; xml: 892; fortran: 672
file content (106 lines) | stat: -rw-r--r-- 2,852 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#include "AArch64Subtarget.h"
#include "AArch64TargetMachine.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Support/TargetSelect.h"

#include "gtest/gtest.h"
#include <initializer_list>
#include <memory>

using namespace llvm;

namespace {

struct TestCase {
  int64_t Imm;
  bool Result;
};

const std::initializer_list<TestCase> Tests = {
    // ScalableImm, Result
    // No change, easily 'supported'
    {0, true},

    // addvl increments by whole registers, range [-32,31]
    // +(16 * vscale), one register's worth
    {16, true},
    // -(32 * 16 * vscale)
    {-512, true},
    // -(33 * 16 * vscale)
    {-528, false},
    // +(31 * 16 * vscale)
    {496, true},
    // +(32 * 16 * vscale)
    {512, false},

    // inc[h|w|d] increments by the number of 16/32/64bit elements in a
    // register. mult_imm is in the range [1,16]
    // +(mult_imm * num_elts * vscale)
    // +(1 * 8 * vscale), 16 bit
    {8, true},
    // +(15 * 8 * vscale), 16 bit
    {120, true},
    // +(1 * 4 * vscale), 32 bit
    {4, true},
    // +(7 * 4 * vscale), 32 bit
    {28, true},
    // +(1 * 2 * vscale), 64 bit
    {2, true},
    // +(13 * 2 * vscale), 64 bit
    {26, true},
    // +(17 * 8 * vscale), 16 bit, out of range.
    {136, false},
    // +(19 * 2 * vscale), 64 bit, out of range.
    {38, false},
    // +(21 * 4 * vscale), 32 bit, out of range.
    {84, false},

    // dec[h|w|d] -- Same as above, but negative.
    // -(mult_imm * num_elts * vscale)
    // -(1 * 8 * vscale), 16 bit
    {-8, true},
    // -(15 * 8 * vscale), 16 bit
    {-120, true},
    // -(1 * 4 * vscale), 32 bit
    {-4, true},
    // -(7 * 4 * vscale), 32 bit
    {-28, true},
    // -(1 * 2 * vscale), 64 bit
    {-2, true},
    // -(13 * 2 * vscale), 64 bit
    {-26, true},
    // -(17 * 8 * vscale), 16 bit, out of range.
    {-136, false},
    // -(19 * 2 * vscale), 64 bit, out of range.
    {-38, false},
    // -(21 * 4 * vscale), 32 bit, out of range.
    {-84, false},

    // Invalid; not divisible by the above powers of 2.
    {5, false},
};
} // namespace

TEST(Immediates, Immediates) {
  LLVMInitializeAArch64TargetInfo();
  LLVMInitializeAArch64Target();
  LLVMInitializeAArch64TargetMC();

  std::string Error;
  auto TT = Triple::normalize("aarch64");
  const Target *T = TargetRegistry::lookupTarget(TT, Error);

  std::unique_ptr<TargetMachine> TM(T->createTargetMachine(
      TT, "generic", "+sve2", TargetOptions(), std::nullopt, std::nullopt,
      CodeGenOptLevel::Default));
  AArch64Subtarget ST(TM->getTargetTriple(), TM->getTargetCPU(),
                      TM->getTargetCPU(), TM->getTargetFeatureString(), *TM,
                      true);

  auto *TLI = ST.getTargetLowering();

  for (const auto &Test : Tests) {
    ASSERT_EQ(TLI->isLegalAddScalableImmediate(Test.Imm), Test.Result);
  }
}