mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-14 11:32:34 +00:00
333d5c9f51
stored rather than the pointer type. This change is analogous to r220138 which changed the canonicalization for loads. The rationale is the same: memory does not have a type, operations (and thus the values they produce) have a type. We should match that type as closely as possible rather than reading some form of semantics into the pointer type. With this change, loads and stores should no longer be made with nonsensical types for the values that tehy load and store. This is particularly important when trying to match specific loaded and stored types in the process of doing other instcombines, which is what led me down this twisty maze of miscanonicalization. I've put quite some effort into looking through IR to find places where LLVM's optimizer was being unreasonably conservative in the face of mismatched load and store types, however it is possible (let's say, likely!) I have missed some. If you see regressions here, or from r220138, the likely cause is some part of LLVM failing to cope with load and store types differing. Test cases appreciated, it is important that we root all of these out of LLVM. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@222748 91177308-0d34-0410-b5e6-96231b3b80d8
65 lines
1.9 KiB
LLVM
65 lines
1.9 KiB
LLVM
; RUN: opt -S -instcombine < %s | FileCheck %s
|
|
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128-n8:16:32"
|
|
target triple = "i386-apple-darwin10.0.0"
|
|
|
|
; CHECK-LABEL: define void @fu1(
|
|
define void @fu1(i32 %parm) nounwind ssp {
|
|
%1 = alloca i32, align 4
|
|
; CHECK: alloca double*
|
|
%ptr = alloca double*, align 4
|
|
store i32 %parm, i32* %1, align 4
|
|
store double* null, double** %ptr, align 4
|
|
%2 = load i32* %1, align 4
|
|
%3 = icmp ne i32 %2, 0
|
|
br i1 %3, label %4, label %10
|
|
|
|
; <label>:4 ; preds = %0
|
|
%5 = load i32* %1, align 4
|
|
%6 = shl nsw i32 %5, 3
|
|
; With "nsw", the alloca and its bitcast can be fused:
|
|
%7 = add nsw i32 %6, 2048
|
|
; CHECK: alloca double
|
|
%8 = alloca i8, i32 %7
|
|
%9 = bitcast i8* %8 to double*
|
|
; CHECK-NEXT: store double*
|
|
store double* %9, double** %ptr, align 4
|
|
br label %10
|
|
; <label>:10 ; preds = %4, %0
|
|
%11 = load double** %ptr, align 4
|
|
call void @bar(double* %11)
|
|
; CHECK: ret
|
|
ret void
|
|
}
|
|
|
|
declare void @bar(double*)
|
|
|
|
; CHECK-LABEL: define void @fu2(
|
|
define void @fu2(i32 %parm) nounwind ssp {
|
|
%1 = alloca i32, align 4
|
|
%ptr = alloca double*, align 4
|
|
store i32 %parm, i32* %1, align 4
|
|
store double* null, double** %ptr, align 4
|
|
%2 = load i32* %1, align 4
|
|
%3 = icmp ne i32 %2, 0
|
|
br i1 %3, label %4, label %10
|
|
|
|
; <label>:4 ; preds = %0
|
|
%5 = load i32* %1, align 4
|
|
%6 = mul nsw i32 %5, 8
|
|
; Without "nsw", the alloca and its bitcast cannot be fused:
|
|
%7 = add i32 %6, 2048
|
|
; CHECK: alloca i8
|
|
%8 = alloca i8, i32 %7
|
|
; CHECK-NEXT: bitcast double**
|
|
; CHECK-NEXT: store i8*
|
|
%9 = bitcast i8* %8 to double*
|
|
store double* %9, double** %ptr, align 4
|
|
br label %10
|
|
|
|
; <label>:10 ; preds = %4, %0
|
|
%11 = load double** %ptr, align 4
|
|
call void @bar(double* %11)
|
|
ret void
|
|
}
|
|
|