; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt < %s -data-layout="e-p:32:32:32-p1:16:16:16-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-n8:16:32" -basic-aa -gvn -S -dce | FileCheck %s
-; RUN: opt < %s -data-layout="E-p:32:32:32-p1:16:16:16-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-n32" -basic-aa -gvn -S -dce | FileCheck %s
+; RUN: opt < %s -data-layout="e-p:32:32:32-p1:16:16:16-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-n8:16:32" -basic-aa -gvn -S -dce | FileCheck %s --check-prefixes=CHECK,LE
+; RUN: opt < %s -data-layout="E-p:32:32:32-p1:16:16:16-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-n32" -basic-aa -gvn -S -dce | FileCheck %s --check-prefixes=CHECK,BE
;; Trivial RLE test.
define i32 @test0(i32 %V, i32* %P) {
;; i32 -> i8 forwarding
define i8 @coerce_mustalias5(i32 %V, i32* %P) {
+; LE-LABEL: @coerce_mustalias5(
+; LE-NEXT: store i32 [[V:%.*]], i32* [[P:%.*]], align 4
+; LE-NEXT: [[TMP1:%.*]] = trunc i32 [[V]] to i8
+; LE-NEXT: ret i8 [[TMP1]]
+;
+; BE-LABEL: @coerce_mustalias5(
+; BE-NEXT: store i32 [[V:%.*]], i32* [[P:%.*]], align 4
+; BE-NEXT: [[TMP1:%.*]] = lshr i32 [[V]], 24
+; BE-NEXT: [[TMP2:%.*]] = trunc i32 [[TMP1]] to i8
+; BE-NEXT: ret i8 [[TMP2]]
+;
store i32 %V, i32* %P
%P2 = bitcast i32* %P to i8*
;; i64 -> float forwarding
define float @coerce_mustalias6(i64 %V, i64* %P) {
+; LE-LABEL: @coerce_mustalias6(
+; LE-NEXT: store i64 [[V:%.*]], i64* [[P:%.*]], align 4
+; LE-NEXT: [[TMP1:%.*]] = trunc i64 [[V]] to i32
+; LE-NEXT: [[TMP2:%.*]] = bitcast i32 [[TMP1]] to float
+; LE-NEXT: ret float [[TMP2]]
+;
+; BE-LABEL: @coerce_mustalias6(
+; BE-NEXT: store i64 [[V:%.*]], i64* [[P:%.*]], align 4
+; BE-NEXT: [[TMP1:%.*]] = lshr i64 [[V]], 32
+; BE-NEXT: [[TMP2:%.*]] = trunc i64 [[TMP1]] to i32
+; BE-NEXT: [[TMP3:%.*]] = bitcast i32 [[TMP2]] to float
+; BE-NEXT: ret float [[TMP3]]
+;
store i64 %V, i64* %P
%P2 = bitcast i64* %P to float*
;; i64 -> i8* (32-bit) forwarding
define i8* @coerce_mustalias7(i64 %V, i64* %P) {
+; LE-LABEL: @coerce_mustalias7(
+; LE-NEXT: store i64 [[V:%.*]], i64* [[P:%.*]], align 4
+; LE-NEXT: [[TMP1:%.*]] = trunc i64 [[V]] to i32
+; LE-NEXT: [[TMP2:%.*]] = inttoptr i32 [[TMP1]] to i8*
+; LE-NEXT: ret i8* [[TMP2]]
+;
+; BE-LABEL: @coerce_mustalias7(
+; BE-NEXT: store i64 [[V:%.*]], i64* [[P:%.*]], align 4
+; BE-NEXT: [[TMP1:%.*]] = lshr i64 [[V]], 32
+; BE-NEXT: [[TMP2:%.*]] = trunc i64 [[TMP1]] to i32
+; BE-NEXT: [[TMP3:%.*]] = inttoptr i32 [[TMP2]] to i8*
+; BE-NEXT: ret i8* [[TMP3]]
+;
store i64 %V, i64* %P
%P2 = bitcast i64* %P to i8**
;; non-local i32/float -> i8 load forwarding.
define i8 @coerce_mustalias_nonlocal0(i32* %P, i1 %cond) {
+; LE-LABEL: @coerce_mustalias_nonlocal0(
+; LE-NEXT: [[P2:%.*]] = bitcast i32* [[P:%.*]] to float*
+; LE-NEXT: br i1 [[COND:%.*]], label [[T:%.*]], label [[F:%.*]]
+; LE: T:
+; LE-NEXT: store i32 42, i32* [[P]], align 4
+; LE-NEXT: br label [[CONT:%.*]]
+; LE: F:
+; LE-NEXT: store float 1.000000e+00, float* [[P2]], align 4
+; LE-NEXT: br label [[CONT]]
+; LE: Cont:
+; LE-NEXT: [[A:%.*]] = phi i8 [ 0, [[F]] ], [ 42, [[T]] ]
+; LE-NEXT: ret i8 [[A]]
+;
+; BE-LABEL: @coerce_mustalias_nonlocal0(
+; BE-NEXT: [[P2:%.*]] = bitcast i32* [[P:%.*]] to float*
+; BE-NEXT: br i1 [[COND:%.*]], label [[T:%.*]], label [[F:%.*]]
+; BE: T:
+; BE-NEXT: store i32 42, i32* [[P]], align 4
+; BE-NEXT: br label [[CONT:%.*]]
+; BE: F:
+; BE-NEXT: store float 1.000000e+00, float* [[P2]], align 4
+; BE-NEXT: br label [[CONT]]
+; BE: Cont:
+; BE-NEXT: [[A:%.*]] = phi i8 [ 63, [[F]] ], [ 0, [[T]] ]
+; BE-NEXT: ret i8 [[A]]
+;
%P2 = bitcast i32* %P to float*
%P3 = bitcast i32* %P to i8*
br i1 %cond, label %T, label %F
;; non-local i32/float -> i8 load forwarding. This also tests that the "P3"
;; bitcast equivalence can be properly phi translated.
define i8 @coerce_mustalias_nonlocal1(i32* %P, i1 %cond) {
+; LE-LABEL: @coerce_mustalias_nonlocal1(
+; LE-NEXT: [[P2:%.*]] = bitcast i32* [[P:%.*]] to float*
+; LE-NEXT: br i1 [[COND:%.*]], label [[T:%.*]], label [[F:%.*]]
+; LE: T:
+; LE-NEXT: store i32 42, i32* [[P]], align 4
+; LE-NEXT: br label [[CONT:%.*]]
+; LE: F:
+; LE-NEXT: store float 1.000000e+00, float* [[P2]], align 4
+; LE-NEXT: br label [[CONT]]
+; LE: Cont:
+; LE-NEXT: [[A:%.*]] = phi i8 [ 0, [[F]] ], [ 42, [[T]] ]
+; LE-NEXT: ret i8 [[A]]
+;
+; BE-LABEL: @coerce_mustalias_nonlocal1(
+; BE-NEXT: [[P2:%.*]] = bitcast i32* [[P:%.*]] to float*
+; BE-NEXT: br i1 [[COND:%.*]], label [[T:%.*]], label [[F:%.*]]
+; BE: T:
+; BE-NEXT: store i32 42, i32* [[P]], align 4
+; BE-NEXT: br label [[CONT:%.*]]
+; BE: F:
+; BE-NEXT: store float 1.000000e+00, float* [[P2]], align 4
+; BE-NEXT: br label [[CONT]]
+; BE: Cont:
+; BE-NEXT: [[A:%.*]] = phi i8 [ 63, [[F]] ], [ 0, [[T]] ]
+; BE-NEXT: ret i8 [[A]]
+;
%P2 = bitcast i32* %P to float*
br i1 %cond, label %T, label %F
T:
;; non-local i32 -> i8 partial redundancy load forwarding.
define i8 @coerce_mustalias_pre0(i32* %P, i1 %cond) {
+; LE-LABEL: @coerce_mustalias_pre0(
+; LE-NEXT: [[P3:%.*]] = bitcast i32* [[P:%.*]] to i8*
+; LE-NEXT: br i1 [[COND:%.*]], label [[T:%.*]], label [[F:%.*]]
+; LE: T:
+; LE-NEXT: store i32 42, i32* [[P]], align 4
+; LE-NEXT: br label [[CONT:%.*]]
+; LE: F:
+; LE-NEXT: [[A_PRE:%.*]] = load i8, i8* [[P3]], align 1
+; LE-NEXT: br label [[CONT]]
+; LE: Cont:
+; LE-NEXT: [[A:%.*]] = phi i8 [ [[A_PRE]], [[F]] ], [ 42, [[T]] ]
+; LE-NEXT: ret i8 [[A]]
+;
+; BE-LABEL: @coerce_mustalias_pre0(
+; BE-NEXT: [[P3:%.*]] = bitcast i32* [[P:%.*]] to i8*
+; BE-NEXT: br i1 [[COND:%.*]], label [[T:%.*]], label [[F:%.*]]
+; BE: T:
+; BE-NEXT: store i32 42, i32* [[P]], align 4
+; BE-NEXT: br label [[CONT:%.*]]
+; BE: F:
+; BE-NEXT: [[A_PRE:%.*]] = load i8, i8* [[P3]], align 1
+; BE-NEXT: br label [[CONT]]
+; BE: Cont:
+; BE-NEXT: [[A:%.*]] = phi i8 [ [[A_PRE]], [[F]] ], [ 0, [[T]] ]
+; BE-NEXT: ret i8 [[A]]
+;
%P3 = bitcast i32* %P to i8*
br i1 %cond, label %T, label %F
T:
;; i32 -> i8 forwarding.
;; PR4216
define i8 @coerce_offset0(i32 %V, i32* %P) {
+; LE-LABEL: @coerce_offset0(
+; LE-NEXT: store i32 [[V:%.*]], i32* [[P:%.*]], align 4
+; LE-NEXT: [[TMP1:%.*]] = lshr i32 [[V]], 16
+; LE-NEXT: [[TMP2:%.*]] = trunc i32 [[TMP1]] to i8
+; LE-NEXT: ret i8 [[TMP2]]
+;
+; BE-LABEL: @coerce_offset0(
+; BE-NEXT: store i32 [[V:%.*]], i32* [[P:%.*]], align 4
+; BE-NEXT: [[TMP1:%.*]] = lshr i32 [[V]], 8
+; BE-NEXT: [[TMP2:%.*]] = trunc i32 [[TMP1]] to i8
+; BE-NEXT: ret i8 [[TMP2]]
+;
store i32 %V, i32* %P
%P2 = bitcast i32* %P to i8*
;; non-local i32/float -> i8 load forwarding.
define i8 @coerce_offset_nonlocal0(i32* %P, i1 %cond) {
+; LE-LABEL: @coerce_offset_nonlocal0(
+; LE-NEXT: [[P2:%.*]] = bitcast i32* [[P:%.*]] to float*
+; LE-NEXT: br i1 [[COND:%.*]], label [[T:%.*]], label [[F:%.*]]
+; LE: T:
+; LE-NEXT: store i32 57005, i32* [[P]], align 4
+; LE-NEXT: br label [[CONT:%.*]]
+; LE: F:
+; LE-NEXT: store float 1.000000e+00, float* [[P2]], align 4
+; LE-NEXT: br label [[CONT]]
+; LE: Cont:
+; LE-NEXT: [[A:%.*]] = phi i8 [ -128, [[F]] ], [ 0, [[T]] ]
+; LE-NEXT: ret i8 [[A]]
+;
+; BE-LABEL: @coerce_offset_nonlocal0(
+; BE-NEXT: [[P2:%.*]] = bitcast i32* [[P:%.*]] to float*
+; BE-NEXT: br i1 [[COND:%.*]], label [[T:%.*]], label [[F:%.*]]
+; BE: T:
+; BE-NEXT: store i32 57005, i32* [[P]], align 4
+; BE-NEXT: br label [[CONT:%.*]]
+; BE: F:
+; BE-NEXT: store float 1.000000e+00, float* [[P2]], align 4
+; BE-NEXT: br label [[CONT]]
+; BE: Cont:
+; BE-NEXT: [[A:%.*]] = phi i8 [ 0, [[F]] ], [ -34, [[T]] ]
+; BE-NEXT: ret i8 [[A]]
+;
%P2 = bitcast i32* %P to float*
%P3 = bitcast i32* %P to i8*
%P4 = getelementptr i8, i8* %P3, i32 2