mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-15 04:30:12 +00:00
cc7052343e
Stop folding constant adds into GEP when the type size doesn't match. Otherwise, the adds' operands are effectively being promoted, changing the conditions of an overflow. Results are different when: sext(a) + sext(b) != sext(a + b) Problem originally found on x86-64, but also fixed issues with ARM and PPC, which used similar code. <rdar://problem/15292280> Patch by Duncan Exon Smith! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@194840 91177308-0d34-0410-b5e6-96231b3b80d8
38 lines
1.0 KiB
LLVM
38 lines
1.0 KiB
LLVM
; fastisel should not fold add with non-pointer bitwidth
|
|
; sext(a) + sext(b) != sext(a + b)
|
|
; RUN: llc -mtriple=x86_64-apple-darwin %s -O0 -o - | FileCheck %s
|
|
|
|
define zeroext i8 @gep_promotion(i8* %ptr) nounwind uwtable ssp {
|
|
entry:
|
|
%ptr.addr = alloca i8*, align 8
|
|
%add = add i8 64, 64 ; 0x40 + 0x40
|
|
%0 = load i8** %ptr.addr, align 8
|
|
|
|
; CHECK-LABEL: _gep_promotion:
|
|
; CHECK: movzbl ({{.*}})
|
|
%arrayidx = getelementptr inbounds i8* %0, i8 %add
|
|
|
|
%1 = load i8* %arrayidx, align 1
|
|
ret i8 %1
|
|
}
|
|
|
|
define zeroext i8 @gep_promotion_nonconst(i8 %i, i8* %ptr) nounwind uwtable ssp {
|
|
entry:
|
|
%i.addr = alloca i8, align 4
|
|
%ptr.addr = alloca i8*, align 8
|
|
store i8 %i, i8* %i.addr, align 4
|
|
store i8* %ptr, i8** %ptr.addr, align 8
|
|
%0 = load i8* %i.addr, align 4
|
|
; CHECK-LABEL: _gep_promotion_nonconst:
|
|
; CHECK: movzbl ({{.*}})
|
|
%xor = xor i8 %0, -128 ; %0 ^ 0x80
|
|
%add = add i8 %xor, -127 ; %xor + 0x81
|
|
%1 = load i8** %ptr.addr, align 8
|
|
|
|
%arrayidx = getelementptr inbounds i8* %1, i8 %add
|
|
|
|
%2 = load i8* %arrayidx, align 1
|
|
ret i8 %2
|
|
}
|
|
|