Krzysztof Parzyszek | 52c2158 | 2018-11-29 18:20:08 +0000 | [diff] [blame] | 1 | // RUN: llvm-tblgen -gen-register-info -I %p/../../include %s 2>&1 | FileCheck %s |
| 2 | // |
| 3 | // CHECK-NOT: warning: SubRegIndex Test::subreg_h64 and Test::subreg_h32 compose ambiguously as Test::subreg_hh32 or Test::subreg_h32 |
| 4 | // CHECK: warning: SubRegIndex Test::subreg_l64 and Test::subreg_l32 compose ambiguously as Test::subreg_ll32 or Test::subreg_l32 |
| 5 | |
| 6 | include "llvm/Target/Target.td" |
| 7 | |
| 8 | def TestInstrInfo : InstrInfo { |
| 9 | } |
| 10 | |
| 11 | def Test : Target { |
| 12 | let InstructionSet = TestInstrInfo; |
| 13 | } |
| 14 | |
| 15 | let Namespace = "Test" in { |
| 16 | def subreg_l32 : SubRegIndex<32, 0>; |
| 17 | def subreg_h32 : SubRegIndex<32, 32>; |
| 18 | def subreg_h64 : SubRegIndex<64, 64>; |
| 19 | def subreg_l64 : SubRegIndex<64, 0>; |
| 20 | def subreg_hh32 : ComposedSubRegIndex<subreg_h64, subreg_h32>; |
| 21 | def subreg_ll32 : ComposedSubRegIndex<subreg_l64, subreg_l32>; |
| 22 | } |
| 23 | |
| 24 | class TestReg<string n, list<Register> s> : RegisterWithSubRegs<n, s> { |
| 25 | let Namespace = "Test"; |
| 26 | } |
| 27 | |
| 28 | // -------------------------------------------------------------------- |
| 29 | // A situation that previously caused the warning about ambiguous |
| 30 | // composition. |
| 31 | // |
| 32 | // The actual subregister actions are: |
| 33 | // subreg_h64: { F0Q->F0D V0Q->F0D } |
| 34 | // subreg_h32: { F0D->F0S F0Q->F2S V0Q->F0S } |
| 35 | // composition: { F0Q->F0S V0Q->F0S } (this is the same as subreg_hh32) |
| 36 | // |
| 37 | // For the register V0Q, subreg_hh32(V0Q) = subreg_h32(V0Q) = F0S, which |
| 38 | // would be enough to trigger the warning about ambiguous composition. |
| 39 | // However, for F0Q, subreg_hh32(F0Q) = F0S, while subreg_h32(F0Q) = F2S, |
| 40 | // which shows that there two subregister indices are different. |
| 41 | // Make sure that the warning is not emitted in this case. |
| 42 | |
| 43 | class FPR32<string n> : TestReg<n, []> { |
| 44 | } |
| 45 | |
| 46 | class FPR64<string n, FPR32 high> : TestReg<n, [high]> { |
| 47 | let SubRegIndices = [subreg_h32]; |
| 48 | } |
| 49 | |
| 50 | class FPR128<string n, FPR64 high, FPR32 low> : TestReg<n, [high, low]> { |
| 51 | let SubRegIndices = [subreg_h64, subreg_h32]; |
| 52 | } |
| 53 | |
| 54 | class VPR128<string n, FPR64 high> : TestReg<n, [high]> { |
| 55 | let SubRegIndices = [subreg_h64]; |
| 56 | } |
| 57 | |
| 58 | def F0S : FPR32<"f0s">; |
| 59 | def F1S : FPR32<"f1s">; |
| 60 | def F2S : FPR32<"f2s">; |
| 61 | |
| 62 | def F0D : FPR64<"f0d", F0S>; |
| 63 | def F0Q : FPR128<"f0q", F0D, F2S>; |
| 64 | def V0Q : VPR128<"v0q", F0D>; |
| 65 | |
| 66 | def FP32 : RegisterClass<"FP32", [f32], 32, (add F0S)>; |
| 67 | def FP64 : RegisterClass<"FP64", [f64], 64, (add F0D)>; |
| 68 | def FP128 : RegisterClass<"FP128", [v2f64], 128, (add F0Q)>; |
| 69 | def VP128 : RegisterClass<"VP128", [v2f64], 128, (add V0Q)>; |
| 70 | |
| 71 | // -------------------------------------------------------------------- |
| 72 | // A situation where the warning is legitimate. |
| 73 | // Make sure that the warning is still displayed. |
| 74 | |
| 75 | class GPR32<string n> : TestReg<n, []> { |
| 76 | } |
| 77 | |
| 78 | class GPR64<string n, GPR32 low> : TestReg<n, [low]> { |
| 79 | let SubRegIndices = [subreg_l32]; |
| 80 | } |
| 81 | |
| 82 | class GPR128<string n, GPR64 low> : TestReg<n, [low]> { |
| 83 | let SubRegIndices = [subreg_l64]; |
| 84 | } |
| 85 | |
| 86 | def G0S : GPR32<"g0s">; |
| 87 | def G0D : GPR64<"g0d", G0S>; |
| 88 | def G0Q : GPR128<"g0q", G0D>; |
| 89 | |
| 90 | def GP32 : RegisterClass<"GP32", [i32], 32, (add G0S)>; |
| 91 | def GP64 : RegisterClass<"GP64", [i64], 64, (add G0D)>; |
| 92 | def GP128 : RegisterClass<"GP128", [v2i64], 128, (add G0Q)>; |