mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-01 05:01:59 +01:00
7bd29ba25d
Summary: If aligment on `LoadInst` isn't specified, load is assumed to be ABI-aligned. And said aligment may be different for different types. So if we change load type, but don't pay extra attention to the aligment (i.e. keep it unspecified), we may either overpromise (if the default aligment of the new type is higher), or underpromise (if the default aligment of the new type is smaller). Thus, if no alignment is specified, we need to manually preserve the implied ABI alignment. This addresses https://bugs.llvm.org/show_bug.cgi?id=44543 by making combineLoadToNewType preserve ABI alignment of the load. Reviewers: spatel, lebedev.ri Subscribers: hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D72710
102 lines
2.4 KiB
LLVM
102 lines
2.4 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
; RUN: opt -instcombine -S < %s | FileCheck %s
|
|
|
|
target datalayout = "p:64:64:64-i64:32:32"
|
|
|
|
|
|
define i64* @test1(i8* %x) {
|
|
; CHECK-LABEL: @test1(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = bitcast i8* [[X:%.*]] to i64**
|
|
; CHECK-NEXT: [[B1:%.*]] = load i64*, i64** [[TMP0]], align 4
|
|
; CHECK-NEXT: ret i64* [[B1]]
|
|
;
|
|
entry:
|
|
%a = bitcast i8* %x to i64*
|
|
%b = load i64, i64* %a
|
|
%c = inttoptr i64 %b to i64*
|
|
|
|
ret i64* %c
|
|
}
|
|
|
|
define i32* @test2(i8* %x) {
|
|
; CHECK-LABEL: @test2(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A:%.*]] = bitcast i8* [[X:%.*]] to i32*
|
|
; CHECK-NEXT: [[B:%.*]] = load i32, i32* [[A]], align 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[B]] to i64
|
|
; CHECK-NEXT: [[C:%.*]] = inttoptr i64 [[TMP0]] to i32*
|
|
; CHECK-NEXT: ret i32* [[C]]
|
|
;
|
|
entry:
|
|
%a = bitcast i8* %x to i32*
|
|
%b = load i32, i32* %a
|
|
%c = inttoptr i32 %b to i32*
|
|
|
|
ret i32* %c
|
|
}
|
|
|
|
define i64* @test3(i8* %x) {
|
|
; CHECK-LABEL: @test3(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[A:%.*]] = bitcast i8* [[X:%.*]] to i32*
|
|
; CHECK-NEXT: [[B:%.*]] = load i32, i32* [[A]], align 4
|
|
; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[B]] to i64
|
|
; CHECK-NEXT: [[C:%.*]] = inttoptr i64 [[TMP0]] to i64*
|
|
; CHECK-NEXT: ret i64* [[C]]
|
|
;
|
|
entry:
|
|
%a = bitcast i8* %x to i32*
|
|
%b = load i32, i32* %a
|
|
%c = inttoptr i32 %b to i64*
|
|
|
|
ret i64* %c
|
|
}
|
|
|
|
define i64 @test4(i8* %x) {
|
|
; CHECK-LABEL: @test4(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = bitcast i8* [[X:%.*]] to i64*
|
|
; CHECK-NEXT: [[B1:%.*]] = load i64, i64* [[TMP0]], align 8
|
|
; CHECK-NEXT: ret i64 [[B1]]
|
|
;
|
|
entry:
|
|
%a = bitcast i8* %x to i64**
|
|
%b = load i64*, i64** %a
|
|
%c = ptrtoint i64* %b to i64
|
|
|
|
ret i64 %c
|
|
}
|
|
|
|
define i32 @test5(i8* %x) {
|
|
; CHECK-LABEL: @test5(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = bitcast i8* [[X:%.*]] to i64*
|
|
; CHECK-NEXT: [[B1:%.*]] = load i64, i64* [[TMP0]], align 8
|
|
; CHECK-NEXT: [[C:%.*]] = trunc i64 [[B1]] to i32
|
|
; CHECK-NEXT: ret i32 [[C]]
|
|
;
|
|
entry:
|
|
%a = bitcast i8* %x to i32**
|
|
%b = load i32*, i32** %a
|
|
%c = ptrtoint i32* %b to i32
|
|
|
|
ret i32 %c
|
|
}
|
|
|
|
define i64 @test6(i8* %x) {
|
|
; CHECK-LABEL: @test6(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = bitcast i8* [[X:%.*]] to i64*
|
|
; CHECK-NEXT: [[B1:%.*]] = load i64, i64* [[TMP0]], align 8
|
|
; CHECK-NEXT: ret i64 [[B1]]
|
|
;
|
|
entry:
|
|
%a = bitcast i8* %x to i32**
|
|
%b = load i32*, i32** %a
|
|
%c = ptrtoint i32* %b to i64
|
|
|
|
ret i64 %c
|
|
}
|
|
|