Steve King via llvm-dev
2016-Jan-15 01:39 UTC
[llvm-dev] Help handling opaque AArch64 immediates
Hello LLVM, I'm playing with a new ISD::OPAQUE instruction to make hoisting first class and eliminate a lot of tweaky flag setting/checking around opaque constants. It's going well for the IR and x86, but I now I need to sort out details for all the other targets. To start, can someone please advise on the AAarch64 equivalent of these X86 patterns? // Opaque values become mov immediate to register def : Pat<(i64 (opaque imm:$src)), (MOV64ri imm:$src)>; def : Pat<(i32 (opaque imm:$src)), (MOV32ri imm:$src)>; def : Pat<(i16 (opaque imm:$src)), (MOV16ri imm:$src)>; The 'opaque' here is of course hiding the immediate from folding. What I'm looking for is the AAarch64 equivalent to copying the opaque immediate into a register. I promise your help won't be construed as an endorsement of the ISD::OPAQUE idea :) Thanks, -steve
Tim Northover via llvm-dev
2016-Jan-15 02:26 UTC
[llvm-dev] Help handling opaque AArch64 immediates
On 14 January 2016 at 17:39, Steve King via llvm-dev <llvm-dev at lists.llvm.org> wrote:> // Opaque values become mov immediate to register > def : Pat<(i64 (opaque imm:$src)), (MOV64ri imm:$src)>; > def : Pat<(i32 (opaque imm:$src)), (MOV32ri imm:$src)>;These two are pseudo-instructions: MOVi32imm and MOVi64imm work in basically the same way as the x86 instructions I think. They get expanded into real sequences in AArch64ExpandPseudos.cpp.> def : Pat<(i16 (opaque imm:$src)), (MOV16ri imm:$src)>;This is slightly different, the instruction is most likely MOVZWi, with two wrinkles: i16 isn't a legal type and there's an extra "shift amount" immediate. For your purposes something along the lines of def : Pat<(i64 (opaque (imm0_65535 imm:$src))), (MOVZWi imm:$src, 0)>; is probably right (untested, I'm afraid, but it should contain the essential ingredients). Cheers. Tim.
Tim Northover via llvm-dev
2016-Jan-15 02:28 UTC
[llvm-dev] Help handling opaque AArch64 immediates
> def : Pat<(i64 (opaque (imm0_65535 imm:$src))), (MOVZWi imm:$src, 0)>;Sorry, that should certainly not be i64 in there. def : Pat<(i32 (opaque (imm0_65535 imm:$src))), (MOVZWi imm:$src, 0)>; is more likely. Tim.
Steve King via llvm-dev
2016-Jan-15 20:10 UTC
[llvm-dev] Help handling opaque AArch64 immediates
On Thu, Jan 14, 2016 at 6:26 PM, Tim Northover <t.p.northover at gmail.com> wrote:> On 14 January 2016 at 17:39, Steve King via llvm-dev > <llvm-dev at lists.llvm.org> wrote: >> // Opaque values become mov immediate to register >> def : Pat<(i64 (opaque imm:$src)), (MOV64ri imm:$src)>; >> def : Pat<(i32 (opaque imm:$src)), (MOV32ri imm:$src)>; > > These two are pseudo-instructions: MOVi32imm and MOVi64imm work in > basically the same way as the x86 instructions I think. They get > expanded into real sequences in AArch64ExpandPseudos.cpp. >Thanks Tim! Ignoring the 16-bit issue for the moment, I have your suggested pattern: def : Pat<(i64 (opaque imm:$src)), (MOVi64imm imm:$src)>; def : Pat<(i32 (opaque imm:$src)), (MOVi32imm imm:$src)>; LLVM is happy, except a test fails with what I think is a 64-bit vs. 32-bit discrepancy. test/CodeGen/AArch64/arm64-const-addr.ll:8:10: error: expected string not found in input ; CHECK: movz w8, #0x40f, lsl #16 ^ <stdin>:3:2: note: scanning from here .align 2 ^ <stdin>:6:2: note: possible intended match here movz x8, #0x40f, lsl #16 The test wants a movz w8 (32-bit), but opaque lowering produced a movz x8 (64-bit). Since the constant pointer is born as "inttoptr i64", is movz x8 be correct and the test wrong? Thanks, -steve Full test file: ; RUN: llc -mtriple=arm64-darwin-unknown < %s | FileCheck %s %T = type { i32, i32, i32, i32 } ; Test if the constant base address gets only materialized once. define i32 @test1() nounwind { ; CHECK-LABEL: test1 ; CHECK: movz w8, #0x40f, lsl #16 ; CHECK-NEXT: movk w8, #0xc000 ; CHECK-NEXT: ldp w9, w10, [x8, #4] ; CHECK: ldr w8, [x8, #12] %at = inttoptr i64 68141056 to %T* %o1 = getelementptr %T, %T* %at, i32 0, i32 1 %t1 = load i32, i32* %o1 %o2 = getelementptr %T, %T* %at, i32 0, i32 2 %t2 = load i32, i32* %o2 %a1 = add i32 %t1, %t2 %o3 = getelementptr %T, %T* %at, i32 0, i32 3 %t3 = load i32, i32* %o3 %a2 = add i32 %a1, %t3 ret i32 %a2 }
Seemingly Similar Threads
- [LLVMdev] [PATCH][Review request] tablegen: extend list fields
- [LLVMdev] [llvm-commits] [PATCH][Review request] tablegen: extend list fields
- [LLVMdev] [llvm-commits] [PATCH][Review request] tablegen: extend list fields
- [LLVMdev] [AArch64] Question about far call
- How vregs are assigned to operands in IR