From eee61558f44892eebbb483215db23bb760968883 Mon Sep 17 00:00:00 2001 From: Andrei Safronov Date: Thu, 6 Feb 2025 02:26:37 +0300 Subject: [PATCH 1/2] [Xtensa] Implement Xtensa Boolean Option. --- .../Disassembler/XtensaDisassembler.cpp | 16 +++++ .../MCTargetDesc/XtensaMCTargetDesc.cpp | 2 + llvm/lib/Target/Xtensa/XtensaFeatures.td | 5 ++ llvm/lib/Target/Xtensa/XtensaISelLowering.cpp | 4 ++ llvm/lib/Target/Xtensa/XtensaInstrInfo.td | 70 +++++++++++++++++++ llvm/lib/Target/Xtensa/XtensaRegisterInfo.td | 24 ++++++- llvm/lib/Target/Xtensa/XtensaSubtarget.h | 5 ++ llvm/test/MC/Disassembler/Xtensa/boolean.txt | 59 ++++++++++++++++ llvm/test/MC/Xtensa/boolean.s | 58 +++++++++++++++ 9 files changed, 242 insertions(+), 1 deletion(-) create mode 100644 llvm/test/MC/Disassembler/Xtensa/boolean.txt create mode 100644 llvm/test/MC/Xtensa/boolean.s diff --git a/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp b/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp index 7ad8a87ed599a..27d1cc9c8177c 100644 --- a/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp +++ b/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp @@ -98,6 +98,22 @@ static DecodeStatus DecodeSRRegisterClass(MCInst &Inst, uint64_t RegNo, return MCDisassembler::Fail; } +const unsigned BRDecoderTable[] = { + Xtensa::B0, Xtensa::B1, Xtensa::B2, Xtensa::B3, Xtensa::B4, Xtensa::B5, + Xtensa::B6, Xtensa::B7, Xtensa::B8, Xtensa::B9, Xtensa::B10, Xtensa::B11, + Xtensa::B12, Xtensa::B13, Xtensa::B14, Xtensa::B15}; + +static DecodeStatus DecodeBRRegisterClass(MCInst &Inst, uint64_t RegNo, + uint64_t Address, + const void *Decoder) { + if (RegNo >= std::size(BRDecoderTable)) + return MCDisassembler::Fail; + + unsigned Reg = BRDecoderTable[RegNo]; + Inst.addOperand(MCOperand::createReg(Reg)); + return MCDisassembler::Success; +} + static bool tryAddingSymbolicOperand(int64_t Value, bool isBranch, uint64_t Address, uint64_t Offset, uint64_t InstSize, MCInst &MI, diff --git a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.cpp b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.cpp index 37dee072e5b3d..adaa9a71a905c 100644 --- a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.cpp +++ b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.cpp @@ -77,6 +77,8 @@ bool Xtensa::isValidAddrOffsetForOpcode(unsigned Opcode, int64_t Offset) { // Verify Special Register bool Xtensa::checkRegister(MCRegister RegNo, const FeatureBitset &FeatureBits) { switch (RegNo) { + case Xtensa::BREG: + return FeatureBits[Xtensa::FeatureBoolean]; case Xtensa::WINDOWBASE: case Xtensa::WINDOWSTART: return FeatureBits[Xtensa::FeatureWindowed]; diff --git a/llvm/lib/Target/Xtensa/XtensaFeatures.td b/llvm/lib/Target/Xtensa/XtensaFeatures.td index 6f24a674ae0ce..b0cbeb9456796 100644 --- a/llvm/lib/Target/Xtensa/XtensaFeatures.td +++ b/llvm/lib/Target/Xtensa/XtensaFeatures.td @@ -12,3 +12,8 @@ def FeatureWindowed : SubtargetFeature<"windowed", "HasWindowed", "true", "Enable Xtensa Windowed Register option">; def HasWindowed : Predicate<"Subtarget->hasWindowed()">, AssemblerPredicate<(all_of FeatureWindowed)>; + +def FeatureBoolean : SubtargetFeature<"bool", "HasBoolean", "true", + "Enable Xtensa Boolean extension">; +def HasBoolean : Predicate<"Subtarget->hasBoolean()">, + AssemblerPredicate<(all_of FeatureBoolean)>; diff --git a/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp b/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp index cdf38a0669479..57f0cbbc36c24 100644 --- a/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp +++ b/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp @@ -49,6 +49,10 @@ XtensaTargetLowering::XtensaTargetLowering(const TargetMachine &TM, // Set up the register classes. addRegisterClass(MVT::i32, &Xtensa::ARRegClass); + if (Subtarget.hasBoolean()) { + addRegisterClass(MVT::v1i1, &Xtensa::BRRegClass); + } + // Set up special registers. setStackPointerRegisterToSaveRestore(Xtensa::SP); diff --git a/llvm/lib/Target/Xtensa/XtensaInstrInfo.td b/llvm/lib/Target/Xtensa/XtensaInstrInfo.td index 5ef795a0e5287..e52dcbf1377c5 100644 --- a/llvm/lib/Target/Xtensa/XtensaInstrInfo.td +++ b/llvm/lib/Target/Xtensa/XtensaInstrInfo.td @@ -779,3 +779,73 @@ def ROTW : RRR_Inst<0x00, 0x00, 0x04, (outs), (ins imm8n_7:$imm), let s = 0x0; let t = imm{3-0}; } + +//===----------------------------------------------------------------------===// +// Boolean Instructions +//===----------------------------------------------------------------------===// + +def ALL4 : RRR_Inst<0x00, 0x00, 0x00, (outs BR:$t), (ins BR:$s), + "all4\t$t, $s", []>, Requires<[HasBoolean]> { + let r = 0x9; +} + +def ALL8 : RRR_Inst<0x00, 0x00, 0x00, (outs BR:$t), (ins BR:$s), + "all8\t$t, $s", []>, Requires<[HasBoolean]> { + let r = 0xB; +} + +def ANDB : RRR_Inst<0x00, 0x02, 0x00, (outs BR:$r), (ins BR:$s, BR:$t), + "andb\t$r, $s, $t", []>, Requires<[HasBoolean]>; +def ANDBC : RRR_Inst<0x00, 0x02, 0x01, (outs BR:$r), (ins BR:$s, BR:$t), + "andbc\t$r, $s, $t", []>, Requires<[HasBoolean]>; +def ORB : RRR_Inst<0x00, 0x02, 0x02, (outs BR:$r), (ins BR:$s, BR:$t), + "orb\t$r, $s, $t", []>, Requires<[HasBoolean]>; +def ORBC : RRR_Inst<0x00, 0x02, 0x03, (outs BR:$r), (ins BR:$s, BR:$t), + "orbc\t$r, $s, $t", []>, Requires<[HasBoolean]>; +def XORB : RRR_Inst<0x00, 0x02, 0x04, (outs BR:$r), (ins BR:$s, BR:$t), + "xorb\t$r, $s, $t", []>, Requires<[HasBoolean]>; + +def ANY4 : RRR_Inst<0x00, 0x00, 0x00, (outs BR:$t), (ins BR:$s), + "any4\t$t, $s", []>, Requires<[HasBoolean]> { + let r = 0x8; +} + +def ANY8 : RRR_Inst<0x00, 0x00, 0x00, (outs BR:$t), (ins BR:$s), + "any8\t$t, $s", []>, Requires<[HasBoolean]> { + let r = 0xA; +} + +let isBranch = 1, isTerminator = 1, Predicates = [HasBoolean] in { + def BT : RRI8_Inst<0x06, (outs), (ins BR:$b, brtarget:$target), + "bt\t$b, $target", []> { + bits<8> target; + bits<4> b; + + let r = 0x1; + let s = b; + let t = 0x7; + let imm8 = target; + } + + def BF : RRI8_Inst<0x06, (outs), (ins BR:$b, brtarget:$target), + "bf\t$b, $target", []> { + bits<8> target; + bits<4> b; + + let r = 0x0; + let s = b; + let t = 0x7; + let imm8 = target; + } +} + +def : InstAlias<"_BT\t$b, $target", (BT BR:$b, brtarget:$target)>; +def : InstAlias<"_BF\t$b, $target", (BF BR:$b, brtarget:$target)>; + +let Constraints = "$dr = $r,@earlyclobber $dr" in { + def MOVF : RRR_Inst<0x00, 0x03, 0x0C, (outs AR:$dr), (ins AR:$r, AR:$s, BR:$t), + "movf\t$r, $s, $t", []>, Requires<[HasBoolean]>; + + def MOVT : RRR_Inst<0x00, 0x03, 0x0D, (outs AR:$dr), (ins AR:$r, AR:$s, BR:$t), + "movt\t$r, $s, $t", []>, Requires<[HasBoolean]>; +} diff --git a/llvm/lib/Target/Xtensa/XtensaRegisterInfo.td b/llvm/lib/Target/Xtensa/XtensaRegisterInfo.td index 09087edc86712..920354ff41ba5 100644 --- a/llvm/lib/Target/Xtensa/XtensaRegisterInfo.td +++ b/llvm/lib/Target/Xtensa/XtensaRegisterInfo.td @@ -64,6 +64,7 @@ def A15 : ARReg<15, "a15">, DwarfRegNum<[15]>; def AR : RegisterClass<"Xtensa", [i32], 32, (add A8, A9, A10, A11, A12, A13, A14, A15, A7, A6, A5, A4, A3, A2, A0, SP)>; + //===----------------------------------------------------------------------===// // Special-purpose registers //===----------------------------------------------------------------------===// @@ -75,8 +76,29 @@ class SRReg num, string n, list alt = []> : XtensaReg { // Shift Amount Register def SAR : SRReg<3, "sar", ["SAR","3"]>; +// Boolean Register +def BREG : SRReg<4, "br", ["BR","4"]>; + // Windowed Register Option registers def WINDOWBASE : SRReg<72, "windowbase", ["WINDOWBASE", "72"]>; def WINDOWSTART : SRReg<73, "windowstart", ["WINDOWSTART", "73"]>; -def SR : RegisterClass<"Xtensa", [i32], 32, (add SAR, WINDOWBASE, WINDOWSTART)>; +def SR : RegisterClass<"Xtensa", [i32], 32, (add SAR, BREG, + WINDOWBASE, WINDOWSTART)>; + +//===----------------------------------------------------------------------===// +// Boolean registers +//===----------------------------------------------------------------------===// +class BReg num, string n> : XtensaReg { + let HWEncoding{3-0} = num; +} + +foreach i = 0-15 in { + def B#i : BReg; +} + +// Boolean register class +def BR : RegisterClass<"Xtensa", [v1i1], 8, (add B0, B1, + B2, B3, B4, B5, B6, B7, B8, B9, B10, B11, B12, B13, B14, B15)> { + let Size = 8; +} diff --git a/llvm/lib/Target/Xtensa/XtensaSubtarget.h b/llvm/lib/Target/Xtensa/XtensaSubtarget.h index dddc0f7ef605d..ef83bcc987027 100644 --- a/llvm/lib/Target/Xtensa/XtensaSubtarget.h +++ b/llvm/lib/Target/Xtensa/XtensaSubtarget.h @@ -42,6 +42,9 @@ class XtensaSubtarget : public XtensaGenSubtargetInfo { // Enabled Xtensa Windowed Register Option bool HasWindowed; + // Enabled Boolean Option + bool HasBoolean; + XtensaSubtarget &initializeSubtargetDependencies(StringRef CPU, StringRef FS); public: @@ -69,6 +72,8 @@ class XtensaSubtarget : public XtensaGenSubtargetInfo { bool hasWindowed() const { return HasWindowed; } + bool hasBoolean() const { return HasBoolean; } + // Automatically generated by tblgen. void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS); }; diff --git a/llvm/test/MC/Disassembler/Xtensa/boolean.txt b/llvm/test/MC/Disassembler/Xtensa/boolean.txt new file mode 100644 index 0000000000000..5763db6b4f166 --- /dev/null +++ b/llvm/test/MC/Disassembler/Xtensa/boolean.txt @@ -0,0 +1,59 @@ +# NOTE: Assertions have been autogenerated by utils/update_mc_test_checks.py UTC_ARGS: --version 5 +# RUN: llvm-mc -triple=xtensa -mattr=+bool -disassemble %s | FileCheck -check-prefixes=CHECK-BOOLEAN %s +# RUN: not llvm-mc -triple=xtensa -disassemble %s 2>&1 | FileCheck --implicit-check-not=warning: -check-prefixes=CHECK-CORE %s + +## Verify that binary code is correctly disassembled with +## boolean option enabled. Also verify that dissasembling without +## boolean option generates warnings. + +[0x10,0x94,0x00] +# CHECK-BOOLEAN: all4 b1, b4 +# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding + +[0x10,0xb8,0x00] +# CHECK-BOOLEAN: all8 b1, b8 +# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding + +[0x30,0x12,0x02] +# CHECK-BOOLEAN: andb b1, b2, b3 +# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding + +[0x30,0x12,0x12] +# CHECK-BOOLEAN: andbc b1, b2, b3 +# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding + +[0x30,0x12,0x22] +# CHECK-BOOLEAN: orb b1, b2, b3 +# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding + +[0x30,0x12,0x32] +# CHECK-BOOLEAN: orbc b1, b2, b3 +# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding + +[0x30,0x12,0x42] +# CHECK-BOOLEAN: xorb b1, b2, b3 +# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding + +[0x10,0x84,0x00] +# CHECK-BOOLEAN: any4 b1, b4 +# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding + +[0x10,0xa8,0x00] +# CHECK-BOOLEAN: any8 b1, b8 +# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding + +[0x76,0x11,0x10] +# CHECK-BOOLEAN: bt b1, . +20 +# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding + +[0x76,0x00,0x10] +# CHECK-BOOLEAN: bf b0, . +20 +# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding + +[0x10,0x23,0xc3] +# CHECK-BOOLEAN: movf a2, a3, b1 +# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding + +[0x20,0x34,0xd3] +# CHECK-BOOLEAN: movt a3, a4, b2 +# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding diff --git a/llvm/test/MC/Xtensa/boolean.s b/llvm/test/MC/Xtensa/boolean.s new file mode 100644 index 0000000000000..1bd64b82718d3 --- /dev/null +++ b/llvm/test/MC/Xtensa/boolean.s @@ -0,0 +1,58 @@ +# RUN: llvm-mc %s -triple=xtensa -show-encoding --mattr=+bool \ +# RUN: | FileCheck -check-prefixes=CHECK,CHECK-INST %s + +.align 4 +// CHECK: .p2align 4 + +LBL0: +// CHECK: LBL0: + +all4 b1, b4 +// CHECK: all4 b1, b4 # encoding: [0x10,0x94,0x00] + +all8 b1, b8 +// CHECK: all8 b1, b8 # encoding: [0x10,0xb8,0x00] + +andb b1, b2, b3 +// CHECK: andb b1, b2, b3 # encoding: [0x30,0x12,0x02] + +andbc b1, b2, b3 +// CHECK: andbc b1, b2, b3 # encoding: [0x30,0x12,0x12] + +orb b1, b2, b3 +// CHECK: orb b1, b2, b3 # encoding: [0x30,0x12,0x22] + +orbc b1, b2, b3 +// CHECK: orbc b1, b2, b3 # encoding: [0x30,0x12,0x32] + +xorb b1, b2, b3 +// CHECK: xorb b1, b2, b3 # encoding: [0x30,0x12,0x42] + +any4 b1, b4 +// CHECK: any4 b1, b4 # encoding: [0x10,0x84,0x00] + +any8 b1, b8 +// CHECK: any8 b1, b8 # encoding: [0x10,0xa8,0x00] + +bt b1, LBL0 +// CHECK: bt b1, LBL0 # encoding: [0x76,0x11,A] +// CHECK-NEXT: # fixup A - offset: 0, value: LBL0, kind: fixup_xtensa_branch_8 + +bf b0, LBL0 +// CHECK: bf b0, LBL0 # encoding: [0x76,0x00,A] +// CHECK-NEXT: # fixup A - offset: 0, value: LBL0, kind: fixup_xtensa_branch_8 + +movf a2, a3, b1 +// CHECK: movf a2, a3, b1 # encoding: [0x10,0x23,0xc3] + +movt a3, a4, b2 +// CHECK: movt a3, a4, b2 # encoding: [0x20,0x34,0xd3] + +xsr a3, br +// CHECK: xsr a3, br # encoding: [0x30,0x04,0x61] + +xsr.br a3 +// CHECK: xsr a3, br # encoding: [0x30,0x04,0x61] + +xsr a3, 4 +// CHECK: xsr a3, br # encoding: [0x30,0x04,0x61] From d149bcb4b856ca5d211964bc276d525c561882e2 Mon Sep 17 00:00:00 2001 From: Andrei Safronov Date: Sat, 15 Feb 2025 02:21:45 +0300 Subject: [PATCH 2/2] [Xtensa] Minor fixed in disassembler and subtarget. Fix boolean test. --- .../Xtensa/Disassembler/XtensaDisassembler.cpp | 12 ++++++------ llvm/lib/Target/Xtensa/XtensaSubtarget.cpp | 2 -- llvm/lib/Target/Xtensa/XtensaSubtarget.h | 12 ++++-------- llvm/test/MC/Xtensa/boolean.s | 2 +- 4 files changed, 11 insertions(+), 17 deletions(-) diff --git a/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp b/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp index 27d1cc9c8177c..b1027488904df 100644 --- a/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp +++ b/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp @@ -57,7 +57,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeXtensaDisassembler() { createXtensaDisassembler); } -const unsigned ARDecoderTable[] = { +const MCPhysReg ARDecoderTable[] = { Xtensa::A0, Xtensa::SP, Xtensa::A2, Xtensa::A3, Xtensa::A4, Xtensa::A5, Xtensa::A6, Xtensa::A7, Xtensa::A8, Xtensa::A9, Xtensa::A10, Xtensa::A11, Xtensa::A12, Xtensa::A13, Xtensa::A14, Xtensa::A15}; @@ -68,12 +68,12 @@ static DecodeStatus DecodeARRegisterClass(MCInst &Inst, uint64_t RegNo, if (RegNo >= std::size(ARDecoderTable)) return MCDisassembler::Fail; - unsigned Reg = ARDecoderTable[RegNo]; + MCPhysReg Reg = ARDecoderTable[RegNo]; Inst.addOperand(MCOperand::createReg(Reg)); return MCDisassembler::Success; } -const unsigned SRDecoderTable[] = { +const MCPhysReg SRDecoderTable[] = { Xtensa::SAR, 3, Xtensa::WINDOWBASE, 72, Xtensa::WINDOWSTART, 73}; static DecodeStatus DecodeSRRegisterClass(MCInst &Inst, uint64_t RegNo, @@ -84,7 +84,7 @@ static DecodeStatus DecodeSRRegisterClass(MCInst &Inst, uint64_t RegNo, for (unsigned i = 0; i < std::size(SRDecoderTable); i += 2) { if (SRDecoderTable[i + 1] == RegNo) { - unsigned Reg = SRDecoderTable[i]; + MCPhysReg Reg = SRDecoderTable[i]; if (!Xtensa::checkRegister(Reg, Decoder->getSubtargetInfo().getFeatureBits())) @@ -98,7 +98,7 @@ static DecodeStatus DecodeSRRegisterClass(MCInst &Inst, uint64_t RegNo, return MCDisassembler::Fail; } -const unsigned BRDecoderTable[] = { +const MCPhysReg BRDecoderTable[] = { Xtensa::B0, Xtensa::B1, Xtensa::B2, Xtensa::B3, Xtensa::B4, Xtensa::B5, Xtensa::B6, Xtensa::B7, Xtensa::B8, Xtensa::B9, Xtensa::B10, Xtensa::B11, Xtensa::B12, Xtensa::B13, Xtensa::B14, Xtensa::B15}; @@ -109,7 +109,7 @@ static DecodeStatus DecodeBRRegisterClass(MCInst &Inst, uint64_t RegNo, if (RegNo >= std::size(BRDecoderTable)) return MCDisassembler::Fail; - unsigned Reg = BRDecoderTable[RegNo]; + MCPhysReg Reg = BRDecoderTable[RegNo]; Inst.addOperand(MCOperand::createReg(Reg)); return MCDisassembler::Success; } diff --git a/llvm/lib/Target/Xtensa/XtensaSubtarget.cpp b/llvm/lib/Target/Xtensa/XtensaSubtarget.cpp index d6b1b4bc15463..6b1d3255db247 100644 --- a/llvm/lib/Target/Xtensa/XtensaSubtarget.cpp +++ b/llvm/lib/Target/Xtensa/XtensaSubtarget.cpp @@ -30,8 +30,6 @@ XtensaSubtarget::initializeSubtargetDependencies(StringRef CPU, StringRef FS) { CPUName = "generic"; } - HasDensity = false; - // Parse features string. ParseSubtargetFeatures(CPUName, CPUName, FS); return *this; diff --git a/llvm/lib/Target/Xtensa/XtensaSubtarget.h b/llvm/lib/Target/Xtensa/XtensaSubtarget.h index ef83bcc987027..962bed2c2e36f 100644 --- a/llvm/lib/Target/Xtensa/XtensaSubtarget.h +++ b/llvm/lib/Target/Xtensa/XtensaSubtarget.h @@ -36,14 +36,10 @@ class XtensaSubtarget : public XtensaGenSubtargetInfo { SelectionDAGTargetInfo TSInfo; XtensaFrameLowering FrameLowering; - // Enabled Xtensa Density Option - bool HasDensity; - - // Enabled Xtensa Windowed Register Option - bool HasWindowed; - - // Enabled Boolean Option - bool HasBoolean; +// Bool members corresponding to the SubtargetFeatures defined in tablegen +#define GET_SUBTARGETINFO_MACRO(ATTRIBUTE, DEFAULT, GETTER) \ + bool ATTRIBUTE = DEFAULT; +#include "XtensaGenSubtargetInfo.inc" XtensaSubtarget &initializeSubtargetDependencies(StringRef CPU, StringRef FS); diff --git a/llvm/test/MC/Xtensa/boolean.s b/llvm/test/MC/Xtensa/boolean.s index 1bd64b82718d3..6429370558e0c 100644 --- a/llvm/test/MC/Xtensa/boolean.s +++ b/llvm/test/MC/Xtensa/boolean.s @@ -1,5 +1,5 @@ # RUN: llvm-mc %s -triple=xtensa -show-encoding --mattr=+bool \ -# RUN: | FileCheck -check-prefixes=CHECK,CHECK-INST %s +# RUN: | FileCheck -check-prefixes=CHECK %s .align 4 // CHECK: .p2align 4