llvm.org GIT mirror llvm / b3cb8ab
[AsmPrinter] refactor to support %c w/ GlobalAddress' Summary: Targets like ARM, MSP430, PPC, and SystemZ have complex behavior when printing the address of a MachineOperand::MO_GlobalAddress. Move that handling into a new overriden method in each base class. A virtual method was added to the base class for handling the generic case. Refactors a few subclasses to support the target independent %a, %c, and %n. The patch also contains small cleanups for AVRAsmPrinter and SystemZAsmPrinter. It seems that NVPTXTargetLowering is possibly missing some logic to transform GlobalAddressSDNodes for TargetLowering::LowerAsmOperandForConstraint to handle with "i" extended inline assembly asm constraints. Fixes: - https://bugs.llvm.org/show_bug.cgi?id=41402 - https://github.com/ClangBuiltLinux/linux/issues/449 Reviewers: echristo, void Reviewed By: void Subscribers: void, craig.topper, jholewinski, dschuff, jyknight, dylanmckay, sdardis, nemanjai, javed.absar, sbc100, jgravelle-google, eraman, kristof.beyls, hiraditya, aheejin, kbarton, fedor.sergeev, jrtc27, atanasyan, jsji, llvm-commits, kees, tpimh, nathanchance, peter.smith, srhines Tags: #llvm Differential Revision: https://reviews.llvm.org/D60887 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@359337 91177308-0d34-0410-b5e6-96231b3b80d8 Nick Desaulniers 1 year, 7 months ago
33 changed file(s) with 406 addition(s) and 86 deletion(s). Raw diff Collapse all Expand all
589589 virtual void PrintSpecial(const MachineInstr *MI, raw_ostream &OS,
590590 const char *Code) const;
591591
592 /// Print the MachineOperand as a symbol. Targets with complex handling of
593 /// symbol references should override the base implementation.
594 virtual void PrintSymbolOperand(const MachineOperand &MO, raw_ostream &OS);
595
592596 /// Print the specified operand of MI, an INLINEASM instruction, using the
593597 /// specified assembler variant. Targets should override this to format as
594598 /// appropriate. This method can return true if the operand is erroneous.
598598 }
599599 }
600600
601 void AsmPrinter::PrintSymbolOperand(const MachineOperand &MO, raw_ostream &OS) {
602 assert(MO.isGlobal() && "caller should check MO.isGlobal");
603 getSymbol(MO.getGlobal())->print(OS, MAI);
604 printOffset(MO.getOffset(), OS);
605 }
606
601607 /// PrintAsmOperand - Print the specified operand of MI, an INLINEASM
602608 /// instruction, using the specified assembler variant. Targets should
603609 /// override this to format as appropriate for machine specific ExtraCodes
620626 }
621627 LLVM_FALLTHROUGH; // GCC allows '%a' to behave like '%c' with immediates.
622628 case 'c': // Substitute immediate value without immediate syntax
623 if (!MO.isImm())
624 return true;
625 O << MO.getImm();
626 return false;
629 if (MO.isImm()) {
630 O << MO.getImm();
631 return false;
632 }
633 if (MO.isGlobal()) {
634 PrintSymbolOperand(MO, O);
635 return false;
636 }
637 return true;
627638 case 'n': // Negate the immediate constant.
628639 if (!MO.isImm())
629640 return true;
435435 break;
436436 }
437437 case MachineOperand::MO_GlobalAddress: {
438 const GlobalValue *GV = MO.getGlobal();
439 MCSymbol *Sym = getSymbol(GV);
440
441 // FIXME: Can we get anything other than a plain symbol here?
442 assert(!MO.getTargetFlags() && "Unknown operand target flag!");
443
444 Sym->print(O, MAI);
445 printOffset(MO.getOffset(), O);
438 PrintSymbolOperand(MO, O);
446439 break;
447440 }
448441 case MachineOperand::MO_BlockAddress: {
182182 return false;
183183 }
184184
185 void ARMAsmPrinter::PrintSymbolOperand(const MachineOperand &MO,
186 raw_ostream &O) {
187 assert(MO.isGlobal() && "caller should check MO.isGlobal");
188 unsigned TF = MO.getTargetFlags();
189 if (TF & ARMII::MO_LO16)
190 O << ":lower16:";
191 else if (TF & ARMII::MO_HI16)
192 O << ":upper16:";
193 GetARMGVSymbol(MO.getGlobal(), TF)->print(O, MAI);
194 printOffset(MO.getOffset(), O);
195 }
196
185197 void ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
186198 raw_ostream &O) {
187199 const MachineOperand &MO = MI->getOperand(OpNum);
188 unsigned TF = MO.getTargetFlags();
189200
190201 switch (MO.getType()) {
191202 default: llvm_unreachable("");
202213 break;
203214 }
204215 case MachineOperand::MO_Immediate: {
205 int64_t Imm = MO.getImm();
206216 O << '#';
217 unsigned TF = MO.getTargetFlags();
207218 if (TF == ARMII::MO_LO16)
208219 O << ":lower16:";
209220 else if (TF == ARMII::MO_HI16)
210221 O << ":upper16:";
211 O << Imm;
222 O << MO.getImm();
212223 break;
213224 }
214225 case MachineOperand::MO_MachineBasicBlock:
215226 MO.getMBB()->getSymbol()->print(O, MAI);
216227 return;
217228 case MachineOperand::MO_GlobalAddress: {
218 const GlobalValue *GV = MO.getGlobal();
219 if (TF & ARMII::MO_LO16)
220 O << ":lower16:";
221 else if (TF & ARMII::MO_HI16)
222 O << ":upper16:";
223 GetARMGVSymbol(GV, TF)->print(O, MAI);
224
225 printOffset(MO.getOffset(), O);
229 PrintSymbolOperand(MO, O);
226230 break;
227231 }
228232 case MachineOperand::MO_ConstantPoolIndex:
7474
7575 void printOperand(const MachineInstr *MI, int OpNum, raw_ostream &O);
7676
77 void PrintSymbolOperand(const MachineOperand &MO, raw_ostream &O) override;
7778 bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
7879 const char *ExtraCode, raw_ostream &O) override;
7980 bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum,
4141
4242 StringRef getPassName() const override { return "AVR Assembly Printer"; }
4343
44 void printOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O,
45 const char *Modifier = 0);
44 void printOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O);
4645
4746 bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
4847 const char *ExtraCode, raw_ostream &O) override;
5756 };
5857
5958 void AVRAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
60 raw_ostream &O, const char *Modifier) {
59 raw_ostream &O) {
6160 const MachineOperand &MO = MI->getOperand(OpNo);
6261
6362 switch (MO.getType()) {
103103 bool BPFAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
104104 const char *ExtraCode, raw_ostream &O) {
105105 if (ExtraCode && ExtraCode[0])
106 return true; // BPF does not have special modifiers
106 return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, O);
107107
108108 printOperand(MI, OpNo, O);
109109 return false;
9090 GetCPISymbol(MO.getIndex())->print(O, MAI);
9191 return;
9292 case MachineOperand::MO_GlobalAddress:
93 // Computing the address of a global symbol, not calling it.
94 getSymbol(MO.getGlobal())->print(O, MAI);
95 printOffset(MO.getOffset(), O);
93 PrintSymbolOperand(MO, O);
9694 return;
9795 }
9896 }
135135 return false;
136136 }
137137 default:
138 return true; // Unknown modifier.
138 return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, O);
139139 }
140140 }
141141 printOperand(MI, OpNo, O);
4646
4747 bool runOnMachineFunction(MachineFunction &MF) override;
4848
49 void PrintSymbolOperand(const MachineOperand &MO, raw_ostream &O) override;
4950 void printOperand(const MachineInstr *MI, int OpNum,
5051 raw_ostream &O, const char* Modifier = nullptr);
5152 void printSrcMemOperand(const MachineInstr *MI, int OpNum,
6061 };
6162 } // end of anonymous namespace
6263
64 void MSP430AsmPrinter::PrintSymbolOperand(const MachineOperand &MO,
65 raw_ostream &O) {
66 uint64_t Offset = MO.getOffset();
67 if (Offset)
68 O << '(' << Offset << '+';
69
70 getSymbol(MO.getGlobal())->print(O, MAI);
71
72 if (Offset)
73 O << ')';
74 }
6375
6476 void MSP430AsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
6577 raw_ostream &O, const char *Modifier) {
7890 MO.getMBB()->getSymbol()->print(O, MAI);
7991 return;
8092 case MachineOperand::MO_GlobalAddress: {
81 bool isMemOp = Modifier && !strcmp(Modifier, "mem");
82 uint64_t Offset = MO.getOffset();
83
8493 // If the global address expression is a part of displacement field with a
8594 // register base, we should not emit any prefix symbol here, e.g.
86 // mov.w &foo, r1
87 // vs
8895 // mov.w glb(r1), r2
8996 // Otherwise (!) msp430-as will silently miscompile the output :(
9097 if (!Modifier || strcmp(Modifier, "nohash"))
91 O << (isMemOp ? '&' : '#');
92 if (Offset)
93 O << '(' << Offset << '+';
94
95 getSymbol(MO.getGlobal())->print(O, MAI);
96
97 if (Offset)
98 O << ')';
99
98 O << '#';
99 PrintSymbolOperand(MO, O);
100100 return;
101101 }
102102 }
128128 const char *ExtraCode, raw_ostream &O) {
129129 // Does this asm operand have a single letter operand modifier?
130130 if (ExtraCode && ExtraCode[0])
131 return true; // Unknown modifier.
131 return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, O);
132132
133133 printOperand(MI, OpNo, O);
134134 return false;
691691 return;
692692
693693 case MachineOperand::MO_GlobalAddress:
694 getSymbol(MO.getGlobal())->print(O, MAI);
694 PrintSymbolOperand(MO, O);
695695 break;
696696
697697 case MachineOperand::MO_BlockAddress: {
22292229 break;
22302230
22312231 case MachineOperand::MO_GlobalAddress:
2232 getSymbol(MO.getGlobal())->print(O, MAI);
2232 PrintSymbolOperand(MO, O);
22332233 break;
22342234
22352235 case MachineOperand::MO_MachineBasicBlock:
100100 /// The \p MI would be INLINEASM ONLY.
101101 void printOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O);
102102
103 void PrintSymbolOperand(const MachineOperand &MO, raw_ostream &O) override;
103104 bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
104105 const char *ExtraCode, raw_ostream &O) override;
105106 bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
157158
158159 } // end anonymous namespace
159160
161 void PPCAsmPrinter::PrintSymbolOperand(const MachineOperand &MO,
162 raw_ostream &O) {
163 // Computing the address of a global symbol, not calling it.
164 const GlobalValue *GV = MO.getGlobal();
165 MCSymbol *SymToPrint;
166
167 // External or weakly linked global variables need non-lazily-resolved stubs
168 if (Subtarget->hasLazyResolverStub(GV)) {
169 SymToPrint = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
170 MachineModuleInfoImpl::StubValueTy &StubSym =
171 MMI->getObjFileInfo().getGVStubEntry(
172 SymToPrint);
173 if (!StubSym.getPointer())
174 StubSym = MachineModuleInfoImpl::StubValueTy(getSymbol(GV),
175 !GV->hasInternalLinkage());
176 } else {
177 SymToPrint = getSymbol(GV);
178 }
179
180 SymToPrint->print(O, MAI);
181
182 printOffset(MO.getOffset(), O);
183 }
184
160185 void PPCAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
161186 raw_ostream &O) {
162187 const DataLayout &DL = getDataLayout();
189214 GetBlockAddressSymbol(MO.getBlockAddress())->print(O, MAI);
190215 return;
191216 case MachineOperand::MO_GlobalAddress: {
192 // Computing the address of a global symbol, not calling it.
193 const GlobalValue *GV = MO.getGlobal();
194 MCSymbol *SymToPrint;
195
196 // External or weakly linked global variables need non-lazily-resolved stubs
197 if (Subtarget->hasLazyResolverStub(GV)) {
198 SymToPrint = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
199 MachineModuleInfoImpl::StubValueTy &StubSym =
200 MMI->getObjFileInfo().getGVStubEntry(
201 SymToPrint);
202 if (!StubSym.getPointer())
203 StubSym = MachineModuleInfoImpl::StubValueTy(getSymbol(GV),
204 !GV->hasInternalLinkage());
205 } else {
206 SymToPrint = getSymbol(GV);
207 }
208
209 SymToPrint->print(O, MAI);
210
211 printOffset(MO.getOffset(), O);
217 PrintSymbolOperand(MO, O);
212218 return;
213219 }
214220
356356 MO.getMBB()->getSymbol()->print(O, MAI);
357357 return;
358358 case MachineOperand::MO_GlobalAddress:
359 getSymbol(MO.getGlobal())->print(O, MAI);
359 PrintSymbolOperand(MO, O);
360360 break;
361361 case MachineOperand::MO_BlockAddress:
362362 O << GetBlockAddressSymbol(MO.getBlockAddress())->getName();
619619 bool SystemZAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
620620 const char *ExtraCode,
621621 raw_ostream &OS) {
622 if (ExtraCode && *ExtraCode == 'n') {
623 if (!MI->getOperand(OpNo).isImm())
624 return true;
625 OS << -int64_t(MI->getOperand(OpNo).getImm());
626 } else {
627 SystemZMCInstLower Lower(MF->getContext(), *this);
628 MCOperand MO(Lower.lowerOperand(MI->getOperand(OpNo)));
629 SystemZInstPrinter::printOperand(MO, MAI, OS);
630 }
622 if (ExtraCode)
623 return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, OS);
624 SystemZMCInstLower Lower(MF->getContext(), *this);
625 MCOperand MO(Lower.lowerOperand(MI->getOperand(OpNo)));
626 SystemZInstPrinter::printOperand(MO, MAI, OS);
631627 return false;
632628 }
633629
406406 OS << regToString(MO);
407407 return false;
408408 case MachineOperand::MO_GlobalAddress:
409 getSymbol(MO.getGlobal())->print(OS, MAI);
410 printOffset(MO.getOffset(), OS);
409 PrintSymbolOperand(MO, OS);
411410 return false;
412411 case MachineOperand::MO_ExternalSymbol:
413412 GetExternalSymbolSymbol(MO.getSymbolName())->print(OS, MAI);
298298 case MachineOperand::MO_GlobalAddress:
299299 case MachineOperand::MO_ConstantPoolIndex:
300300 PrintSymbolOperand(DispSpec, O);
301 break;
301302 }
302303
303304 if (Modifier && strcmp(Modifier, "H") == 0)
101101 // Choose between emitting .seh_ directives and .cv_fpo_ directives.
102102 void EmitSEHInstruction(const MachineInstr *MI);
103103
104 void PrintSymbolOperand(const MachineOperand &MO, raw_ostream &O);
104 void PrintSymbolOperand(const MachineOperand &MO, raw_ostream &O) override;
105105 void PrintOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O);
106106 void PrintModifiedOperand(const MachineInstr *MI, unsigned OpNo,
107107 raw_ostream &O, const char *Modifier);
212212 MO.getMBB()->getSymbol()->print(O, MAI);
213213 break;
214214 case MachineOperand::MO_GlobalAddress:
215 getSymbol(MO.getGlobal())->print(O, MAI);
215 PrintSymbolOperand(MO, O);
216216 break;
217217 case MachineOperand::MO_ConstantPoolIndex:
218218 O << DL.getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << '_'
0 ; RUN: llc -mtriple=aarch64-linux-gnu < %s | FileCheck %s
1
2
3 ; Test that %c works with immediates
4 ; CHECK-LABEL: test_inlineasm_c_output_template0
5 ; CHECK: TEST 42
6 define dso_local i32 @test_inlineasm_c_output_template0() {
7 tail call void asm sideeffect "//TEST ${0:c}", "i"(i32 42)
8 ret i32 42
9 }
10
11 ; Test that %c works with global address
12 ; CHECK-LABEL: test_inlineasm_c_output_template1:
13 ; CHECK: TEST {{_?}}baz
14 @baz = internal global i32 0, align 4
15 define dso_local i32 @test_inlineasm_c_output_template1() {
16 tail call void asm sideeffect "//TEST ${0:c}", "i"(i32* nonnull @baz)
17 ret i32 43
18 }
19
20 ; Test that %n works with immediates
21 ; CHECK-LABEL: test_inlineasm_c_output_template2
22 ; CHECK: TEST -42
23 define dso_local i32 @test_inlineasm_c_output_template2() {
24 tail call void asm sideeffect "//TEST ${0:n}", "i"(i32 42)
25 ret i32 42
26 }
77 ret i32 42
88 }
99
10 ; Test that %c works with global address
11 ; CHECK-LABEL: test_inlineasm_c_output_template2
12 ; CHECK: @TEST baz
13 @baz = internal global i32 0, align 4
14 define dso_local i32 @test_inlineasm_c_output_template2() {
15 tail call void asm sideeffect "@TEST ${0:c}", "i"(i32* nonnull @baz)
16 ret i32 42
17 }
18
1019 ; Test that %n works with immediates
1120 ; CHECK-LABEL: test_inlineasm_c_output_template1
1221 ; CHECK: @TEST -42
0 ; RUN: llc -mtriple=bpfel-linux-gnu < %s | FileCheck %s
1
2 ; Test that %c works with immediates
3 ; CHECK-LABEL: test_inlineasm_c_output_template0
4 ; CHECK: #TEST 42
5 define dso_local i32 @test_inlineasm_c_output_template0() {
6 tail call void asm sideeffect "#TEST ${0:c}", "i"(i32 42)
7 ret i32 42
8 }
9
10 ; Test that %c works with global address
11 ; CHECK-LABEL: test_inlineasm_c_output_template1
12 ; CHECK: #TEST baz
13 @baz = internal global i32 0, align 4
14 define dso_local i32 @test_inlineasm_c_output_template1() {
15 tail call void asm sideeffect "#TEST ${0:c}", "i"(i32* nonnull @baz)
16 ret i32 42
17 }
18
19 ; Test that %n works with immediates
20 ; CHECK-LABEL: test_inlineasm_c_output_template2
21 ; CHECK: #TEST -42
22 define dso_local i32 @test_inlineasm_c_output_template2() {
23 tail call void asm sideeffect "#TEST ${0:n}", "i"(i32 42)
24 ret i32 42
25 }
77 ret i32 42
88 }
99
10 ; Test that %c works with global address
11 ; CHECK-LABEL: test_inlineasm_c_output_template1:
12 ; CHECK: TEST {{_?}}baz
13 @baz = internal global i32 0, align 4
14 define dso_local i32 @test_inlineasm_c_output_template1() {
15 tail call void asm sideeffect "//TEST ${0:c}", "i"(i32* nonnull @baz)
16 ret i32 43
17 }
18
1019 ; Test that %n works with immediates
11 ; CHECK-LABEL: test_inlineasm_c_output_template1
20 ; CHECK-LABEL: test_inlineasm_c_output_template2
1221 ; CHECK: //TEST -42
13 define dso_local i32 @test_inlineasm_c_output_template1() {
22 define dso_local i32 @test_inlineasm_c_output_template2() {
1423 tail call void asm sideeffect "//TEST ${0:n}", "i"(i32 42)
1524 ret i32 42
1625 }
0 ; RUN: llc -mtriple=lanai-linux-gnueabi < %s | FileCheck %s
1
2 ; Test that %c works with immediates
3 ; CHECK-LABEL: test_inlineasm_c_output_template0
4 ; CHECK: !TEST 42
5 define dso_local i32 @test_inlineasm_c_output_template0() {
6 tail call void asm sideeffect "!TEST ${0:c}", "i"(i32 42)
7 ret i32 42
8 }
9
10 ; Test that %c works with global address
11 ; CHECK-LABEL: test_inlineasm_c_output_template1
12 ; CHECK: !TEST baz
13 @baz = internal global i32 0, align 4
14 define dso_local i32 @test_inlineasm_c_output_template1() {
15 tail call void asm sideeffect "!TEST ${0:c}", "i"(i32* nonnull @baz)
16 ret i32 42
17 }
18
19 ; Test that %n works with immediates
20 ; CHECK-LABEL: test_inlineasm_c_output_template2
21 ; CHECK: !TEST -42
22 define dso_local i32 @test_inlineasm_c_output_template2() {
23 tail call void asm sideeffect "!TEST ${0:n}", "i"(i32 42)
24 ret i32 42
25 }
0 ; RUN: llc -mtriple=msp430-linux-gnu < %s | FileCheck %s
1
2 ; Test that %c works with immediates
3 ; CHECK-LABEL: test_inlineasm_c_output_template0
4 ; CHECK: ;TEST 42
5 define dso_local i32 @test_inlineasm_c_output_template0() {
6 tail call void asm sideeffect ";TEST ${0:c}", "i"(i32 42)
7 ret i32 42
8 }
9
10 ; Test that %c works with global address
11 ; CHECK-LABEL: test_inlineasm_c_output_template2
12 ; CHECK: ;TEST baz
13 @baz = internal global i32 0, align 4
14 define dso_local i32 @test_inlineasm_c_output_template2() {
15 tail call void asm sideeffect ";TEST ${0:c}", "i"(i32* nonnull @baz)
16 ret i32 42
17 }
18
19 ; Test that %n works with immediates
20 ; CHECK-LABEL: test_inlineasm_c_output_template1
21 ; CHECK: ;TEST -42
22 define dso_local i32 @test_inlineasm_c_output_template1() {
23 tail call void asm sideeffect ";TEST ${0:n}", "i"(i32 42)
24 ret i32 42
25 }
0 ; RUN: llc -mtriple=mips64el-linux-gnu < %s | FileCheck %s
1
2 ; Test that %c works with immediates
3 ; CHECK-LABEL: test_inlineasm_c_output_template0
4 ; CHECK: #TEST 42
5 define dso_local i32 @test_inlineasm_c_output_template0() {
6 tail call void asm sideeffect "#TEST ${0:c}", "i"(i32 42)
7 ret i32 42
8 }
9
10 ; Test that %c works with global address
11 ; CHECK-LABEL: test_inlineasm_c_output_template1
12 ; CHECK: #TEST baz
13 @baz = internal global i32 0, align 4
14 define dso_local i32 @test_inlineasm_c_output_template1() {
15 tail call void asm sideeffect "#TEST ${0:c}", "i"(i32* nonnull @baz)
16 ret i32 42
17 }
18
19 ; Test that %n works with immediates
20 ; CHECK-LABEL: test_inlineasm_c_output_template2
21 ; CHECK: #TEST -42
22 define dso_local i32 @test_inlineasm_c_output_template2() {
23 tail call void asm sideeffect "#TEST ${0:n}", "i"(i32 42)
24 ret i32 42
25 }
0 ; RUN: llc -march=nvptx < %s | FileCheck %s
1
2 ; Test that %c works with immediates
3 ; CHECK-LABEL: test_inlineasm_c_output_template0
4 ; CHECK: //TEST 42
5 define dso_local i32 @test_inlineasm_c_output_template0() {
6 tail call void asm sideeffect "//TEST ${0:c}", "i"(i32 42)
7 ret i32 42
8 }
9
10 ; Test that %c works with global address
11 ; FIXME: seems this case isn't handled properly by
12 ; SelectionDAG TargetLowering::LowerAsmOperandForConstraint?
13 ; check: test_inlineasm_c_output_template1
14 ; check: //TEST baz
15 ;@baz = internal global i32 0, align 4
16 ;define dso_local i32 @test_inlineasm_c_output_template1() {
17 ; tail call void asm sideeffect "//TEST ${0:c}", "i"(i32* nonnull @baz)
18 ; ret i32 42
19 ;}
20
21 ; Test that %n works with immediates
22 ; CHECK-LABEL: test_inlineasm_c_output_template2
23 ; CHECK: //TEST -42
24 define dso_local i32 @test_inlineasm_c_output_template2() {
25 tail call void asm sideeffect "//TEST ${0:n}", "i"(i32 42)
26 ret i32 42
27 }
77 ret i32 42
88 }
99
10 ; Test that %c works with global address
11 ; CHECK-LABEL: test_inlineasm_c_output_template1:
12 ; CHECK: #TEST baz
13 @baz = internal global i32 0, align 4
14 define dso_local i32 @test_inlineasm_c_output_template1() {
15 tail call void asm sideeffect "#TEST ${0:c}", "i"(i32* nonnull @baz)
16 ret i32 43
17 }
18
1019 ; Test that %n works with immediates
11 ; CHECK-LABEL: test_inlineasm_c_output_template1
20 ; CHECK-LABEL: test_inlineasm_c_output_template2
1221 ; CHECK: #TEST -42
13 define dso_local i32 @test_inlineasm_c_output_template1() {
22 define dso_local i32 @test_inlineasm_c_output_template2() {
1423 tail call void asm sideeffect "#TEST ${0:n}", "i"(i32 42)
1524 ret i32 42
1625 }
0 ; RUN: llc -mtriple=sparc-linux-gnu < %s | FileCheck %s
1
2 ; Test that %c works with immediates
3 ; CHECK-LABEL: test_inlineasm_c_output_template0
4 ; CHECK: !TEST 42
5 define dso_local i32 @test_inlineasm_c_output_template0() {
6 tail call void asm sideeffect "!TEST ${0:c}", "i"(i32 42)
7 ret i32 42
8 }
9
10 ; Test that %c works with global address
11 ; CHECK-LABEL: test_inlineasm_c_output_template1
12 ; CHECK: !TEST baz
13 @baz = internal global i32 0, align 4
14 define dso_local i32 @test_inlineasm_c_output_template1() {
15 tail call void asm sideeffect "!TEST ${0:c}", "i"(i32* nonnull @baz)
16 ret i32 42
17 }
18
19 ; Test that %n works with immediates
20 ; CHECK-LABEL: test_inlineasm_c_output_template2
21 ; CHECK: !TEST -42
22 define dso_local i32 @test_inlineasm_c_output_template2() {
23 tail call void asm sideeffect "!TEST ${0:n}", "i"(i32 42)
24 ret i32 42
25 }
0 ; RUN: llc -mtriple=s390x-linux-gnu < %s | FileCheck %s
1
2 ; Test that %c works with immediates
3 ; CHECK-LABEL: test_inlineasm_c_output_template0
4 ; CHECK: #TEST 42
5 define dso_local i32 @test_inlineasm_c_output_template0() {
6 tail call void asm sideeffect "#TEST ${0:c}", "i"(i32 42)
7 ret i32 42
8 }
9
10 ; Test that %c works with global address
11 ; CHECK-LABEL: test_inlineasm_c_output_template2
12 ; CHECK: #TEST baz
13 @baz = internal global i32 0, align 4
14 define dso_local i32 @test_inlineasm_c_output_template2() {
15 tail call void asm sideeffect "#TEST ${0:c}", "i"(i32* nonnull @baz)
16 ret i32 42
17 }
18
19 ; Test that %n works with immediates
20 ; CHECK-LABEL: test_inlineasm_c_output_template1
21 ; CHECK: #TEST -42
22 define dso_local i32 @test_inlineasm_c_output_template1() {
23 tail call void asm sideeffect "#TEST ${0:n}", "i"(i32 42)
24 ret i32 42
25 }
0 ; RUN: llc -mtriple=wasm32 < %s | FileCheck %s
1
2 ; Test that %c works with immediates
3 ; CHECK-LABEL: test_inlineasm_c_output_template0
4 ; CHECK: #TEST 42
5 define dso_local i32 @test_inlineasm_c_output_template0() {
6 tail call void asm sideeffect "#TEST ${0:c}", "i"(i32 42)
7 ret i32 42
8 }
9
10 ; Test that %c works with global address
11 ; CHECK-LABEL: test_inlineasm_c_output_template2
12 ; CHECK: #TEST baz
13 @baz = internal global i32 0, align 4
14 define dso_local i32 @test_inlineasm_c_output_template2() {
15 tail call void asm sideeffect "#TEST ${0:c}", "i"(i32* nonnull @baz)
16 ret i32 42
17 }
18
19 ; Test that %n works with immediates
20 ; CHECK-LABEL: test_inlineasm_c_output_template1
21 ; CHECK: #TEST -42
22 define dso_local i32 @test_inlineasm_c_output_template1() {
23 tail call void asm sideeffect "#TEST ${0:n}", "i"(i32 42)
24 ret i32 42
25 }
0 ; RUN: llc -mtriple=x86_64-linux-gnu < %s | FileCheck %s
1
2 ; Test that %c works with immediates
3 ; CHECK-LABEL: test_inlineasm_c_output_template0
4 ; CHECK: #TEST 42
5 define dso_local i32 @test_inlineasm_c_output_template0() {
6 tail call void asm sideeffect "#TEST ${0:c}", "i"(i32 42)
7 ret i32 42
8 }
9
10 ; Test that %c works with global address
11 ; CHECK-LABEL: test_inlineasm_c_output_template1
12 ; CHECK: #TEST baz
13 @baz = internal global i32 0, align 4
14 define dso_local i32 @test_inlineasm_c_output_template1() {
15 tail call void asm sideeffect "#TEST ${0:c}", "i"(i32* nonnull @baz)
16 ret i32 42
17 }
0 ; RUN: llc -march=xcore < %s | FileCheck %s
1
2 ; Test that %c works with immediates
3 ; CHECK-LABEL: test_inlineasm_c_output_template0
4 ; CHECK: #TEST 42
5 define dso_local i32 @test_inlineasm_c_output_template0() {
6 tail call void asm sideeffect "#TEST ${0:c}", "i"(i32 42)
7 ret i32 42
8 }
9
10 ; Test that %c works with global address
11 ; CHECK-LABEL: test_inlineasm_c_output_template2
12 ; CHECK: #TEST baz
13 @baz = internal global i32 0, align 4
14 define dso_local i32 @test_inlineasm_c_output_template2() {
15 tail call void asm sideeffect "#TEST ${0:c}", "i"(i32* nonnull @baz)
16 ret i32 42
17 }
18
19 ; Test that %n works with immediates
20 ; CHECK-LABEL: test_inlineasm_c_output_template1
21 ; CHECK: #TEST -42
22 define dso_local i32 @test_inlineasm_c_output_template1() {
23 tail call void asm sideeffect "#TEST ${0:n}", "i"(i32 42)
24 ret i32 42
25 }