Eric Bentura
2015-Jul-07 13:06 UTC
[LLVMdev] ARM Jump table pcrelative relaxation in clang / llc
I have created a small ll file to reproduce the problem.
I used the intrinsic function llvm.arm.space to introduce space between the
beginning of the code and the jump table.
If the first argument of llvm.arm.space is higher than INT_MAX (
*2147483647)*, then the bug is hit. Lower or equal to that value, it
passes. It looks like a precision issue. Does this sound familiar to
someone?
; ModuleID = 'test.c'
target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
target triple = "armv5e-none-linux-androideabi"
declare i32 @llvm.arm.space(i32, i32)
; Function Attrs: nounwind
define i32 @main() #0 {
entry:
%retval = alloca i32, align 4
%a = alloca i32, align 4
store i32 0, i32* %retval
store i32 0, i32* %a, align 4
%0 = load i32* %a, align 4
call i32 @llvm.arm.space(i32* 2147483647*, i32 undef)
switch i32 %0, label %sw.default [
i32 0, label %sw.bb
i32 1, label %sw.bb1
i32 2, label %sw.bb2
i32 3, label %sw.bb3
]
sw.bb: ; preds = %entry
store i32 1, i32* %retval
br label %return
sw.bb1: ; preds = %entry
store i32 2, i32* %retval
br label %return
sw.bb2: ; preds = %entry
store i32 3, i32* %retval
br label %return
sw.bb3: ; preds = %entry
store i32 4, i32* %retval
br label %return
sw.default: ; preds = %entry
br label %sw.epilog
sw.epilog: ; preds = %sw.default
store i32 0, i32* %retval
br label %return
return: ; preds = %sw.epilog,
%sw.bb3, %sw.bb2, %sw.bb1, %sw.bb
%2 = load i32* %retval
ret i32 %2
}
; Function Attrs: nounwind
declare i32 @rand() #0
attributes #0 = { nounwind "less-precise-fpmad"="false"
"no-frame-pointer-elim"="true"
"no-frame-pointer-elim-non-leaf"
"no-infs-fp-math"="false"
"no-nans-fp-math"="false"
"stack-protector-buffer-size"="8"
"unsafe-fp-math"="false"
"use-soft-float"="true" }
attributes #1 = { nounwind }
!llvm.module.flags = !{!0, !1, !2}
!llvm.ident = !{!3}
!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{i32 1, !"min_enum_size", i32 4}
!2 = !{i32 1, !"PIC Level", i32 1}
!3 = !{!"clang version 3.7.0 (trunk 229364)"}
2015-07-06 21:13 GMT+03:00 Eric Bentura <ebentura at gmail.com>:
> It is certainly helping - Thanks Renato.
>
> 2015-07-06 18:39 GMT+03:00 Renato Golin <renato.golin at linaro.org>:
>
>> On 6 July 2015 at 16:32, Eric Bentura <ebentura at gmail.com>
wrote:
>> > I tried to build the object file using clang 3.7 and it fails with
the
>> same
>> > error.
>> > Where should I look at in the ARM backend to understand what
happens?
>> > Where the jump table instruction is generated and supposed to be
>> relaxed?
>>
>> Have a look at lib/Target/ARM/ARMConstantIslandPass.cpp, especially
>> where Tim's patch touches:
>>
>> http://llvm.org/viewvc/llvm-project?view=revision&revision=238680
>>
>> Instruction relaxation rules should be in the TableGen files, I think,
>> but that means it could be in a number of places.
>>
>> Step through lib/Target/ARM/ARMAsmPrinter.cpp, at
>> ARMAsmPrinter::EmitJumpTableInsts and see what the operand is.
>>
>> You'd expect that it would be already relaxed by that point. If it
is,
>> the bug is in the printer. If not, it could be in the instruction
>> selection process, either ARMISelLowering or during validation, at
>> ARMISelDAGToDAG.
>>
>> Hope that helps.
>>
>> cheers,
>> --renato
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://lists.llvm.org/pipermail/llvm-dev/attachments/20150707/a158a1e2/attachment.html>
Tim Northover
2015-Jul-07 15:06 UTC
[LLVMdev] ARM Jump table pcrelative relaxation in clang / llc
On 7 July 2015 at 06:06, Eric Bentura <ebentura at gmail.com> wrote:> I have created a small ll file to reproduce the problem. > I used the intrinsic function llvm.arm.space to introduce space between the > beginning of the code and the jump table.It does look like the value in @llvm.arm.space is interpreted incorrectly if it's bigger than INT_MAX, but that's well outside its intended range and could inevitably be used to break ConstantIslands (the longest ARM immediate branch is 26-bits; no indivisible entity in .text can be bigger than that). It's probably an unrelated issue. Also, I know I said the backend should accept any size code, but 2GB is definitely going to trigger more edge cases than average. Cheers. Tim.
Eric Bentura
2015-Jul-13 12:41 UTC
[LLVMdev] ARM Jump table pcrelative relaxation in clang / llc
Hi,
I have kept working on this and found the following (as llvm 3.5):
1) In the function MCObjectStreamer::EmitInstruction there is a check for
the instruction being relaxable or not:
if (!Assembler.getBackend().mayNeedRelaxation(Inst)) {
EmitInstToData(Inst, STI);
return;
}
At this stage, the instruction as been already selected to be ARM::ADR.
The call to mayNeed
2015-07-07 18:06 GMT+03:00 Tim Northover <t.p.northover at gmail.com>:
> On 7 July 2015 at 06:06, Eric Bentura <ebentura at gmail.com> wrote:
> > I have created a small ll file to reproduce the problem.
> > I used the intrinsic function llvm.arm.space to introduce space
between
> the
> > beginning of the code and the jump table.
>
> It does look like the value in @llvm.arm.space is interpreted
> incorrectly if it's bigger than INT_MAX, but that's well outside
its
> intended range and could inevitably be used to break ConstantIslands
> (the longest ARM immediate branch is 26-bits; no indivisible entity in
> .text can be bigger than that). It's probably an unrelated issue.
>
> Also, I know I said the backend should accept any size code, but 2GB
> is definitely going to trigger more edge cases than average.
>
> Cheers.
>
> Tim.
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://lists.llvm.org/pipermail/llvm-dev/attachments/20150713/602e32d9/attachment.html>
Reasonably Related Threads
- [LLVMdev] ARM Jump table pcrelative relaxation in clang / llc
- [LLVMdev] ARM Jump table pcrelative relaxation in clang / llc
- [LLVMdev] ARM Jump table pcrelative relaxation in clang / llc
- Branch relaxation at assembler level (RISCV)
- [MC] Questions about relaxation in MC