llvm.org GIT mirror llvm / 5b113a2
[GlobalISel][X86] Support G_LSHR/G_ASHR/G_SHL Support G_LSHR/G_ASHR/G_SHL. We have 3 variance for shift instructions : shift gpr, shift imm, shift 1. Currently GlobalIsel TableGen generate patterns for shift imm and shift 1, but with shiftCount i8. In G_LSHR/G_ASHR/G_SHL like LLVM-IR both arguments has the same type, so for now only shift i8 can use auto generated TableGen patterns. The support of G_SHL/G_ASHR enables tryCombineSExt from LegalizationArtifactCombiner.h to hit, which results in different legalization for the following tests: LLVM :: CodeGen/X86/GlobalISel/ext-x86-64.ll LLVM :: CodeGen/X86/GlobalISel/gep.ll LLVM :: CodeGen/X86/GlobalISel/legalize-ext-x86-64.mir -; X64-NEXT: movsbl %dil, %eax +; X64-NEXT: movl $24, %ecx +; X64-NEXT: # kill: def $cl killed $ecx +; X64-NEXT: shll %cl, %edi +; X64-NEXT: movl $24, %ecx +; X64-NEXT: # kill: def $cl killed $ecx +; X64-NEXT: sarl %cl, %edi +; X64-NEXT: movl %edi, %eax ..which is not optimal and should be addressed later. Rework of the patch by igorb Reviewed By: igorb Differential Revision: https://reviews.llvm.org/D44395 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@327499 91177308-0d34-0410-b5e6-96231b3b80d8 Alexander Ivchenko 2 years ago
16 changed file(s) with 2430 addition(s) and 13 deletion(s). Raw diff Collapse all Expand all
111111 bool materializeFP(MachineInstr &I, MachineRegisterInfo &MRI,
112112 MachineFunction &MF) const;
113113 bool selectImplicitDefOrPHI(MachineInstr &I, MachineRegisterInfo &MRI) const;
114 bool selectShift(MachineInstr &I, MachineRegisterInfo &MRI,
115 MachineFunction &MF) const;
114116
115117 // emit insert subreg instruction and insert it before MachineInstr &I
116118 bool emitInsertSubreg(unsigned DstReg, unsigned SrcReg, MachineInstr &I,
372374 case TargetOpcode::G_IMPLICIT_DEF:
373375 case TargetOpcode::G_PHI:
374376 return selectImplicitDefOrPHI(I, MRI);
377 case TargetOpcode::G_SHL:
378 case TargetOpcode::G_ASHR:
379 case TargetOpcode::G_LSHR:
380 return selectShift(I, MRI, MF);
375381 }
376382
377383 return false;
13951401 return true;
13961402 }
13971403
1404 // Currently GlobalIsel TableGen generates patterns for shift imm and shift 1,
1405 // but with shiftCount i8. In G_LSHR/G_ASHR/G_SHL like LLVM-IR both arguments
1406 // has the same type, so for now only shift i8 can use auto generated
1407 // TableGen patterns.
1408 bool X86InstructionSelector::selectShift(MachineInstr &I,
1409 MachineRegisterInfo &MRI,
1410 MachineFunction &MF) const {
1411
1412 assert((I.getOpcode() == TargetOpcode::G_SHL ||
1413 I.getOpcode() == TargetOpcode::G_ASHR ||
1414 I.getOpcode() == TargetOpcode::G_LSHR) &&
1415 "unexpected instruction");
1416
1417 unsigned DstReg = I.getOperand(0).getReg();
1418 const LLT DstTy = MRI.getType(DstReg);
1419 const RegisterBank &DstRB = *RBI.getRegBank(DstReg, MRI, TRI);
1420
1421 const static struct ShiftEntry {
1422 unsigned SizeInBits;
1423 unsigned CReg;
1424 unsigned OpLSHR;
1425 unsigned OpASHR;
1426 unsigned OpSHL;
1427 } OpTable[] = {
1428 {8, X86::CL, X86::SHR8rCL, X86::SAR8rCL, X86::SHL8rCL}, // i8
1429 {16, X86::CX, X86::SHR16rCL, X86::SAR16rCL, X86::SHL16rCL}, // i16
1430 {32, X86::ECX, X86::SHR32rCL, X86::SAR32rCL, X86::SHL32rCL}, // i32
1431 {64, X86::RCX, X86::SHR64rCL, X86::SAR64rCL, X86::SHL64rCL} // i64
1432 };
1433
1434 if (DstRB.getID() != X86::GPRRegBankID)
1435 return false;
1436
1437 auto ShiftEntryIt = std::find_if(
1438 std::begin(OpTable), std::end(OpTable), [DstTy](const ShiftEntry &El) {
1439 return El.SizeInBits == DstTy.getSizeInBits();
1440 });
1441 if (ShiftEntryIt == std::end(OpTable))
1442 return false;
1443
1444 unsigned CReg = ShiftEntryIt->CReg;
1445 unsigned Opcode = 0;
1446 switch (I.getOpcode()) {
1447 case TargetOpcode::G_SHL:
1448 Opcode = ShiftEntryIt->OpSHL;
1449 break;
1450 case TargetOpcode::G_ASHR:
1451 Opcode = ShiftEntryIt->OpASHR;
1452 break;
1453 case TargetOpcode::G_LSHR:
1454 Opcode = ShiftEntryIt->OpLSHR;
1455 break;
1456 default:
1457 return false;
1458 }
1459
1460 unsigned Op0Reg = I.getOperand(1).getReg();
1461 unsigned Op1Reg = I.getOperand(2).getReg();
1462
1463 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(TargetOpcode::COPY),
1464 ShiftEntryIt->CReg)
1465 .addReg(Op1Reg);
1466
1467 // The shift instruction uses X86::CL. If we defined a super-register
1468 // of X86::CL, emit a subreg KILL to precisely describe what we're doing here.
1469 if (CReg != X86::CL)
1470 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(TargetOpcode::KILL),
1471 X86::CL)
1472 .addReg(CReg, RegState::Kill);
1473
1474 MachineInstr &ShiftInst =
1475 *BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(Opcode), DstReg)
1476 .addReg(Op0Reg);
1477
1478 constrainSelectedInstRegOperands(ShiftInst, TII, TRI, RBI);
1479 I.eraseFromParent();
1480 return true;
1481 }
1482
13981483 InstructionSelector *
13991484 llvm::createX86InstructionSelector(const X86TargetMachine &TM,
14001485 X86Subtarget &Subtarget,
129129 .maxScalar(0, s32)
130130 .widenScalarToNextPow2(0, /*Min*/ 8);
131131 getActionDefinitionsBuilder(G_INTTOPTR).legalFor({s32, p0});
132
133 // Shifts
134 getActionDefinitionsBuilder({G_SHL, G_LSHR, G_ASHR})
135 .legalFor({s8, s16, s32})
136 .clampScalar(0, s8, s32);
132137 }
133138
134139 // Control-flow
207212
208213 // Comparison
209214 setAction({G_ICMP, 1, s64}, Legal);
215
216 // Shifts
217 getActionDefinitionsBuilder({G_SHL, G_LSHR, G_ASHR})
218 .legalFor({s8, s16, s32, s64})
219 .clampScalar(0, s8, s64);
210220
211221 // Merge/Unmerge
212222 setAction({G_MERGE_VALUES, s128}, Legal);
172172 switch (Opc) {
173173 case TargetOpcode::G_ADD:
174174 case TargetOpcode::G_SUB:
175 case TargetOpcode::G_MUL:
176 case TargetOpcode::G_SHL:
177 case TargetOpcode::G_LSHR:
178 case TargetOpcode::G_ASHR:
175179 return getSameOperandsMapping(MI, false);
176180 break;
177181 case TargetOpcode::G_FADD:
0 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
1 ; RUN: llc -mtriple=x86_64-linux-gnu -global-isel -verify-machineinstrs < %s -o - | FileCheck %s --check-prefix=X64
2
3 define i64 @test_ashr_i64(i64 %arg1, i64 %arg2) {
4 ; X64-LABEL: test_ashr_i64:
5 ; X64: # %bb.0:
6 ; X64-NEXT: movq %rsi, %rcx
7 ; X64-NEXT: # kill: def $cl killed $rcx
8 ; X64-NEXT: sarq %cl, %rdi
9 ; X64-NEXT: movq %rdi, %rax
10 ; X64-NEXT: retq
11 %res = ashr i64 %arg1, %arg2
12 ret i64 %res
13 }
14
15 define i64 @test_ashr_i64_imm(i64 %arg1) {
16 ; X64-LABEL: test_ashr_i64_imm:
17 ; X64: # %bb.0:
18 ; X64-NEXT: movq $5, %rcx
19 ; X64-NEXT: # kill: def $cl killed $rcx
20 ; X64-NEXT: sarq %cl, %rdi
21 ; X64-NEXT: movq %rdi, %rax
22 ; X64-NEXT: retq
23 %res = ashr i64 %arg1, 5
24 ret i64 %res
25 }
26
27 define i64 @test_ashr_i64_imm1(i64 %arg1) {
28 ; X64-LABEL: test_ashr_i64_imm1:
29 ; X64: # %bb.0:
30 ; X64-NEXT: movq $1, %rcx
31 ; X64-NEXT: # kill: def $cl killed $rcx
32 ; X64-NEXT: sarq %cl, %rdi
33 ; X64-NEXT: movq %rdi, %rax
34 ; X64-NEXT: retq
35 %res = ashr i64 %arg1, 1
36 ret i64 %res
37 }
38
39 define i32 @test_ashr_i32(i32 %arg1, i32 %arg2) {
40 ; X64-LABEL: test_ashr_i32:
41 ; X64: # %bb.0:
42 ; X64-NEXT: movl %esi, %ecx
43 ; X64-NEXT: # kill: def $cl killed $ecx
44 ; X64-NEXT: sarl %cl, %edi
45 ; X64-NEXT: movl %edi, %eax
46 ; X64-NEXT: retq
47 %res = ashr i32 %arg1, %arg2
48 ret i32 %res
49 }
50
51 define i32 @test_ashr_i32_imm(i32 %arg1) {
52 ; X64-LABEL: test_ashr_i32_imm:
53 ; X64: # %bb.0:
54 ; X64-NEXT: movl $5, %ecx
55 ; X64-NEXT: # kill: def $cl killed $ecx
56 ; X64-NEXT: sarl %cl, %edi
57 ; X64-NEXT: movl %edi, %eax
58 ; X64-NEXT: retq
59 %res = ashr i32 %arg1, 5
60 ret i32 %res
61 }
62
63 define i32 @test_ashr_i32_imm1(i32 %arg1) {
64 ; X64-LABEL: test_ashr_i32_imm1:
65 ; X64: # %bb.0:
66 ; X64-NEXT: movl $1, %ecx
67 ; X64-NEXT: # kill: def $cl killed $ecx
68 ; X64-NEXT: sarl %cl, %edi
69 ; X64-NEXT: movl %edi, %eax
70 ; X64-NEXT: retq
71 %res = ashr i32 %arg1, 1
72 ret i32 %res
73 }
74
75 define i16 @test_ashr_i16(i32 %arg1, i32 %arg2) {
76 ; X64-LABEL: test_ashr_i16:
77 ; X64: # %bb.0:
78 ; X64-NEXT: movl %esi, %ecx
79 ; X64-NEXT: # kill: def $cl killed $cx
80 ; X64-NEXT: sarw %cl, %di
81 ; X64-NEXT: movl %edi, %eax
82 ; X64-NEXT: retq
83 %a = trunc i32 %arg1 to i16
84 %a2 = trunc i32 %arg2 to i16
85 %res = ashr i16 %a, %a2
86 ret i16 %res
87 }
88
89 define i16 @test_ashr_i16_imm(i32 %arg1) {
90 ; X64-LABEL: test_ashr_i16_imm:
91 ; X64: # %bb.0:
92 ; X64-NEXT: movw $5, %cx
93 ; X64-NEXT: # kill: def $cl killed $cx
94 ; X64-NEXT: sarw %cl, %di
95 ; X64-NEXT: movl %edi, %eax
96 ; X64-NEXT: retq
97 %a = trunc i32 %arg1 to i16
98 %res = ashr i16 %a, 5
99 ret i16 %res
100 }
101
102 define i16 @test_ashr_i16_imm1(i32 %arg1) {
103 ; X64-LABEL: test_ashr_i16_imm1:
104 ; X64: # %bb.0:
105 ; X64-NEXT: movw $1, %cx
106 ; X64-NEXT: # kill: def $cl killed $cx
107 ; X64-NEXT: sarw %cl, %di
108 ; X64-NEXT: movl %edi, %eax
109 ; X64-NEXT: retq
110 %a = trunc i32 %arg1 to i16
111 %res = ashr i16 %a, 1
112 ret i16 %res
113 }
114
115 define i8 @test_ashr_i8(i32 %arg1, i32 %arg2) {
116 ; X64-LABEL: test_ashr_i8:
117 ; X64: # %bb.0:
118 ; X64-NEXT: movl %esi, %ecx
119 ; X64-NEXT: sarb %cl, %dil
120 ; X64-NEXT: movl %edi, %eax
121 ; X64-NEXT: retq
122 %a = trunc i32 %arg1 to i8
123 %a2 = trunc i32 %arg2 to i8
124 %res = ashr i8 %a, %a2
125 ret i8 %res
126 }
127
128 define i8 @test_ashr_i8_imm(i32 %arg1) {
129 ; X64-LABEL: test_ashr_i8_imm:
130 ; X64: # %bb.0:
131 ; X64-NEXT: sarb $5, %dil
132 ; X64-NEXT: movl %edi, %eax
133 ; X64-NEXT: retq
134 %a = trunc i32 %arg1 to i8
135 %res = ashr i8 %a, 5
136 ret i8 %res
137 }
138
139 define i8 @test_ashr_i8_imm1(i32 %arg1) {
140 ; X64-LABEL: test_ashr_i8_imm1:
141 ; X64: # %bb.0:
142 ; X64-NEXT: sarb %dil
143 ; X64-NEXT: movl %edi, %eax
144 ; X64-NEXT: retq
145 %a = trunc i32 %arg1 to i8
146 %res = ashr i8 %a, 1
147 ret i8 %res
148 }
149
150 define i1 @test_ashr_i1(i32 %arg1, i32 %arg2) {
151 ; X64-LABEL: test_ashr_i1:
152 ; X64: # %bb.0:
153 ; X64-NEXT: shlb $7, %dil
154 ; X64-NEXT: sarb $7, %dil
155 ; X64-NEXT: shlb $7, %sil
156 ; X64-NEXT: sarb $7, %sil
157 ; X64-NEXT: movl %esi, %ecx
158 ; X64-NEXT: sarb %cl, %dil
159 ; X64-NEXT: movl %edi, %eax
160 ; X64-NEXT: retq
161 %a = trunc i32 %arg1 to i1
162 %a2 = trunc i32 %arg2 to i1
163 %res = ashr i1 %a, %a2
164 ret i1 %res
165 }
166
167 define i1 @test_ashr_i1_imm1(i32 %arg1) {
168 ; X64-LABEL: test_ashr_i1_imm1:
169 ; X64: # %bb.0:
170 ; X64-NEXT: movb $-1, %cl
171 ; X64-NEXT: shlb $7, %dil
172 ; X64-NEXT: sarb $7, %dil
173 ; X64-NEXT: shlb $7, %cl
174 ; X64-NEXT: sarb $7, %cl
175 ; X64-NEXT: sarb %cl, %dil
176 ; X64-NEXT: movl %edi, %eax
177 ; X64-NEXT: retq
178 %a = trunc i32 %arg1 to i1
179 %res = ashr i1 %a, 1
180 ret i1 %res
181 }
1717 define i64 @test_sext_i8(i8 %val) {
1818 ; X64-LABEL: test_sext_i8:
1919 ; X64: # %bb.0:
20 ; X64-NEXT: movsbq %dil, %rax
20 ; X64-NEXT: # kill: def $edi killed $edi def $rdi
21 ; X64-NEXT: movq $56, %rcx
22 ; X64-NEXT: # kill: def $cl killed $rcx
23 ; X64-NEXT: shlq %cl, %rdi
24 ; X64-NEXT: movq $56, %rcx
25 ; X64-NEXT: # kill: def $cl killed $rcx
26 ; X64-NEXT: sarq %cl, %rdi
27 ; X64-NEXT: movq %rdi, %rax
2128 ; X64-NEXT: retq
2229 %r = sext i8 %val to i64
2330 ret i64 %r
2633 define i64 @test_sext_i16(i16 %val) {
2734 ; X64-LABEL: test_sext_i16:
2835 ; X64: # %bb.0:
29 ; X64-NEXT: movswq %di, %rax
36 ; X64-NEXT: # kill: def $edi killed $edi def $rdi
37 ; X64-NEXT: movq $48, %rcx
38 ; X64-NEXT: # kill: def $cl killed $rcx
39 ; X64-NEXT: shlq %cl, %rdi
40 ; X64-NEXT: movq $48, %rcx
41 ; X64-NEXT: # kill: def $cl killed $rcx
42 ; X64-NEXT: sarq %cl, %rdi
43 ; X64-NEXT: movq %rdi, %rax
3044 ; X64-NEXT: retq
3145 %r = sext i16 %val to i64
3246 ret i64 %r
8585 define i32 @test_sext_i8(i8 %val) {
8686 ; X64-LABEL: test_sext_i8:
8787 ; X64: # %bb.0:
88 ; X64-NEXT: movsbl %dil, %eax
88 ; X64-NEXT: movl $24, %ecx
89 ; X64-NEXT: # kill: def $cl killed $ecx
90 ; X64-NEXT: shll %cl, %edi
91 ; X64-NEXT: movl $24, %ecx
92 ; X64-NEXT: # kill: def $cl killed $ecx
93 ; X64-NEXT: sarl %cl, %edi
94 ; X64-NEXT: movl %edi, %eax
8995 ; X64-NEXT: retq
9096 ;
9197 ; X32-LABEL: test_sext_i8:
99105 define i32 @test_sext_i16(i16 %val) {
100106 ; X64-LABEL: test_sext_i16:
101107 ; X64: # %bb.0:
102 ; X64-NEXT: movswl %di, %eax
108 ; X64-NEXT: movl $16, %ecx
109 ; X64-NEXT: # kill: def $cl killed $ecx
110 ; X64-NEXT: shll %cl, %edi
111 ; X64-NEXT: movl $16, %ecx
112 ; X64-NEXT: # kill: def $cl killed $ecx
113 ; X64-NEXT: sarl %cl, %edi
114 ; X64-NEXT: movl %edi, %eax
103115 ; X64-NEXT: retq
104116 ;
105117 ; X32-LABEL: test_sext_i16:
44 define i32* @test_gep_i8(i32 *%arr, i8 %ind) {
55 ; X64_GISEL-LABEL: test_gep_i8:
66 ; X64_GISEL: # %bb.0:
7 ; X64_GISEL-NEXT: # kill: def $esi killed $esi def $rsi
78 ; X64_GISEL-NEXT: movq $4, %rax
8 ; X64_GISEL-NEXT: movsbq %sil, %rcx
9 ; X64_GISEL-NEXT: imulq %rax, %rcx
10 ; X64_GISEL-NEXT: leaq (%rdi,%rcx), %rax
9 ; X64_GISEL-NEXT: movq $56, %rcx
10 ; X64_GISEL-NEXT: # kill: def $cl killed $rcx
11 ; X64_GISEL-NEXT: shlq %cl, %rsi
12 ; X64_GISEL-NEXT: movq $56, %rcx
13 ; X64_GISEL-NEXT: # kill: def $cl killed $rcx
14 ; X64_GISEL-NEXT: sarq %cl, %rsi
15 ; X64_GISEL-NEXT: imulq %rax, %rsi
16 ; X64_GISEL-NEXT: leaq (%rdi,%rsi), %rax
1117 ; X64_GISEL-NEXT: retq
1218 ;
1319 ; X64-LABEL: test_gep_i8:
3844 define i32* @test_gep_i16(i32 *%arr, i16 %ind) {
3945 ; X64_GISEL-LABEL: test_gep_i16:
4046 ; X64_GISEL: # %bb.0:
47 ; X64_GISEL-NEXT: # kill: def $esi killed $esi def $rsi
4148 ; X64_GISEL-NEXT: movq $4, %rax
42 ; X64_GISEL-NEXT: movswq %si, %rcx
43 ; X64_GISEL-NEXT: imulq %rax, %rcx
44 ; X64_GISEL-NEXT: leaq (%rdi,%rcx), %rax
49 ; X64_GISEL-NEXT: movq $48, %rcx
50 ; X64_GISEL-NEXT: # kill: def $cl killed $rcx
51 ; X64_GISEL-NEXT: shlq %cl, %rsi
52 ; X64_GISEL-NEXT: movq $48, %rcx
53 ; X64_GISEL-NEXT: # kill: def $cl killed $rcx
54 ; X64_GISEL-NEXT: sarq %cl, %rsi
55 ; X64_GISEL-NEXT: imulq %rax, %rsi
56 ; X64_GISEL-NEXT: leaq (%rdi,%rsi), %rax
4557 ; X64_GISEL-NEXT: retq
4658 ;
4759 ; X64-LABEL: test_gep_i16:
0 # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
1 # RUN: llc -mtriple=x86_64-linux-gnu -global-isel -run-pass=legalizer %s -o - | FileCheck %s
2 --- |
3
4 define void @test_ashr() { ret void }
5 define void @test_ashr_i1() { ret void }
6 ...
7 ---
8 name: test_ashr
9 alignment: 4
10 legalized: false
11 regBankSelected: false
12 tracksRegLiveness: true
13 registers:
14 - { id: 0, class: _, preferred-register: '' }
15 - { id: 1, class: _, preferred-register: '' }
16 - { id: 2, class: _, preferred-register: '' }
17 - { id: 3, class: _, preferred-register: '' }
18 - { id: 4, class: _, preferred-register: '' }
19 - { id: 5, class: _, preferred-register: '' }
20 - { id: 6, class: _, preferred-register: '' }
21 - { id: 7, class: _, preferred-register: '' }
22 - { id: 8, class: _, preferred-register: '' }
23 - { id: 9, class: _, preferred-register: '' }
24 - { id: 10, class: _, preferred-register: '' }
25 - { id: 11, class: _, preferred-register: '' }
26 body: |
27 bb.1 (%ir-block.0):
28 liveins: $rdi, $rsi
29
30 ; CHECK-LABEL: name: test_ashr
31 ; CHECK: liveins: $rdi, $rsi
32 ; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $rdi
33 ; CHECK: [[COPY1:%[0-9]+]]:_(s64) = COPY $rsi
34 ; CHECK: RET 0
35 %0(s64) = COPY $rdi
36 %1(s64) = COPY $rsi
37 %2(s64) = G_ASHR %0, %1
38
39 %3(s32) = G_TRUNC %0
40 %4(s32) = G_TRUNC %1
41 %5(s32) = G_ASHR %3, %4
42
43 %6(s16) = G_TRUNC %0
44 %7(s16) = G_TRUNC %1
45 %8(s16) = G_ASHR %6, %7
46
47 %9(s8) = G_TRUNC %0
48 %10(s8) = G_TRUNC %1
49 %11(s8) = G_ASHR %9, %10
50
51 RET 0
52
53 ...
54 ---
55 name: test_ashr_i1
56 alignment: 4
57 legalized: false
58 regBankSelected: false
59 tracksRegLiveness: true
60 registers:
61 - { id: 0, class: _, preferred-register: '' }
62 - { id: 1, class: _, preferred-register: '' }
63 - { id: 2, class: _, preferred-register: '' }
64 - { id: 3, class: _, preferred-register: '' }
65 - { id: 4, class: _, preferred-register: '' }
66 body: |
67 bb.1 (%ir-block.0):
68 liveins: $rdi, $rsi
69
70 ; CHECK-LABEL: name: test_ashr_i1
71 ; CHECK: liveins: $rdi, $rsi
72 ; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $rdi
73 ; CHECK: [[COPY1:%[0-9]+]]:_(s64) = COPY $rsi
74 ; CHECK: RET 0
75 %0(s64) = COPY $rdi
76 %1(s64) = COPY $rsi
77 %2(s1) = G_TRUNC %0
78 %3(s1) = G_TRUNC %1
79 %4(s1) = G_ASHR %2, %3
80
81 RET 0
82
83 ...
7676
7777 ; CHECK-LABEL: name: test_sext_i1
7878 ; CHECK: [[COPY:%[0-9]+]]:_(s8) = COPY $dil
79 ; CHECK: [[TRUNC:%[0-9]+]]:_(s1) = G_TRUNC [[COPY]](s8)
80 ; CHECK: [[SEXT:%[0-9]+]]:_(s64) = G_SEXT [[TRUNC]](s1)
81 ; CHECK: $rax = COPY [[SEXT]](s64)
79 ; CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 63
80 ; CHECK: [[ANYEXT:%[0-9]+]]:_(s64) = G_ANYEXT [[COPY]](s8)
81 ; CHECK: [[SHL:%[0-9]+]]:_(s64) = G_SHL [[ANYEXT]], [[C]]
82 ; CHECK: [[ASHR:%[0-9]+]]:_(s64) = G_ASHR [[SHL]], [[C]]
83 ; CHECK: $rax = COPY [[ASHR]](s64)
8284 ; CHECK: RET 0, implicit $rax
8385 %0(s8) = COPY $dil
8486 %1(s1) = G_TRUNC %0(s8)
0 # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
1 # RUN: llc -mtriple=x86_64-linux-gnu -global-isel -run-pass=legalizer %s -o - | FileCheck %s
2 --- |
3
4 define void @test_lshr() { ret void }
5 define void @test_lshr_i1() { ret void }
6 ...
7 ---
8 name: test_lshr
9 alignment: 4
10 legalized: false
11 regBankSelected: false
12 tracksRegLiveness: true
13 registers:
14 - { id: 0, class: _, preferred-register: '' }
15 - { id: 1, class: _, preferred-register: '' }
16 - { id: 2, class: _, preferred-register: '' }
17 - { id: 3, class: _, preferred-register: '' }
18 - { id: 4, class: _, preferred-register: '' }
19 - { id: 5, class: _, preferred-register: '' }
20 - { id: 6, class: _, preferred-register: '' }
21 - { id: 7, class: _, preferred-register: '' }
22 - { id: 8, class: _, preferred-register: '' }
23 - { id: 9, class: _, preferred-register: '' }
24 - { id: 10, class: _, preferred-register: '' }
25 - { id: 11, class: _, preferred-register: '' }
26 body: |
27 bb.1 (%ir-block.0):
28 liveins: $rdi, $rsi
29
30 ; CHECK-LABEL: name: test_lshr
31 ; CHECK: liveins: $rdi, $rsi
32 ; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $rdi
33 ; CHECK: [[COPY1:%[0-9]+]]:_(s64) = COPY $rsi
34 ; CHECK: RET 0
35 %0(s64) = COPY $rdi
36 %1(s64) = COPY $rsi
37 %2(s64) = G_LSHR %0, %1
38
39 %3(s32) = G_TRUNC %0
40 %4(s32) = G_TRUNC %1
41 %5(s32) = G_LSHR %3, %4
42
43 %6(s16) = G_TRUNC %0
44 %7(s16) = G_TRUNC %1
45 %8(s16) = G_LSHR %6, %7
46
47 %9(s8) = G_TRUNC %0
48 %10(s8) = G_TRUNC %1
49 %11(s8) = G_LSHR %9, %10
50
51 RET 0
52
53 ...
54 ---
55 name: test_lshr_i1
56 alignment: 4
57 legalized: false
58 regBankSelected: false
59 tracksRegLiveness: true
60 registers:
61 - { id: 0, class: _, preferred-register: '' }
62 - { id: 1, class: _, preferred-register: '' }
63 - { id: 2, class: _, preferred-register: '' }
64 - { id: 3, class: _, preferred-register: '' }
65 - { id: 4, class: _, preferred-register: '' }
66 body: |
67 bb.1 (%ir-block.0):
68 liveins: $rdi, $rsi
69
70 ; CHECK-LABEL: name: test_lshr_i1
71 ; CHECK: liveins: $rdi, $rsi
72 ; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $rdi
73 ; CHECK: [[COPY1:%[0-9]+]]:_(s64) = COPY $rsi
74 ; CHECK: RET 0
75 %0(s64) = COPY $rdi
76 %1(s64) = COPY $rsi
77 %2(s1) = G_TRUNC %0
78 %3(s1) = G_TRUNC %1
79 %4(s1) = G_LSHR %2, %3
80
81 RET 0
82
83 ...
0 # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
1 # RUN: llc -mtriple=x86_64-linux-gnu -global-isel -run-pass=legalizer %s -o - | FileCheck %s
2 --- |
3
4 define void @test_shl() { ret void }
5 define void @test_shl_i1() { ret void }
6 ...
7 ---
8 name: test_shl
9 alignment: 4
10 legalized: false
11 regBankSelected: false
12 tracksRegLiveness: true
13 registers:
14 - { id: 0, class: _, preferred-register: '' }
15 - { id: 1, class: _, preferred-register: '' }
16 - { id: 2, class: _, preferred-register: '' }
17 - { id: 3, class: _, preferred-register: '' }
18 - { id: 4, class: _, preferred-register: '' }
19 - { id: 5, class: _, preferred-register: '' }
20 - { id: 6, class: _, preferred-register: '' }
21 - { id: 7, class: _, preferred-register: '' }
22 - { id: 8, class: _, preferred-register: '' }
23 - { id: 9, class: _, preferred-register: '' }
24 - { id: 10, class: _, preferred-register: '' }
25 - { id: 11, class: _, preferred-register: '' }
26 body: |
27 bb.1 (%ir-block.0):
28 liveins: $rdi, $rsi
29
30 ; CHECK-LABEL: name: test_shl
31 ; CHECK: liveins: $rdi, $rsi
32 ; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $rdi
33 ; CHECK: [[COPY1:%[0-9]+]]:_(s64) = COPY $rsi
34 ; CHECK: RET 0
35 %0(s64) = COPY $rdi
36 %1(s64) = COPY $rsi
37 %2(s64) = G_SHL %0, %1
38
39 %3(s32) = G_TRUNC %0
40 %4(s32) = G_TRUNC %1
41 %5(s32) = G_SHL %3, %4
42
43 %6(s16) = G_TRUNC %0
44 %7(s16) = G_TRUNC %1
45 %8(s16) = G_SHL %6, %7
46
47 %9(s8) = G_TRUNC %0
48 %10(s8) = G_TRUNC %1
49 %11(s8) = G_SHL %9, %10
50
51 RET 0
52
53 ...
54 ---
55 name: test_shl_i1
56 alignment: 4
57 legalized: false
58 regBankSelected: false
59 tracksRegLiveness: true
60 registers:
61 - { id: 0, class: _, preferred-register: '' }
62 - { id: 1, class: _, preferred-register: '' }
63 - { id: 2, class: _, preferred-register: '' }
64 - { id: 3, class: _, preferred-register: '' }
65 - { id: 4, class: _, preferred-register: '' }
66 body: |
67 bb.1 (%ir-block.0):
68 liveins: $rdi, $rsi
69
70 ; CHECK-LABEL: name: test_shl_i1
71 ; CHECK: liveins: $rdi, $rsi
72 ; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $rdi
73 ; CHECK: [[COPY1:%[0-9]+]]:_(s64) = COPY $rsi
74 ; CHECK: RET 0
75 %0(s64) = COPY $rdi
76 %1(s64) = COPY $rsi
77 %2(s1) = G_TRUNC %0
78 %3(s1) = G_TRUNC %1
79 %4(s1) = G_SHL %2, %3
80
81 RET 0
82
83 ...
0 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
1 ; RUN: llc -mtriple=x86_64-linux-gnu -global-isel -verify-machineinstrs < %s -o - | FileCheck %s --check-prefix=X64
2
3 define i64 @test_lshr_i64(i64 %arg1, i64 %arg2) {
4 ; X64-LABEL: test_lshr_i64:
5 ; X64: # %bb.0:
6 ; X64-NEXT: movq %rsi, %rcx
7 ; X64-NEXT: # kill: def $cl killed $rcx
8 ; X64-NEXT: shrq %cl, %rdi
9 ; X64-NEXT: movq %rdi, %rax
10 ; X64-NEXT: retq
11 %res = lshr i64 %arg1, %arg2
12 ret i64 %res
13 }
14
15 define i64 @test_lshr_i64_imm(i64 %arg1) {
16 ; X64-LABEL: test_lshr_i64_imm:
17 ; X64: # %bb.0:
18 ; X64-NEXT: movq $5, %rcx
19 ; X64-NEXT: # kill: def $cl killed $rcx
20 ; X64-NEXT: shrq %cl, %rdi
21 ; X64-NEXT: movq %rdi, %rax
22 ; X64-NEXT: retq
23 %res = lshr i64 %arg1, 5
24 ret i64 %res
25 }
26
27 define i64 @test_lshr_i64_imm1(i64 %arg1) {
28 ; X64-LABEL: test_lshr_i64_imm1:
29 ; X64: # %bb.0:
30 ; X64-NEXT: movq $1, %rcx
31 ; X64-NEXT: # kill: def $cl killed $rcx
32 ; X64-NEXT: shrq %cl, %rdi
33 ; X64-NEXT: movq %rdi, %rax
34 ; X64-NEXT: retq
35 %res = lshr i64 %arg1, 1
36 ret i64 %res
37 }
38
39 define i32 @test_lshr_i32(i32 %arg1, i32 %arg2) {
40 ; X64-LABEL: test_lshr_i32:
41 ; X64: # %bb.0:
42 ; X64-NEXT: movl %esi, %ecx
43 ; X64-NEXT: # kill: def $cl killed $ecx
44 ; X64-NEXT: shrl %cl, %edi
45 ; X64-NEXT: movl %edi, %eax
46 ; X64-NEXT: retq
47 %res = lshr i32 %arg1, %arg2
48 ret i32 %res
49 }
50
51 define i32 @test_lshr_i32_imm(i32 %arg1) {
52 ; X64-LABEL: test_lshr_i32_imm:
53 ; X64: # %bb.0:
54 ; X64-NEXT: movl $5, %ecx
55 ; X64-NEXT: # kill: def $cl killed $ecx
56 ; X64-NEXT: shrl %cl, %edi
57 ; X64-NEXT: movl %edi, %eax
58 ; X64-NEXT: retq
59 %res = lshr i32 %arg1, 5
60 ret i32 %res
61 }
62
63 define i32 @test_lshr_i32_imm1(i32 %arg1) {
64 ; X64-LABEL: test_lshr_i32_imm1:
65 ; X64: # %bb.0:
66 ; X64-NEXT: movl $1, %ecx
67 ; X64-NEXT: # kill: def $cl killed $ecx
68 ; X64-NEXT: shrl %cl, %edi
69 ; X64-NEXT: movl %edi, %eax
70 ; X64-NEXT: retq
71 %res = lshr i32 %arg1, 1
72 ret i32 %res
73 }
74
75 define i16 @test_lshr_i16(i32 %arg1, i32 %arg2) {
76 ; X64-LABEL: test_lshr_i16:
77 ; X64: # %bb.0:
78 ; X64-NEXT: movl %esi, %ecx
79 ; X64-NEXT: # kill: def $cl killed $cx
80 ; X64-NEXT: shrw %cl, %di
81 ; X64-NEXT: movl %edi, %eax
82 ; X64-NEXT: retq
83 %a = trunc i32 %arg1 to i16
84 %a2 = trunc i32 %arg2 to i16
85 %res = lshr i16 %a, %a2
86 ret i16 %res
87 }
88
89 define i16 @test_lshr_i16_imm(i32 %arg1) {
90 ; X64-LABEL: test_lshr_i16_imm:
91 ; X64: # %bb.0:
92 ; X64-NEXT: movw $5, %cx
93 ; X64-NEXT: # kill: def $cl killed $cx
94 ; X64-NEXT: shrw %cl, %di
95 ; X64-NEXT: movl %edi, %eax
96 ; X64-NEXT: retq
97 %a = trunc i32 %arg1 to i16
98 %res = lshr i16 %a, 5
99 ret i16 %res
100 }
101
102 define i16 @test_lshr_i16_imm1(i32 %arg1) {
103 ; X64-LABEL: test_lshr_i16_imm1:
104 ; X64: # %bb.0:
105 ; X64-NEXT: movw $1, %cx
106 ; X64-NEXT: # kill: def $cl killed $cx
107 ; X64-NEXT: shrw %cl, %di
108 ; X64-NEXT: movl %edi, %eax
109 ; X64-NEXT: retq
110 %a = trunc i32 %arg1 to i16
111 %res = lshr i16 %a, 1
112 ret i16 %res
113 }
114
115 define i8 @test_lshr_i8(i32 %arg1, i32 %arg2) {
116 ; X64-LABEL: test_lshr_i8:
117 ; X64: # %bb.0:
118 ; X64-NEXT: movl %esi, %ecx
119 ; X64-NEXT: shrb %cl, %dil
120 ; X64-NEXT: movl %edi, %eax
121 ; X64-NEXT: retq
122 %a = trunc i32 %arg1 to i8
123 %a2 = trunc i32 %arg2 to i8
124 %res = lshr i8 %a, %a2
125 ret i8 %res
126 }
127
128 define i8 @test_lshr_i8_imm(i32 %arg1) {
129 ; X64-LABEL: test_lshr_i8_imm:
130 ; X64: # %bb.0:
131 ; X64-NEXT: shrb $5, %dil
132 ; X64-NEXT: movl %edi, %eax
133 ; X64-NEXT: retq
134 %a = trunc i32 %arg1 to i8
135 %res = lshr i8 %a, 5
136 ret i8 %res
137 }
138
139 define i8 @test_lshr_i8_imm1(i32 %arg1) {
140 ; X64-LABEL: test_lshr_i8_imm1:
141 ; X64: # %bb.0:
142 ; X64-NEXT: shrb %dil
143 ; X64-NEXT: movl %edi, %eax
144 ; X64-NEXT: retq
145 %a = trunc i32 %arg1 to i8
146 %res = lshr i8 %a, 1
147 ret i8 %res
148 }
149
150 define i1 @test_lshr_i1(i32 %arg1, i32 %arg2) {
151 ; X64-LABEL: test_lshr_i1:
152 ; X64: # %bb.0:
153 ; X64-NEXT: andb $1, %dil
154 ; X64-NEXT: andb $1, %sil
155 ; X64-NEXT: movl %esi, %ecx
156 ; X64-NEXT: shrb %cl, %dil
157 ; X64-NEXT: movl %edi, %eax
158 ; X64-NEXT: retq
159 %a = trunc i32 %arg1 to i1
160 %a2 = trunc i32 %arg2 to i1
161 %res = lshr i1 %a, %a2
162 ret i1 %res
163 }
164
165 define i1 @test_lshr_i1_imm1(i32 %arg1) {
166 ; X64-LABEL: test_lshr_i1_imm1:
167 ; X64: # %bb.0:
168 ; X64-NEXT: movb $-1, %cl
169 ; X64-NEXT: andb $1, %dil
170 ; X64-NEXT: andb $1, %cl
171 ; X64-NEXT: shrb %cl, %dil
172 ; X64-NEXT: movl %edi, %eax
173 ; X64-NEXT: retq
174 %a = trunc i32 %arg1 to i1
175 %res = lshr i1 %a, 1
176 ret i1 %res
177 }
0 # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
1 # RUN: llc -mtriple=x86_64-linux-gnu -global-isel -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=ALL
2 --- |
3
4 define i64 @test_ashr_i64(i64 %arg1, i64 %arg2) {
5 %res = ashr i64 %arg1, %arg2
6 ret i64 %res
7 }
8
9 define i64 @test_ashr_i64_imm(i64 %arg1) {
10 %res = ashr i64 %arg1, 5
11 ret i64 %res
12 }
13
14 define i64 @test_ashr_i64_imm1(i64 %arg1) {
15 %res = ashr i64 %arg1, 1
16 ret i64 %res
17 }
18
19 define i32 @test_ashr_i32(i32 %arg1, i32 %arg2) {
20 %res = ashr i32 %arg1, %arg2
21 ret i32 %res
22 }
23
24 define i32 @test_ashr_i32_imm(i32 %arg1) {
25 %res = ashr i32 %arg1, 5
26 ret i32 %res
27 }
28
29 define i32 @test_ashr_i32_imm1(i32 %arg1) {
30 %res = ashr i32 %arg1, 1
31 ret i32 %res
32 }
33
34 define i16 @test_ashr_i16(i32 %arg1, i32 %arg2) {
35 %a = trunc i32 %arg1 to i16
36 %a2 = trunc i32 %arg2 to i16
37 %res = ashr i16 %a, %a2
38 ret i16 %res
39 }
40
41 define i16 @test_ashr_i16_imm(i32 %arg1) {
42 %a = trunc i32 %arg1 to i16
43 %res = ashr i16 %a, 5
44 ret i16 %res
45 }
46
47 define i16 @test_ashr_i16_imm1(i32 %arg1) {
48 %a = trunc i32 %arg1 to i16
49 %res = ashr i16 %a, 1
50 ret i16 %res
51 }
52
53 define i8 @test_ashr_i8(i32 %arg1, i32 %arg2) {
54 %a = trunc i32 %arg1 to i8
55 %a2 = trunc i32 %arg2 to i8
56 %res = ashr i8 %a, %a2
57 ret i8 %res
58 }
59
60 define i8 @test_ashr_i8_imm(i32 %arg1) {
61 %a = trunc i32 %arg1 to i8
62 %res = ashr i8 %a, 5
63 ret i8 %res
64 }
65
66 define i8 @test_ashr_i8_imm1(i32 %arg1) {
67 %a = trunc i32 %arg1 to i8
68 %res = ashr i8 %a, 1
69 ret i8 %res
70 }
71 ...
72 ---
73 name: test_ashr_i64
74 alignment: 4
75 legalized: true
76 regBankSelected: true
77 tracksRegLiveness: true
78 registers:
79 - { id: 0, class: gpr, preferred-register: '' }
80 - { id: 1, class: gpr, preferred-register: '' }
81 - { id: 2, class: gpr, preferred-register: '' }
82 liveins:
83 fixedStack:
84 stack:
85 constants:
86 body: |
87 bb.1 (%ir-block.0):
88 liveins: $rdi, $rsi
89
90 ; ALL-LABEL: name: test_ashr_i64
91 ; ALL: liveins: $rdi, $rsi
92 ; ALL: [[COPY:%[0-9]+]]:gr64 = COPY $rdi
93 ; ALL: [[COPY1:%[0-9]+]]:gr64 = COPY $rsi
94 ; ALL: $rcx = COPY [[COPY1]]
95 ; ALL: $cl = KILL killed $rcx
96 ; ALL: [[SAR64rCL:%[0-9]+]]:gr64 = SAR64rCL [[COPY]], implicit-def $eflags, implicit $cl
97 ; ALL: $rax = COPY [[SAR64rCL]]
98 ; ALL: RET 0, implicit $rax
99 %0(s64) = COPY $rdi
100 %1(s64) = COPY $rsi
101 %2(s64) = G_ASHR %0, %1
102 $rax = COPY %2(s64)
103 RET 0, implicit $rax
104
105 ...
106 ---
107 name: test_ashr_i64_imm
108 alignment: 4
109 legalized: true
110 regBankSelected: true
111 tracksRegLiveness: true
112 registers:
113 - { id: 0, class: gpr, preferred-register: '' }
114 - { id: 1, class: gpr, preferred-register: '' }
115 - { id: 2, class: gpr, preferred-register: '' }
116 liveins:
117 fixedStack:
118 stack:
119 constants:
120 body: |
121 bb.1 (%ir-block.0):
122 liveins: $rdi
123
124 ; ALL-LABEL: name: test_ashr_i64_imm
125 ; ALL: liveins: $rdi
126 ; ALL: [[COPY:%[0-9]+]]:gr64 = COPY $rdi
127 ; ALL: [[MOV64ri32_:%[0-9]+]]:gr64 = MOV64ri32 5
128 ; ALL: $rcx = COPY [[MOV64ri32_]]
129 ; ALL: $cl = KILL killed $rcx
130 ; ALL: [[SAR64rCL:%[0-9]+]]:gr64 = SAR64rCL [[COPY]], implicit-def $eflags, implicit $cl
131 ; ALL: $rax = COPY [[SAR64rCL]]
132 ; ALL: RET 0, implicit $rax
133 %0(s64) = COPY $rdi
134 %1(s64) = G_CONSTANT i64 5
135 %2(s64) = G_ASHR %0, %1
136 $rax = COPY %2(s64)
137 RET 0, implicit $rax
138
139 ...
140 ---
141 name: test_ashr_i64_imm1
142 alignment: 4
143 legalized: true
144 regBankSelected: true
145 tracksRegLiveness: true
146 registers:
147 - { id: 0, class: gpr, preferred-register: '' }
148 - { id: 1, class: gpr, preferred-register: '' }
149 - { id: 2, class: gpr, preferred-register: '' }
150 liveins:
151 fixedStack:
152 stack:
153 constants:
154 body: |
155 bb.1 (%ir-block.0):
156 liveins: $rdi
157
158 ; ALL-LABEL: name: test_ashr_i64_imm1
159 ; ALL: liveins: $rdi
160 ; ALL: [[COPY:%[0-9]+]]:gr64 = COPY $rdi
161 ; ALL: [[MOV64ri32_:%[0-9]+]]:gr64 = MOV64ri32 1
162 ; ALL: $rcx = COPY [[MOV64ri32_]]
163 ; ALL: $cl = KILL killed $rcx
164 ; ALL: [[SAR64rCL:%[0-9]+]]:gr64 = SAR64rCL [[COPY]], implicit-def $eflags, implicit $cl
165 ; ALL: $rax = COPY [[SAR64rCL]]
166 ; ALL: RET 0, implicit $rax
167 %0(s64) = COPY $rdi
168 %1(s64) = G_CONSTANT i64 1
169 %2(s64) = G_ASHR %0, %1
170 $rax = COPY %2(s64)
171 RET 0, implicit $rax
172
173 ...
174 ---
175 name: test_ashr_i32
176 alignment: 4
177 legalized: true
178 regBankSelected: true
179 tracksRegLiveness: true
180 registers:
181 - { id: 0, class: gpr, preferred-register: '' }
182 - { id: 1, class: gpr, preferred-register: '' }
183 - { id: 2, class: gpr, preferred-register: '' }
184 liveins:
185 fixedStack:
186 stack:
187 constants:
188 body: |
189 bb.1 (%ir-block.0):
190 liveins: $edi, $esi
191
192 ; ALL-LABEL: name: test_ashr_i32
193 ; ALL: liveins: $edi, $esi
194 ; ALL: [[COPY:%[0-9]+]]:gr32 = COPY $edi
195 ; ALL: [[COPY1:%[0-9]+]]:gr32 = COPY $esi
196 ; ALL: $ecx = COPY [[COPY1]]
197 ; ALL: $cl = KILL killed $ecx
198 ; ALL: [[SAR32rCL:%[0-9]+]]:gr32 = SAR32rCL [[COPY]], implicit-def $eflags, implicit $cl
199 ; ALL: $eax = COPY [[SAR32rCL]]
200 ; ALL: RET 0, implicit $eax
201 %0(s32) = COPY $edi
202 %1(s32) = COPY $esi
203 %2(s32) = G_ASHR %0, %1
204 $eax = COPY %2(s32)
205 RET 0, implicit $eax
206
207 ...
208 ---
209 name: test_ashr_i32_imm
210 alignment: 4
211 legalized: true
212 regBankSelected: true
213 tracksRegLiveness: true
214 registers:
215 - { id: 0, class: gpr, preferred-register: '' }
216 - { id: 1, class: gpr, preferred-register: '' }
217 - { id: 2, class: gpr, preferred-register: '' }
218 liveins:
219 fixedStack:
220 stack:
221 constants:
222 body: |
223 bb.1 (%ir-block.0):
224 liveins: $edi
225
226 ; ALL-LABEL: name: test_ashr_i32_imm
227 ; ALL: liveins: $edi
228 ; ALL: [[COPY:%[0-9]+]]:gr32 = COPY $edi
229 ; ALL: [[MOV32ri:%[0-9]+]]:gr32 = MOV32ri 5
230 ; ALL: $ecx = COPY [[MOV32ri]]
231 ; ALL: $cl = KILL killed $ecx
232 ; ALL: [[SAR32rCL:%[0-9]+]]:gr32 = SAR32rCL [[COPY]], implicit-def $eflags, implicit $cl
233 ; ALL: $eax = COPY [[SAR32rCL]]
234 ; ALL: RET 0, implicit $eax
235 %0(s32) = COPY $edi
236 %1(s32) = G_CONSTANT i32 5
237 %2(s32) = G_ASHR %0, %1
238 $eax = COPY %2(s32)
239 RET 0, implicit $eax
240
241 ...
242 ---
243 name: test_ashr_i32_imm1
244 alignment: 4
245 legalized: true
246 regBankSelected: true
247 tracksRegLiveness: true
248 registers:
249 - { id: 0, class: gpr, preferred-register: '' }
250 - { id: 1, class: gpr, preferred-register: '' }
251 - { id: 2, class: gpr, preferred-register: '' }
252 liveins:
253 fixedStack:
254 stack:
255 constants:
256 body: |
257 bb.1 (%ir-block.0):
258 liveins: $edi
259
260 ; ALL-LABEL: name: test_ashr_i32_imm1
261 ; ALL: liveins: $edi
262 ; ALL: [[COPY:%[0-9]+]]:gr32 = COPY $edi
263 ; ALL: [[MOV32ri:%[0-9]+]]:gr32 = MOV32ri 1
264 ; ALL: $ecx = COPY [[MOV32ri]]
265 ; ALL: $cl = KILL killed $ecx
266 ; ALL: [[SAR32rCL:%[0-9]+]]:gr32 = SAR32rCL [[COPY]], implicit-def $eflags, implicit $cl
267 ; ALL: $eax = COPY [[SAR32rCL]]
268 ; ALL: RET 0, implicit $eax
269 %0(s32) = COPY $edi
270 %1(s32) = G_CONSTANT i32 1
271 %2(s32) = G_ASHR %0, %1
272 $eax = COPY %2(s32)
273 RET 0, implicit $eax
274
275 ...
276 ---
277 name: test_ashr_i16
278 alignment: 4
279 legalized: true
280 regBankSelected: true
281 tracksRegLiveness: true
282 registers:
283 - { id: 0, class: gpr, preferred-register: '' }
284 - { id: 1, class: gpr, preferred-register: '' }
285 - { id: 2, class: gpr, preferred-register: '' }
286 - { id: 3, class: gpr, preferred-register: '' }
287 - { id: 4, class: gpr, preferred-register: '' }
288 liveins:
289 fixedStack:
290 stack:
291 constants:
292 body: |
293 bb.1 (%ir-block.0):
294 liveins: $edi, $esi
295
296 ; ALL-LABEL: name: test_ashr_i16
297 ; ALL: liveins: $edi, $esi
298 ; ALL: [[COPY:%[0-9]+]]:gr32 = COPY $edi
299 ; ALL: [[COPY1:%[0-9]+]]:gr32 = COPY $esi
300 ; ALL: [[COPY2:%[0-9]+]]:gr16 = COPY [[COPY]].sub_16bit
301 ; ALL: [[COPY3:%[0-9]+]]:gr16 = COPY [[COPY1]].sub_16bit
302 ; ALL: $cx = COPY [[COPY3]]
303 ; ALL: $cl = KILL killed $cx
304 ; ALL: [[SAR16rCL:%[0-9]+]]:gr16 = SAR16rCL [[COPY2]], implicit-def $eflags, implicit $cl
305 ; ALL: $ax = COPY [[SAR16rCL]]
306 ; ALL: RET 0, implicit $ax
307 %0(s32) = COPY $edi
308 %1(s32) = COPY $esi
309 %2(s16) = G_TRUNC %0(s32)
310 %3(s16) = G_TRUNC %1(s32)
311 %4(s16) = G_ASHR %2, %3
312 $ax = COPY %4(s16)
313 RET 0, implicit $ax
314
315 ...
316 ---
317 name: test_ashr_i16_imm
318 alignment: 4
319 legalized: true
320 regBankSelected: true
321 tracksRegLiveness: true
322 registers:
323 - { id: 0, class: gpr, preferred-register: '' }
324 - { id: 1, class: gpr, preferred-register: '' }
325 - { id: 2, class: gpr, preferred-register: '' }
326 - { id: 3, class: gpr, preferred-register: '' }
327 liveins:
328 fixedStack:
329 stack:
330 constants:
331 body: |
332 bb.1 (%ir-block.0):
333 liveins: $edi
334
335 ; ALL-LABEL: name: test_ashr_i16_imm
336 ; ALL: liveins: $edi
337 ; ALL: [[COPY:%[0-9]+]]:gr32 = COPY $edi
338 ; ALL: [[MOV16ri:%[0-9]+]]:gr16 = MOV16ri 5
339 ; ALL: [[COPY1:%[0-9]+]]:gr16 = COPY [[COPY]].sub_16bit
340 ; ALL: $cx = COPY [[MOV16ri]]
341 ; ALL: $cl = KILL killed $cx
342 ; ALL: [[SAR16rCL:%[0-9]+]]:gr16 = SAR16rCL [[COPY1]], implicit-def $eflags, implicit $cl
343 ; ALL: $ax = COPY [[SAR16rCL]]
344 ; ALL: RET 0, implicit $ax
345 %0(s32) = COPY $edi
346 %2(s16) = G_CONSTANT i16 5
347 %1(s16) = G_TRUNC %0(s32)
348 %3(s16) = G_ASHR %1, %2
349 $ax = COPY %3(s16)
350 RET 0, implicit $ax
351
352 ...
353 ---
354 name: test_ashr_i16_imm1
355 alignment: 4
356 legalized: true
357 regBankSelected: true
358 tracksRegLiveness: true
359 registers:
360 - { id: 0, class: gpr, preferred-register: '' }
361 - { id: 1, class: gpr, preferred-register: '' }
362 - { id: 2, class: gpr, preferred-register: '' }
363 - { id: 3, class: gpr, preferred-register: '' }
364 liveins:
365 fixedStack:
366 stack:
367 constants:
368 body: |
369 bb.1 (%ir-block.0):
370 liveins: $edi
371
372 ; ALL-LABEL: name: test_ashr_i16_imm1
373 ; ALL: liveins: $edi
374 ; ALL: [[COPY:%[0-9]+]]:gr32 = COPY $edi
375 ; ALL: [[MOV16ri:%[0-9]+]]:gr16 = MOV16ri 1
376 ; ALL: [[COPY1:%[0-9]+]]:gr16 = COPY [[COPY]].sub_16bit
377 ; ALL: $cx = COPY [[MOV16ri]]
378 ; ALL: $cl = KILL killed $cx
379 ; ALL: [[SAR16rCL:%[0-9]+]]:gr16 = SAR16rCL [[COPY1]], implicit-def $eflags, implicit $cl
380 ; ALL: $ax = COPY [[SAR16rCL]]
381 ; ALL: RET 0, implicit $ax
382 %0(s32) = COPY $edi
383 %2(s16) = G_CONSTANT i16 1
384 %1(s16) = G_TRUNC %0(s32)
385 %3(s16) = G_ASHR %1, %2
386 $ax = COPY %3(s16)
387 RET 0, implicit $ax
388
389 ...
390 ---
391 name: test_ashr_i8
392 alignment: 4
393 legalized: true
394 regBankSelected: true
395 tracksRegLiveness: true
396 registers:
397 - { id: 0, class: gpr, preferred-register: '' }
398 - { id: 1, class: gpr, preferred-register: '' }
399 - { id: 2, class: gpr, preferred-register: '' }
400 - { id: 3, class: gpr, preferred-register: '' }
401 - { id: 4, class: gpr, preferred-register: '' }
402 liveins:
403 fixedStack:
404 stack:
405 constants:
406 body: |
407 bb.1 (%ir-block.0):
408 liveins: $edi, $esi
409
410 ; ALL-LABEL: name: test_ashr_i8
411 ; ALL: liveins: $edi, $esi
412 ; ALL: [[COPY:%[0-9]+]]:gr32 = COPY $edi
413 ; ALL: [[COPY1:%[0-9]+]]:gr32 = COPY $esi
414 ; ALL: [[COPY2:%[0-9]+]]:gr8 = COPY [[COPY]].sub_8bit
415 ; ALL: [[COPY3:%[0-9]+]]:gr8 = COPY [[COPY1]].sub_8bit
416 ; ALL: $cl = COPY [[COPY3]]
417 ; ALL: [[SAR8rCL:%[0-9]+]]:gr8 = SAR8rCL [[COPY2]], implicit-def $eflags, implicit $cl
418 ; ALL: $al = COPY [[SAR8rCL]]
419 ; ALL: RET 0, implicit $al
420 %0(s32) = COPY $edi
421 %1(s32) = COPY $esi
422 %2(s8) = G_TRUNC %0(s32)
423 %3(s8) = G_TRUNC %1(s32)
424 %4(s8) = G_ASHR %2, %3
425 $al = COPY %4(s8)
426 RET 0, implicit $al
427
428 ...
429 ---
430 name: test_ashr_i8_imm
431 alignment: 4
432 legalized: true
433 regBankSelected: true
434 tracksRegLiveness: true
435 registers:
436 - { id: 0, class: gpr, preferred-register: '' }
437 - { id: 1, class: gpr, preferred-register: '' }
438 - { id: 2, class: gpr, preferred-register: '' }
439 - { id: 3, class: gpr, preferred-register: '' }
440 liveins:
441 fixedStack:
442 stack:
443 constants:
444 body: |
445 bb.1 (%ir-block.0):
446 liveins: $edi
447
448 ; ALL-LABEL: name: test_ashr_i8_imm
449 ; ALL: liveins: $edi
450 ; ALL: [[COPY:%[0-9]+]]:gr32 = COPY $edi
451 ; ALL: [[COPY1:%[0-9]+]]:gr8 = COPY [[COPY]].sub_8bit
452 ; ALL: [[SAR8ri:%[0-9]+]]:gr8 = SAR8ri [[COPY1]], 5, implicit-def $eflags
453 ; ALL: $al = COPY [[SAR8ri]]
454 ; ALL: RET 0, implicit $al
455 %0(s32) = COPY $edi
456 %2(s8) = G_CONSTANT i8 5
457 %1(s8) = G_TRUNC %0(s32)
458 %3(s8) = G_ASHR %1, %2
459 $al = COPY %3(s8)
460 RET 0, implicit $al
461
462 ...
463 ---
464 name: test_ashr_i8_imm1
465 alignment: 4
466 legalized: true
467 regBankSelected: true
468 tracksRegLiveness: true
469 registers:
470 - { id: 0, class: gpr, preferred-register: '' }
471 - { id: 1, class: gpr, preferred-register: '' }
472 - { id: 2, class: gpr, preferred-register: '' }
473 - { id: 3, class: gpr, preferred-register: '' }
474 liveins:
475 fixedStack:
476 stack:
477 constants:
478 body: |
479 bb.1 (%ir-block.0):
480 liveins: $edi
481
482 ; ALL-LABEL: name: test_ashr_i8_imm1
483 ; ALL: liveins: $edi
484 ; ALL: [[COPY:%[0-9]+]]:gr32 = COPY $edi
485 ; ALL: [[COPY1:%[0-9]+]]:gr8 = COPY [[COPY]].sub_8bit
486 ; ALL: [[SAR8r1_:%[0-9]+]]:gr8 = SAR8r1 [[COPY1]], implicit-def $eflags
487 ; ALL: $al = COPY [[SAR8r1_]]
488 ; ALL: RET 0, implicit $al
489 %0(s32) = COPY $edi
490 %2(s8) = G_CONSTANT i8 1
491 %1(s8) = G_TRUNC %0(s32)
492 %3(s8) = G_ASHR %1, %2
493 $al = COPY %3(s8)
494 RET 0, implicit $al
495
496 ...
0 # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
1 # RUN: llc -mtriple=x86_64-linux-gnu -global-isel -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=ALL
2 --- |
3
4 define i64 @test_lshr_i64(i64 %arg1, i64 %arg2) {
5 %res = lshr i64 %arg1, %arg2
6 ret i64 %res
7 }
8
9 define i64 @test_lshr_i64_imm(i64 %arg1) {
10 %res = lshr i64 %arg1, 5
11 ret i64 %res
12 }
13
14 define i64 @test_lshr_i64_imm1(i64 %arg1) {
15 %res = lshr i64 %arg1, 1
16 ret i64 %res
17 }
18
19 define i32 @test_lshr_i32(i32 %arg1, i32 %arg2) {
20 %res = lshr i32 %arg1, %arg2
21 ret i32 %res
22 }
23
24 define i32 @test_lshr_i32_imm(i32 %arg1) {
25 %res = lshr i32 %arg1, 5
26 ret i32 %res
27 }
28
29 define i32 @test_lshr_i32_imm1(i32 %arg1) {
30 %res = lshr i32 %arg1, 1
31 ret i32 %res
32 }
33
34 define i16 @test_lshr_i16(i32 %arg1, i32 %arg2) {
35 %a = trunc i32 %arg1 to i16
36 %a2 = trunc i32 %arg2 to i16
37 %res = lshr i16 %a, %a2
38 ret i16 %res
39 }
40
41 define i16 @test_lshr_i16_imm(i32 %arg1) {
42 %a = trunc i32 %arg1 to i16
43 %res = lshr i16 %a, 5
44 ret i16 %res
45 }
46
47 define i16 @test_lshr_i16_imm1(i32 %arg1) {
48 %a = trunc i32 %arg1 to i16
49 %res = lshr i16 %a, 1
50 ret i16 %res
51 }
52
53 define i8 @test_lshr_i8(i32 %arg1, i32 %arg2) {
54 %a = trunc i32 %arg1 to i8
55 %a2 = trunc i32 %arg2 to i8
56 %res = lshr i8 %a, %a2
57 ret i8 %res
58 }
59
60 define i8 @test_lshr_i8_imm(i32 %arg1) {
61 %a = trunc i32 %arg1 to i8
62 %res = lshr i8 %a, 5
63 ret i8 %res
64 }
65
66 define i8 @test_lshr_i8_imm1(i32 %arg1) {
67 %a = trunc i32 %arg1 to i8
68 %res = lshr i8 %a, 1
69 ret i8 %res
70 }
71 ...
72 ---
73 name: test_lshr_i64
74 alignment: 4
75 legalized: true
76 regBankSelected: true
77 tracksRegLiveness: true
78 registers:
79 - { id: 0, class: gpr, preferred-register: '' }
80 - { id: 1, class: gpr, preferred-register: '' }
81 - { id: 2, class: gpr, preferred-register: '' }
82 liveins:
83 fixedStack:
84 stack:
85 constants:
86 body: |
87 bb.1 (%ir-block.0):
88 liveins: $rdi, $rsi
89
90 ; ALL-LABEL: name: test_lshr_i64
91 ; ALL: liveins: $rdi, $rsi
92 ; ALL: [[COPY:%[0-9]+]]:gr64 = COPY $rdi
93 ; ALL: [[COPY1:%[0-9]+]]:gr64 = COPY $rsi
94 ; ALL: $rcx = COPY [[COPY1]]
95 ; ALL: $cl = KILL killed $rcx
96 ; ALL: [[SHR64rCL:%[0-9]+]]:gr64 = SHR64rCL [[COPY]], implicit-def $eflags, implicit $cl
97 ; ALL: $rax = COPY [[SHR64rCL]]
98 ; ALL: RET 0, implicit $rax
99 %0(s64) = COPY $rdi
100 %1(s64) = COPY $rsi
101 %2(s64) = G_LSHR %0, %1
102 $rax = COPY %2(s64)
103 RET 0, implicit $rax
104
105 ...
106 ---
107 name: test_lshr_i64_imm
108 alignment: 4
109 legalized: true
110 regBankSelected: true
111 tracksRegLiveness: true
112 registers:
113 - { id: 0, class: gpr, preferred-register: '' }
114 - { id: 1, class: gpr, preferred-register: '' }
115 - { id: 2, class: gpr, preferred-register: '' }
116 liveins:
117 fixedStack:
118 stack:
119 constants:
120 body: |
121 bb.1 (%ir-block.0):
122 liveins: $rdi
123
124 ; ALL-LABEL: name: test_lshr_i64_imm
125 ; ALL: liveins: $rdi
126 ; ALL: [[COPY:%[0-9]+]]:gr64 = COPY $rdi
127 ; ALL: [[MOV64ri32_:%[0-9]+]]:gr64 = MOV64ri32 5
128 ; ALL: $rcx = COPY [[MOV64ri32_]]
129 ; ALL: $cl = KILL killed $rcx
130 ; ALL: [[SHR64rCL:%[0-9]+]]:gr64 = SHR64rCL [[COPY]], implicit-def $eflags, implicit $cl
131 ; ALL: $rax = COPY [[SHR64rCL]]
132 ; ALL: RET 0, implicit $rax
133 %0(s64) = COPY $rdi
134 %1(s64) = G_CONSTANT i64 5
135 %2(s64) = G_LSHR %0, %1
136 $rax = COPY %2(s64)
137 RET 0, implicit $rax
138
139 ...
140 ---
141 name: test_lshr_i64_imm1
142 alignment: 4
143 legalized: true
144 regBankSelected: true
145 tracksRegLiveness: true
146 registers:
147 - { id: 0, class: gpr, preferred-register: '' }
148 - { id: 1, class: gpr, preferred-register: '' }
149 - { id: 2, class: gpr, preferred-register: '' }
150 liveins:
151 fixedStack:
152 stack:
153 constants:
154 body: |
155 bb.1 (%ir-block.0):
156 liveins: $rdi
157
158 ; ALL-LABEL: name: test_lshr_i64_imm1
159 ; ALL: liveins: $rdi
160 ; ALL: [[COPY:%[0-9]+]]:gr64 = COPY $rdi
161 ; ALL: [[MOV64ri32_:%[0-9]+]]:gr64 = MOV64ri32 1
162 ; ALL: $rcx = COPY [[MOV64ri32_]]
163 ; ALL: $cl = KILL killed $rcx
164 ; ALL: [[SHR64rCL:%[0-9]+]]:gr64 = SHR64rCL [[COPY]], implicit-def $eflags, implicit $cl
165 ; ALL: $rax = COPY [[SHR64rCL]]
166 ; ALL: RET 0, implicit $rax
167 %0(s64) = COPY $rdi
168 %1(s64) = G_CONSTANT i64 1
169 %2(s64) = G_LSHR %0, %1
170 $rax = COPY %2(s64)
171 RET 0, implicit $rax
172
173 ...
174 ---
175 name: test_lshr_i32
176 alignment: 4
177 legalized: true
178 regBankSelected: true
179 tracksRegLiveness: true
180 registers:
181 - { id: 0, class: gpr, preferred-register: '' }
182 - { id: 1, class: gpr, preferred-register: '' }
183 - { id: 2, class: gpr, preferred-register: '' }
184 liveins:
185 fixedStack:
186 stack:
187 constants:
188 body: |
189 bb.1 (%ir-block.0):
190 liveins: $edi, $esi
191
192 ; ALL-LABEL: name: test_lshr_i32
193 ; ALL: liveins: $edi, $esi
194 ; ALL: [[COPY:%[0-9]+]]:gr32 = COPY $edi
195 ; ALL: [[COPY1:%[0-9]+]]:gr32 = COPY $esi
196 ; ALL: $ecx = COPY [[COPY1]]
197 ; ALL: $cl = KILL killed $ecx
198 ; ALL: [[SHR32rCL:%[0-9]+]]:gr32 = SHR32rCL [[COPY]], implicit-def $eflags, implicit $cl
199 ; ALL: $eax = COPY [[SHR32rCL]]
200 ; ALL: RET 0, implicit $eax
201 %0(s32) = COPY $edi
202 %1(s32) = COPY $esi
203 %2(s32) = G_LSHR %0, %1
204 $eax = COPY %2(s32)
205 RET 0, implicit $eax
206
207 ...
208 ---
209 name: test_lshr_i32_imm
210 alignment: 4
211 legalized: true
212 regBankSelected: true
213 tracksRegLiveness: true
214 registers:
215 - { id: 0, class: gpr, preferred-register: '' }
216 - { id: 1, class: gpr, preferred-register: '' }
217 - { id: 2, class: gpr, preferred-register: '' }
218 liveins:
219 fixedStack:
220 stack:
221 constants:
222 body: |
223 bb.1 (%ir-block.0):
224 liveins: $edi
225
226 ; ALL-LABEL: name: test_lshr_i32_imm
227 ; ALL: liveins: $edi
228 ; ALL: [[COPY:%[0-9]+]]:gr32 = COPY $edi
229 ; ALL: [[MOV32ri:%[0-9]+]]:gr32 = MOV32ri 5
230 ; ALL: $ecx = COPY [[MOV32ri]]
231 ; ALL: $cl = KILL killed $ecx
232 ; ALL: [[SHR32rCL:%[0-9]+]]:gr32 = SHR32rCL [[COPY]], implicit-def $eflags, implicit $cl
233 ; ALL: $eax = COPY [[SHR32rCL]]
234 ; ALL: RET 0, implicit $eax
235 %0(s32) = COPY $edi
236 %1(s32) = G_CONSTANT i32 5
237 %2(s32) = G_LSHR %0, %1
238 $eax = COPY %2(s32)
239 RET 0, implicit $eax
240
241 ...
242 ---
243 name: test_lshr_i32_imm1
244 alignment: 4
245 legalized: true
246 regBankSelected: true
247 tracksRegLiveness: true
248 registers:
249 - { id: 0, class: gpr, preferred-register: '' }
250 - { id: 1, class: gpr, preferred-register: '' }
251 - { id: 2, class: gpr, preferred-register: '' }
252 liveins:
253 fixedStack:
254 stack:
255 constants:
256 body: |
257 bb.1 (%ir-block.0):
258 liveins: $edi
259
260 ; ALL-LABEL: name: test_lshr_i32_imm1
261 ; ALL: liveins: $edi
262 ; ALL: [[COPY:%[0-9]+]]:gr32 = COPY $edi
263 ; ALL: [[MOV32ri:%[0-9]+]]:gr32 = MOV32ri 1
264 ; ALL: $ecx = COPY [[MOV32ri]]
265 ; ALL: $cl = KILL killed $ecx
266 ; ALL: [[SHR32rCL:%[0-9]+]]:gr32 = SHR32rCL [[COPY]], implicit-def $eflags, implicit $cl
267 ; ALL: $eax = COPY [[SHR32rCL]]
268 ; ALL: RET 0, implicit $eax
269 %0(s32) = COPY $edi
270 %1(s32) = G_CONSTANT i32 1
271 %2(s32) = G_LSHR %0, %1
272 $eax = COPY %2(s32)
273 RET 0, implicit $eax
274
275 ...
276 ---
277 name: test_lshr_i16
278 alignment: 4
279 legalized: true
280 regBankSelected: true
281 tracksRegLiveness: true
282 registers:
283 - { id: 0, class: gpr, preferred-register: '' }
284 - { id: 1, class: gpr, preferred-register: '' }
285 - { id: 2, class: gpr, preferred-register: '' }
286 - { id: 3, class: gpr, preferred-register: '' }
287 - { id: 4, class: gpr, preferred-register: '' }
288 liveins:
289 fixedStack:
290 stack:
291 constants:
292 body: |
293 bb.1 (%ir-block.0):
294 liveins: $edi, $esi
295
296 ; ALL-LABEL: name: test_lshr_i16
297 ; ALL: liveins: $edi, $esi
298 ; ALL: [[COPY:%[0-9]+]]:gr32 = COPY $edi
299 ; ALL: [[COPY1:%[0-9]+]]:gr32 = COPY $esi
300 ; ALL: [[COPY2:%[0-9]+]]:gr16 = COPY [[COPY]].sub_16bit
301 ; ALL: [[COPY3:%[0-9]+]]:gr16 = COPY [[COPY1]].sub_16bit
302 ; ALL: $cx = COPY [[COPY3]]
303 ; ALL: $cl = KILL killed $cx
304 ; ALL: [[SHR16rCL:%[0-9]+]]:gr16 = SHR16rCL [[COPY2]], implicit-def $eflags, implicit $cl
305 ; ALL: $ax = COPY [[SHR16rCL]]
306 ; ALL: RET 0, implicit $ax
307 %0(s32) = COPY $edi
308 %1(s32) = COPY $esi
309 %2(s16) = G_TRUNC %0(s32)
310 %3(s16) = G_TRUNC %1(s32)
311 %4(s16) = G_LSHR %2, %3
312 $ax = COPY %4(s16)
313 RET 0, implicit $ax
314
315 ...
316 ---
317 name: test_lshr_i16_imm
318 alignment: 4
319 legalized: true
320 regBankSelected: true
321 tracksRegLiveness: true
322 registers:
323 - { id: 0, class: gpr, preferred-register: '' }
324 - { id: 1, class: gpr, preferred-register: '' }
325 - { id: 2, class: gpr, preferred-register: '' }
326 - { id: 3, class: gpr, preferred-register: '' }
327 liveins:
328 fixedStack:
329 stack:
330 constants:
331 body: |
332 bb.1 (%ir-block.0):
333 liveins: $edi
334
335 ; ALL-LABEL: name: test_lshr_i16_imm
336 ; ALL: liveins: $edi
337 ; ALL: [[COPY:%[0-9]+]]:gr32 = COPY $edi
338 ; ALL: [[MOV16ri:%[0-9]+]]:gr16 = MOV16ri 5
339 ; ALL: [[COPY1:%[0-9]+]]:gr16 = COPY [[COPY]].sub_16bit
340 ; ALL: $cx = COPY [[MOV16ri]]
341 ; ALL: $cl = KILL killed $cx
342 ; ALL: [[SHR16rCL:%[0-9]+]]:gr16 = SHR16rCL [[COPY1]], implicit-def $eflags, implicit $cl
343 ; ALL: $ax = COPY [[SHR16rCL]]
344 ; ALL: RET 0, implicit $ax
345 %0(s32) = COPY $edi
346 %2(s16) = G_CONSTANT i16 5
347 %1(s16) = G_TRUNC %0(s32)
348 %3(s16) = G_LSHR %1, %2
349 $ax = COPY %3(s16)
350 RET 0, implicit $ax
351
352 ...
353 ---
354 name: test_lshr_i16_imm1
355 alignment: 4
356 legalized: true
357 regBankSelected: true
358 tracksRegLiveness: true
359 registers:
360 - { id: 0, class: gpr, preferred-register: '' }
361 - { id: 1, class: gpr, preferred-register: '' }
362 - { id: 2, class: gpr, preferred-register: '' }
363 - { id: 3, class: gpr, preferred-register: '' }
364 liveins:
365 fixedStack:
366 stack:
367 constants:
368 body: |
369 bb.1 (%ir-block.0):
370 liveins: $edi
371
372 ; ALL-LABEL: name: test_lshr_i16_imm1
373 ; ALL: liveins: $edi
374 ; ALL: [[COPY:%[0-9]+]]:gr32 = COPY $edi
375 ; ALL: [[MOV16ri:%[0-9]+]]:gr16 = MOV16ri 1
376 ; ALL: [[COPY1:%[0-9]+]]:gr16 = COPY [[COPY]].sub_16bit
377 ; ALL: $cx = COPY [[MOV16ri]]
378 ; ALL: $cl = KILL killed $cx
379 ; ALL: [[SHR16rCL:%[0-9]+]]:gr16 = SHR16rCL [[COPY1]], implicit-def $eflags, implicit $cl
380 ; ALL: $ax = COPY [[SHR16rCL]]
381 ; ALL: RET 0, implicit $ax
382 %0(s32) = COPY $edi
383 %2(s16) = G_CONSTANT i16 1
384 %1(s16) = G_TRUNC %0(s32)
385 %3(s16) = G_LSHR %1, %2
386 $ax = COPY %3(s16)
387 RET 0, implicit $ax
388
389 ...
390 ---
391 name: test_lshr_i8
392 alignment: 4
393 legalized: true
394 regBankSelected: true
395 tracksRegLiveness: true
396 registers:
397 - { id: 0, class: gpr, preferred-register: '' }
398 - { id: 1, class: gpr, preferred-register: '' }
399 - { id: 2, class: gpr, preferred-register: '' }
400 - { id: 3, class: gpr, preferred-register: '' }
401 - { id: 4, class: gpr, preferred-register: '' }
402 liveins:
403 fixedStack:
404 stack:
405 constants:
406 body: |
407 bb.1 (%ir-block.0):
408 liveins: $edi, $esi
409
410 ; ALL-LABEL: name: test_lshr_i8
411 ; ALL: liveins: $edi, $esi
412 ; ALL: [[COPY:%[0-9]+]]:gr32 = COPY $edi
413 ; ALL: [[COPY1:%[0-9]+]]:gr32 = COPY $esi
414 ; ALL: [[COPY2:%[0-9]+]]:gr8 = COPY [[COPY]].sub_8bit
415 ; ALL: [[COPY3:%[0-9]+]]:gr8 = COPY [[COPY1]].sub_8bit
416 ; ALL: $cl = COPY [[COPY3]]
417 ; ALL: [[SHR8rCL:%[0-9]+]]:gr8 = SHR8rCL [[COPY2]], implicit-def $eflags, implicit $cl
418 ; ALL: $al = COPY [[SHR8rCL]]
419 ; ALL: RET 0, implicit $al
420 %0(s32) = COPY $edi
421 %1(s32) = COPY $esi
422 %2(s8) = G_TRUNC %0(s32)
423 %3(s8) = G_TRUNC %1(s32)
424 %4(s8) = G_LSHR %2, %3
425 $al = COPY %4(s8)
426 RET 0, implicit $al
427
428 ...
429 ---
430 name: test_lshr_i8_imm
431 alignment: 4
432 legalized: true
433 regBankSelected: true
434 tracksRegLiveness: true
435 registers:
436 - { id: 0, class: gpr, preferred-register: '' }
437 - { id: 1, class: gpr, preferred-register: '' }
438 - { id: 2, class: gpr, preferred-register: '' }
439 - { id: 3, class: gpr, preferred-register: '' }
440 liveins:
441 fixedStack:
442 stack:
443 constants:
444 body: |
445 bb.1 (%ir-block.0):
446 liveins: $edi
447
448 ; ALL-LABEL: name: test_lshr_i8_imm
449 ; ALL: liveins: $edi
450 ; ALL: [[COPY:%[0-9]+]]:gr32 = COPY $edi
451 ; ALL: [[COPY1:%[0-9]+]]:gr8 = COPY [[COPY]].sub_8bit
452 ; ALL: [[SHR8ri:%[0-9]+]]:gr8 = SHR8ri [[COPY1]], 5, implicit-def $eflags
453 ; ALL: $al = COPY [[SHR8ri]]
454 ; ALL: RET 0, implicit $al
455 %0(s32) = COPY $edi
456 %2(s8) = G_CONSTANT i8 5
457 %1(s8) = G_TRUNC %0(s32)
458 %3(s8) = G_LSHR %1, %2
459 $al = COPY %3(s8)
460 RET 0, implicit $al
461
462 ...
463 ---
464 name: test_lshr_i8_imm1
465 alignment: 4
466 legalized: true
467 regBankSelected: true
468 tracksRegLiveness: true
469 registers:
470 - { id: 0, class: gpr, preferred-register: '' }
471 - { id: 1, class: gpr, preferred-register: '' }
472 - { id: 2, class: gpr, preferred-register: '' }
473 - { id: 3, class: gpr, preferred-register: '' }
474 liveins:
475 fixedStack:
476 stack:
477 constants:
478 body: |
479 bb.1 (%ir-block.0):
480 liveins: $edi
481
482 ; ALL-LABEL: name: test_lshr_i8_imm1
483 ; ALL: liveins: $edi
484 ; ALL: [[COPY:%[0-9]+]]:gr32 = COPY $edi
485 ; ALL: [[COPY1:%[0-9]+]]:gr8 = COPY [[COPY]].sub_8bit
486 ; ALL: [[SHR8r1_:%[0-9]+]]:gr8 = SHR8r1 [[COPY1]], implicit-def $eflags
487 ; ALL: $al = COPY [[SHR8r1_]]
488 ; ALL: RET 0, implicit $al
489 %0(s32) = COPY $edi
490 %2(s8) = G_CONSTANT i8 1
491 %1(s8) = G_TRUNC %0(s32)
492 %3(s8) = G_LSHR %1, %2
493 $al = COPY %3(s8)
494 RET 0, implicit $al
495
496 ...
0 # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
1 # RUN: llc -mtriple=x86_64-linux-gnu -global-isel -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=ALL
2 --- |
3
4 define i64 @test_shl_i64(i64 %arg1, i64 %arg2) {
5 %res = shl i64 %arg1, %arg2
6 ret i64 %res
7 }
8
9 define i64 @test_shl_i64_imm(i64 %arg1) {
10 %res = shl i64 %arg1, 5
11 ret i64 %res
12 }
13
14 define i64 @test_shl_i64_imm1(i64 %arg1) {
15 %res = shl i64 %arg1, 1
16 ret i64 %res
17 }
18
19 define i32 @test_shl_i32(i32 %arg1, i32 %arg2) {
20 %res = shl i32 %arg1, %arg2
21 ret i32 %res
22 }
23
24 define i32 @test_shl_i32_imm(i32 %arg1) {
25 %res = shl i32 %arg1, 5
26 ret i32 %res
27 }
28
29 define i32 @test_shl_i32_imm1(i32 %arg1) {
30 %res = shl i32 %arg1, 1
31 ret i32 %res
32 }
33
34 define i16 @test_shl_i16(i32 %arg1, i32 %arg2) {
35 %a = trunc i32 %arg1 to i16
36 %a2 = trunc i32 %arg2 to i16
37 %res = shl i16 %a, %a2
38 ret i16 %res
39 }
40
41 define i16 @test_shl_i16_imm(i32 %arg1) {
42 %a = trunc i32 %arg1 to i16
43 %res = shl i16 %a, 5
44 ret i16 %res
45 }
46
47 define i16 @test_shl_i16_imm1(i32 %arg1) {
48 %a = trunc i32 %arg1 to i16
49 %res = shl i16 %a, 1
50 ret i16 %res
51 }
52
53 define i8 @test_shl_i8(i32 %arg1, i32 %arg2) {
54 %a = trunc i32 %arg1 to i8
55 %a2 = trunc i32 %arg2 to i8
56 %res = shl i8 %a, %a2
57 ret i8 %res
58 }
59
60 define i8 @test_shl_i8_imm(i32 %arg1) {
61 %a = trunc i32 %arg1 to i8
62 %res = shl i8 %a, 5
63 ret i8 %res
64 }
65
66 define i8 @test_shl_i8_imm1(i32 %arg1) {
67 %a = trunc i32 %arg1 to i8
68 %res = shl i8 %a, 1
69 ret i8 %res
70 }
71
72 ...
73 ---
74 name: test_shl_i64
75 alignment: 4
76 legalized: true
77 regBankSelected: true
78 tracksRegLiveness: true
79 registers:
80 - { id: 0, class: gpr, preferred-register: '' }
81 - { id: 1, class: gpr, preferred-register: '' }
82 - { id: 2, class: gpr, preferred-register: '' }
83 liveins:
84 fixedStack:
85 stack:
86 constants:
87 body: |
88 bb.1 (%ir-block.0):
89 liveins: $rdi, $rsi
90
91 ; ALL-LABEL: name: test_shl_i64
92 ; ALL: liveins: $rdi, $rsi
93 ; ALL: [[COPY:%[0-9]+]]:gr64 = COPY $rdi
94 ; ALL: [[COPY1:%[0-9]+]]:gr64 = COPY $rsi
95 ; ALL: $rcx = COPY [[COPY1]]
96 ; ALL: $cl = KILL killed $rcx
97 ; ALL: [[SHL64rCL:%[0-9]+]]:gr64 = SHL64rCL [[COPY]], implicit-def $eflags, implicit $cl
98 ; ALL: $rax = COPY [[SHL64rCL]]
99 ; ALL: RET 0, implicit $rax
100 %0(s64) = COPY $rdi
101 %1(s64) = COPY $rsi
102 %2(s64) = G_SHL %0, %1
103 $rax = COPY %2(s64)
104 RET 0, implicit $rax
105
106 ...
107 ---
108 name: test_shl_i64_imm
109 alignment: 4
110 legalized: true
111 regBankSelected: true
112 tracksRegLiveness: true
113 registers:
114 - { id: 0, class: gpr, preferred-register: '' }
115 - { id: 1, class: gpr, preferred-register: '' }
116 - { id: 2, class: gpr, preferred-register: '' }
117 liveins:
118 fixedStack:
119 stack:
120 constants:
121 body: |
122 bb.1 (%ir-block.0):
123 liveins: $rdi
124
125 ; ALL-LABEL: name: test_shl_i64_imm
126 ; ALL: liveins: $rdi
127 ; ALL: [[COPY:%[0-9]+]]:gr64 = COPY $rdi
128 ; ALL: [[MOV64ri32_:%[0-9]+]]:gr64 = MOV64ri32 5
129 ; ALL: $rcx = COPY [[MOV64ri32_]]
130 ; ALL: $cl = KILL killed $rcx
131 ; ALL: [[SHL64rCL:%[0-9]+]]:gr64 = SHL64rCL [[COPY]], implicit-def $eflags, implicit $cl
132 ; ALL: $rax = COPY [[SHL64rCL]]
133 ; ALL: RET 0, implicit $rax
134 %0(s64) = COPY $rdi
135 %1(s64) = G_CONSTANT i64 5
136 %2(s64) = G_SHL %0, %1
137 $rax = COPY %2(s64)
138 RET 0, implicit $rax
139
140 ...
141 ---
142 name: test_shl_i64_imm1
143 alignment: 4
144 legalized: true
145 regBankSelected: true
146 tracksRegLiveness: true
147 registers:
148 - { id: 0, class: gpr, preferred-register: '' }
149 - { id: 1, class: gpr, preferred-register: '' }
150 - { id: 2, class: gpr, preferred-register: '' }
151 liveins:
152 fixedStack:
153 stack:
154 constants:
155 body: |
156 bb.1 (%ir-block.0):
157 liveins: $rdi
158
159 ; ALL-LABEL: name: test_shl_i64_imm1
160 ; ALL: liveins: $rdi
161 ; ALL: [[COPY:%[0-9]+]]:gr64 = COPY $rdi
162 ; ALL: [[MOV64ri32_:%[0-9]+]]:gr64 = MOV64ri32 1
163 ; ALL: $rcx = COPY [[MOV64ri32_]]
164 ; ALL: $cl = KILL killed $rcx
165 ; ALL: [[SHL64rCL:%[0-9]+]]:gr64 = SHL64rCL [[COPY]], implicit-def $eflags, implicit $cl
166 ; ALL: $rax = COPY [[SHL64rCL]]
167 ; ALL: RET 0, implicit $rax
168 %0(s64) = COPY $rdi
169 %1(s64) = G_CONSTANT i64 1
170 %2(s64) = G_SHL %0, %1
171 $rax = COPY %2(s64)
172 RET 0, implicit $rax
173
174 ...
175 ---
176 name: test_shl_i32
177 alignment: 4
178 legalized: true
179 regBankSelected: true
180 tracksRegLiveness: true
181 registers:
182 - { id: 0, class: gpr, preferred-register: '' }
183 - { id: 1, class: gpr, preferred-register: '' }
184 - { id: 2, class: gpr, preferred-register: '' }
185 liveins:
186 fixedStack:
187 stack:
188 constants:
189 body: |
190 bb.1 (%ir-block.0):
191 liveins: $edi, $esi
192
193 ; ALL-LABEL: name: test_shl_i32
194 ; ALL: liveins: $edi, $esi
195 ; ALL: [[COPY:%[0-9]+]]:gr32 = COPY $edi
196 ; ALL: [[COPY1:%[0-9]+]]:gr32 = COPY $esi
197 ; ALL: $ecx = COPY [[COPY1]]
198 ; ALL: $cl = KILL killed $ecx
199 ; ALL: [[SHL32rCL:%[0-9]+]]:gr32 = SHL32rCL [[COPY]], implicit-def $eflags, implicit $cl
200 ; ALL: $eax = COPY [[SHL32rCL]]
201 ; ALL: RET 0, implicit $eax
202 %0(s32) = COPY $edi
203 %1(s32) = COPY $esi
204 %2(s32) = G_SHL %0, %1
205 $eax = COPY %2(s32)
206 RET 0, implicit $eax
207
208 ...
209 ---
210 name: test_shl_i32_imm
211 alignment: 4
212 legalized: true
213 regBankSelected: true
214 tracksRegLiveness: true
215 registers:
216 - { id: 0, class: gpr, preferred-register: '' }
217 - { id: 1, class: gpr, preferred-register: '' }
218 - { id: 2, class: gpr, preferred-register: '' }
219 liveins:
220 fixedStack:
221 stack:
222 constants:
223 body: |
224 bb.1 (%ir-block.0):
225 liveins: $edi
226
227 ; ALL-LABEL: name: test_shl_i32_imm
228 ; ALL: liveins: $edi
229 ; ALL: [[COPY:%[0-9]+]]:gr32 = COPY $edi
230 ; ALL: [[MOV32ri:%[0-9]+]]:gr32 = MOV32ri 5
231 ; ALL: $ecx = COPY [[MOV32ri]]
232 ; ALL: $cl = KILL killed $ecx
233 ; ALL: [[SHL32rCL:%[0-9]+]]:gr32 = SHL32rCL [[COPY]], implicit-def $eflags, implicit $cl
234 ; ALL: $eax = COPY [[SHL32rCL]]
235 ; ALL: RET 0, implicit $eax
236 %0(s32) = COPY $edi
237 %1(s32) = G_CONSTANT i32 5
238 %2(s32) = G_SHL %0, %1
239 $eax = COPY %2(s32)
240 RET 0, implicit $eax
241
242 ...
243 ---
244 name: test_shl_i32_imm1
245 alignment: 4
246 legalized: true
247 regBankSelected: true
248 tracksRegLiveness: true
249 registers:
250 - { id: 0, class: gpr, preferred-register: '' }
251 - { id: 1, class: gpr, preferred-register: '' }
252 - { id: 2, class: gpr, preferred-register: '' }
253 liveins:
254 fixedStack:
255 stack:
256 constants:
257 body: |
258 bb.1 (%ir-block.0):
259 liveins: $edi
260
261 ; ALL-LABEL: name: test_shl_i32_imm1
262 ; ALL: liveins: $edi
263 ; ALL: [[COPY:%[0-9]+]]:gr32 = COPY $edi
264 ; ALL: [[MOV32ri:%[0-9]+]]:gr32 = MOV32ri 1
265 ; ALL: $ecx = COPY [[MOV32ri]]
266 ; ALL: $cl = KILL killed $ecx
267 ; ALL: [[SHL32rCL:%[0-9]+]]:gr32 = SHL32rCL [[COPY]], implicit-def $eflags, implicit $cl
268 ; ALL: $eax = COPY [[SHL32rCL]]
269 ; ALL: RET 0, implicit $eax
270 %0(s32) = COPY $edi
271 %1(s32) = G_CONSTANT i32 1
272 %2(s32) = G_SHL %0, %1
273 $eax = COPY %2(s32)
274 RET 0, implicit $eax
275
276 ...
277 ---
278 name: test_shl_i16
279 alignment: 4
280 legalized: true
281 regBankSelected: true
282 tracksRegLiveness: true
283 registers:
284 - { id: 0, class: gpr, preferred-register: '' }
285 - { id: 1, class: gpr, preferred-register: '' }
286 - { id: 2, class: gpr, preferred-register: '' }
287 - { id: 3, class: gpr, preferred-register: '' }
288 - { id: 4, class: gpr, preferred-register: '' }
289 liveins:
290 fixedStack:
291 stack:
292 constants:
293 body: |
294 bb.1 (%ir-block.0):
295 liveins: $edi, $esi
296
297 ; ALL-LABEL: name: test_shl_i16
298 ; ALL: liveins: $edi, $esi
299 ; ALL: [[COPY:%[0-9]+]]:gr32 = COPY $edi
300 ; ALL: [[COPY1:%[0-9]+]]:gr32 = COPY $esi
301 ; ALL: [[COPY2:%[0-9]+]]:gr16 = COPY [[COPY]].sub_16bit
302 ; ALL: [[COPY3:%[0-9]+]]:gr16 = COPY [[COPY1]].sub_16bit
303 ; ALL: $cx = COPY [[COPY3]]
304 ; ALL: $cl = KILL killed $cx
305 ; ALL: [[SHL16rCL:%[0-9]+]]:gr16 = SHL16rCL [[COPY2]], implicit-def $eflags, implicit $cl
306 ; ALL: $ax = COPY [[SHL16rCL]]
307 ; ALL: RET 0, implicit $ax
308 %0(s32) = COPY $edi
309 %1(s32) = COPY $esi
310 %2(s16) = G_TRUNC %0(s32)
311 %3(s16) = G_TRUNC %1(s32)
312 %4(s16) = G_SHL %2, %3
313 $ax = COPY %4(s16)
314 RET 0, implicit $ax
315
316 ...
317 ---
318 name: test_shl_i16_imm
319 alignment: 4
320 legalized: true
321 regBankSelected: true
322 tracksRegLiveness: true
323 registers:
324 - { id: 0, class: gpr, preferred-register: '' }
325 - { id: 1, class: gpr, preferred-register: '' }
326 - { id: 2, class: gpr, preferred-register: '' }
327 - { id: 3, class: gpr, preferred-register: '' }
328 liveins:
329 fixedStack:
330 stack:
331 constants:
332 body: |
333 bb.1 (%ir-block.0):
334 liveins: $edi
335
336 ; ALL-LABEL: name: test_shl_i16_imm
337 ; ALL: liveins: $edi
338 ; ALL: [[COPY:%[0-9]+]]:gr32 = COPY $edi
339 ; ALL: [[MOV16ri:%[0-9]+]]:gr16 = MOV16ri 5
340 ; ALL: [[COPY1:%[0-9]+]]:gr16 = COPY [[COPY]].sub_16bit
341 ; ALL: $cx = COPY [[MOV16ri]]
342 ; ALL: $cl = KILL killed $cx
343 ; ALL: [[SHL16rCL:%[0-9]+]]:gr16 = SHL16rCL [[COPY1]], implicit-def $eflags, implicit $cl
344 ; ALL: $ax = COPY [[SHL16rCL]]
345 ; ALL: RET 0, implicit $ax
346 %0(s32) = COPY $edi
347 %2(s16) = G_CONSTANT i16 5
348 %1(s16) = G_TRUNC %0(s32)
349 %3(s16) = G_SHL %1, %2
350 $ax = COPY %3(s16)
351 RET 0, implicit $ax
352
353 ...
354 ---
355 name: test_shl_i16_imm1
356 alignment: 4
357 legalized: true
358 regBankSelected: true
359 tracksRegLiveness: true
360 registers:
361 - { id: 0, class: gpr, preferred-register: '' }
362 - { id: 1, class: gpr, preferred-register: '' }
363 - { id: 2, class: gpr, preferred-register: '' }
364 - { id: 3, class: gpr, preferred-register: '' }
365 liveins:
366 fixedStack:
367 stack:
368 constants:
369 body: |
370 bb.1 (%ir-block.0):
371 liveins: $edi
372
373 ; ALL-LABEL: name: test_shl_i16_imm1
374 ; ALL: liveins: $edi
375 ; ALL: [[COPY:%[0-9]+]]:gr32 = COPY $edi
376 ; ALL: [[MOV16ri:%[0-9]+]]:gr16 = MOV16ri 1
377 ; ALL: [[COPY1:%[0-9]+]]:gr16 = COPY [[COPY]].sub_16bit
378 ; ALL: $cx = COPY [[MOV16ri]]
379 ; ALL: $cl = KILL killed $cx
380 ; ALL: [[SHL16rCL:%[0-9]+]]:gr16 = SHL16rCL [[COPY1]], implicit-def $eflags, implicit $cl
381 ; ALL: $ax = COPY [[SHL16rCL]]
382 ; ALL: RET 0, implicit $ax
383 %0(s32) = COPY $edi
384 %2(s16) = G_CONSTANT i16 1
385 %1(s16) = G_TRUNC %0(s32)
386 %3(s16) = G_SHL %1, %2
387 $ax = COPY %3(s16)
388 RET 0, implicit $ax
389
390 ...
391 ---
392 name: test_shl_i8
393 alignment: 4
394 legalized: true
395 regBankSelected: true
396 tracksRegLiveness: true
397 registers:
398 - { id: 0, class: gpr, preferred-register: '' }
399 - { id: 1, class: gpr, preferred-register: '' }
400 - { id: 2, class: gpr, preferred-register: '' }
401 - { id: 3, class: gpr, preferred-register: '' }
402 - { id: 4, class: gpr, preferred-register: '' }
403 liveins:
404 fixedStack:
405 stack:
406 constants:
407 body: |
408 bb.1 (%ir-block.0):
409 liveins: $edi, $esi
410
411 ; ALL-LABEL: name: test_shl_i8
412 ; ALL: liveins: $edi, $esi
413 ; ALL: [[COPY:%[0-9]+]]:gr32 = COPY $edi
414 ; ALL: [[COPY1:%[0-9]+]]:gr32 = COPY $esi
415 ; ALL: [[COPY2:%[0-9]+]]:gr8 = COPY [[COPY]].sub_8bit
416 ; ALL: [[COPY3:%[0-9]+]]:gr8 = COPY [[COPY1]].sub_8bit
417 ; ALL: $cl = COPY [[COPY3]]
418 ; ALL: [[SHL8rCL:%[0-9]+]]:gr8 = SHL8rCL [[COPY2]], implicit-def $eflags, implicit $cl
419 ; ALL: $al = COPY [[SHL8rCL]]
420 ; ALL: RET 0, implicit $al
421 %0(s32) = COPY $edi
422 %1(s32) = COPY $esi
423 %2(s8) = G_TRUNC %0(s32)
424 %3(s8) = G_TRUNC %1(s32)
425 %4(s8) = G_SHL %2, %3
426 $al = COPY %4(s8)
427 RET 0, implicit $al
428
429 ...
430 ---
431 name: test_shl_i8_imm
432 alignment: 4
433 legalized: true
434 regBankSelected: true
435 tracksRegLiveness: true
436 registers:
437 - { id: 0, class: gpr, preferred-register: '' }
438 - { id: 1, class: gpr, preferred-register: '' }
439 - { id: 2, class: gpr, preferred-register: '' }
440 - { id: 3, class: gpr, preferred-register: '' }
441 liveins:
442 fixedStack:
443 stack:
444 constants:
445 body: |
446 bb.1 (%ir-block.0):
447 liveins: $edi
448
449 ; ALL-LABEL: name: test_shl_i8_imm
450 ; ALL: liveins: $edi
451 ; ALL: [[COPY:%[0-9]+]]:gr32 = COPY $edi
452 ; ALL: [[COPY1:%[0-9]+]]:gr8 = COPY [[COPY]].sub_8bit
453 ; ALL: [[SHL8ri:%[0-9]+]]:gr8 = SHL8ri [[COPY1]], 5, implicit-def $eflags
454 ; ALL: $al = COPY [[SHL8ri]]
455 ; ALL: RET 0, implicit $al
456 %0(s32) = COPY $edi
457 %2(s8) = G_CONSTANT i8 5
458 %1(s8) = G_TRUNC %0(s32)
459 %3(s8) = G_SHL %1, %2
460 $al = COPY %3(s8)
461 RET 0, implicit $al
462
463 ...
464 ---
465 name: test_shl_i8_imm1
466 alignment: 4
467 legalized: true
468 regBankSelected: true
469 tracksRegLiveness: true
470 registers:
471 - { id: 0, class: gpr, preferred-register: '' }
472 - { id: 1, class: gpr, preferred-register: '' }
473 - { id: 2, class: gpr, preferred-register: '' }
474 - { id: 3, class: gpr, preferred-register: '' }
475 liveins:
476 fixedStack:
477 stack:
478 constants:
479 body: |
480 bb.1 (%ir-block.0):
481 liveins: $edi
482
483 ; ALL-LABEL: name: test_shl_i8_imm1
484 ; ALL: liveins: $edi
485 ; ALL: [[COPY:%[0-9]+]]:gr32 = COPY $edi
486 ; ALL: [[COPY1:%[0-9]+]]:gr8 = COPY [[COPY]].sub_8bit
487 ; ALL: [[ADD8rr:%[0-9]+]]:gr8 = ADD8rr [[COPY1]], [[COPY1]], implicit-def $eflags
488 ; ALL: $al = COPY [[ADD8rr]]
489 ; ALL: RET 0, implicit $al
490 %0(s32) = COPY $edi
491 %2(s8) = G_CONSTANT i8 1
492 %1(s8) = G_TRUNC %0(s32)
493 %3(s8) = G_SHL %1, %2
494 $al = COPY %3(s8)
495 RET 0, implicit $al
496
497 ...
0 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
1 ; RUN: llc -mtriple=x86_64-linux-gnu -global-isel -verify-machineinstrs < %s -o - | FileCheck %s --check-prefix=X64
2
3 define i64 @test_shl_i64(i64 %arg1, i64 %arg2) {
4 ; X64-LABEL: test_shl_i64:
5 ; X64: # %bb.0:
6 ; X64-NEXT: movq %rsi, %rcx
7 ; X64-NEXT: # kill: def $cl killed $rcx
8 ; X64-NEXT: shlq %cl, %rdi
9 ; X64-NEXT: movq %rdi, %rax
10 ; X64-NEXT: retq
11 %res = shl i64 %arg1, %arg2
12 ret i64 %res
13 }
14
15 define i64 @test_shl_i64_imm(i64 %arg1) {
16 ; X64-LABEL: test_shl_i64_imm:
17 ; X64: # %bb.0:
18 ; X64-NEXT: movq $5, %rcx
19 ; X64-NEXT: # kill: def $cl killed $rcx
20 ; X64-NEXT: shlq %cl, %rdi
21 ; X64-NEXT: movq %rdi, %rax
22 ; X64-NEXT: retq
23 %res = shl i64 %arg1, 5
24 ret i64 %res
25 }
26
27 define i64 @test_shl_i64_imm1(i64 %arg1) {
28 ; X64-LABEL: test_shl_i64_imm1:
29 ; X64: # %bb.0:
30 ; X64-NEXT: movq $1, %rcx
31 ; X64-NEXT: # kill: def $cl killed $rcx
32 ; X64-NEXT: shlq %cl, %rdi
33 ; X64-NEXT: movq %rdi, %rax
34 ; X64-NEXT: retq
35 %res = shl i64 %arg1, 1
36 ret i64 %res
37 }
38
39 define i32 @test_shl_i32(i32 %arg1, i32 %arg2) {
40 ; X64-LABEL: test_shl_i32:
41 ; X64: # %bb.0:
42 ; X64-NEXT: movl %esi, %ecx
43 ; X64-NEXT: # kill: def $cl killed $ecx
44 ; X64-NEXT: shll %cl, %edi
45 ; X64-NEXT: movl %edi, %eax
46 ; X64-NEXT: retq
47 %res = shl i32 %arg1, %arg2
48 ret i32 %res
49 }
50
51 define i32 @test_shl_i32_imm(i32 %arg1) {
52 ; X64-LABEL: test_shl_i32_imm:
53 ; X64: # %bb.0:
54 ; X64-NEXT: movl $5, %ecx
55 ; X64-NEXT: # kill: def $cl killed $ecx
56 ; X64-NEXT: shll %cl, %edi
57 ; X64-NEXT: movl %edi, %eax
58 ; X64-NEXT: retq
59 %res = shl i32 %arg1, 5
60 ret i32 %res
61 }
62
63 define i32 @test_shl_i32_imm1(i32 %arg1) {
64 ; X64-LABEL: test_shl_i32_imm1:
65 ; X64: # %bb.0:
66 ; X64-NEXT: movl $1, %ecx
67 ; X64-NEXT: # kill: def $cl killed $ecx
68 ; X64-NEXT: shll %cl, %edi
69 ; X64-NEXT: movl %edi, %eax
70 ; X64-NEXT: retq
71 %res = shl i32 %arg1, 1
72 ret i32 %res
73 }
74
75 define i16 @test_shl_i16(i32 %arg1, i32 %arg2) {
76 ; X64-LABEL: test_shl_i16:
77 ; X64: # %bb.0:
78 ; X64-NEXT: movl %esi, %ecx
79 ; X64-NEXT: # kill: def $cl killed $cx
80 ; X64-NEXT: shlw %cl, %di
81 ; X64-NEXT: movl %edi, %eax
82 ; X64-NEXT: retq
83 %a = trunc i32 %arg1 to i16
84 %a2 = trunc i32 %arg2 to i16
85 %res = shl i16 %a, %a2
86 ret i16 %res
87 }
88
89 define i16 @test_shl_i16_imm(i32 %arg1) {
90 ; X64-LABEL: test_shl_i16_imm:
91 ; X64: # %bb.0:
92 ; X64-NEXT: movw $5, %cx
93 ; X64-NEXT: # kill: def $cl killed $cx
94 ; X64-NEXT: shlw %cl, %di
95 ; X64-NEXT: movl %edi, %eax
96 ; X64-NEXT: retq
97 %a = trunc i32 %arg1 to i16
98 %res = shl i16 %a, 5
99 ret i16 %res
100 }
101
102 define i16 @test_shl_i16_imm1(i32 %arg1) {
103 ; X64-LABEL: test_shl_i16_imm1:
104 ; X64: # %bb.0:
105 ; X64-NEXT: movw $1, %cx
106 ; X64-NEXT: # kill: def $cl killed $cx
107 ; X64-NEXT: shlw %cl, %di
108 ; X64-NEXT: movl %edi, %eax
109 ; X64-NEXT: retq
110 %a = trunc i32 %arg1 to i16
111 %res = shl i16 %a, 1
112 ret i16 %res
113 }
114
115 define i8 @test_shl_i8(i32 %arg1, i32 %arg2) {
116 ; X64-LABEL: test_shl_i8:
117 ; X64: # %bb.0:
118 ; X64-NEXT: movl %esi, %ecx
119 ; X64-NEXT: shlb %cl, %dil
120 ; X64-NEXT: movl %edi, %eax
121 ; X64-NEXT: retq
122 %a = trunc i32 %arg1 to i8
123 %a2 = trunc i32 %arg2 to i8
124 %res = shl i8 %a, %a2
125 ret i8 %res
126 }
127
128 define i8 @test_shl_i8_imm(i32 %arg1) {
129 ; X64-LABEL: test_shl_i8_imm:
130 ; X64: # %bb.0:
131 ; X64-NEXT: shlb $5, %dil
132 ; X64-NEXT: movl %edi, %eax
133 ; X64-NEXT: retq
134 %a = trunc i32 %arg1 to i8
135 %res = shl i8 %a, 5
136 ret i8 %res
137 }
138
139 define i8 @test_shl_i8_imm1(i32 %arg1) {
140 ; X64-LABEL: test_shl_i8_imm1:
141 ; X64: # %bb.0:
142 ; X64-NEXT: addb %dil, %dil
143 ; X64-NEXT: movl %edi, %eax
144 ; X64-NEXT: retq
145 %a = trunc i32 %arg1 to i8
146 %res = shl i8 %a, 1
147 ret i8 %res
148 }
149
150 define i1 @test_shl_i1(i32 %arg1, i32 %arg2) {
151 ; X64-LABEL: test_shl_i1:
152 ; X64: # %bb.0:
153 ; X64-NEXT: movl %esi, %ecx
154 ; X64-NEXT: shlb %cl, %dil
155 ; X64-NEXT: movl %edi, %eax
156 ; X64-NEXT: retq
157 %a = trunc i32 %arg1 to i1
158 %a2 = trunc i32 %arg2 to i1
159 %res = shl i1 %a, %a2
160 ret i1 %res
161 }
162
163 define i1 @test_shl_i1_imm1(i32 %arg1) {
164 ; X64-LABEL: test_shl_i1_imm1:
165 ; X64: # %bb.0:
166 ; X64-NEXT: movb $-1, %cl
167 ; X64-NEXT: shlb %cl, %dil
168 ; X64-NEXT: movl %edi, %eax
169 ; X64-NEXT: retq
170 %a = trunc i32 %arg1 to i1
171 %res = shl i1 %a, 1
172 ret i1 %res
173 }