289 lines
11 KiB
LLVM
289 lines
11 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
; RUN: opt -S -passes=dse -enable-dse-partial-store-merging=false < %s | FileCheck --check-prefixes=CHECK %s
|
|
target datalayout = "E-m:e-i64:64-n32:64"
|
|
target triple = "powerpc64le-unknown-linux"
|
|
|
|
%"struct.std::complex" = type { { float, float } }
|
|
|
|
define void @_Z4testSt7complexIfE(ptr noalias nocapture sret(%"struct.std::complex") %agg.result, i64 %c.coerce) {
|
|
; CHECK-LABEL: @_Z4testSt7complexIfE(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[REF_TMP:%.*]] = alloca i64, align 8
|
|
; CHECK-NEXT: [[C_SROA_0_0_EXTRACT_SHIFT:%.*]] = lshr i64 [[C_COERCE:%.*]], 32
|
|
; CHECK-NEXT: [[C_SROA_0_0_EXTRACT_TRUNC:%.*]] = trunc i64 [[C_SROA_0_0_EXTRACT_SHIFT]] to i32
|
|
; CHECK-NEXT: [[TMP0:%.*]] = bitcast i32 [[C_SROA_0_0_EXTRACT_TRUNC]] to float
|
|
; CHECK-NEXT: [[C_SROA_2_0_EXTRACT_TRUNC:%.*]] = trunc i64 [[C_COERCE]] to i32
|
|
; CHECK-NEXT: [[TMP1:%.*]] = bitcast i32 [[C_SROA_2_0_EXTRACT_TRUNC]] to float
|
|
; CHECK-NEXT: call void @_Z3barSt7complexIfE(ptr nonnull sret(%"struct.std::complex") [[REF_TMP]], i64 [[C_COERCE]])
|
|
; CHECK-NEXT: [[TMP2:%.*]] = load i64, ptr [[REF_TMP]], align 8
|
|
; CHECK-NEXT: [[TMP3:%.*]] = lshr i64 [[TMP2]], 32
|
|
; CHECK-NEXT: [[TMP4:%.*]] = trunc i64 [[TMP3]] to i32
|
|
; CHECK-NEXT: [[TMP5:%.*]] = bitcast i32 [[TMP4]] to float
|
|
; CHECK-NEXT: [[_M_VALUE_IMAGP_I_I:%.*]] = getelementptr inbounds %"struct.std::complex", ptr [[AGG_RESULT:%.*]], i64 0, i32 0, i32 1
|
|
; CHECK-NEXT: [[TMP6:%.*]] = trunc i64 [[TMP2]] to i32
|
|
; CHECK-NEXT: [[TMP7:%.*]] = bitcast i32 [[TMP6]] to float
|
|
; CHECK-NEXT: [[MUL_AD_I_I:%.*]] = fmul fast float [[TMP5]], [[TMP1]]
|
|
; CHECK-NEXT: [[MUL_BC_I_I:%.*]] = fmul fast float [[TMP7]], [[TMP0]]
|
|
; CHECK-NEXT: [[MUL_I_I_I:%.*]] = fadd fast float [[MUL_AD_I_I]], [[MUL_BC_I_I]]
|
|
; CHECK-NEXT: [[MUL_AC_I_I:%.*]] = fmul fast float [[TMP5]], [[TMP0]]
|
|
; CHECK-NEXT: [[MUL_BD_I_I:%.*]] = fmul fast float [[TMP7]], [[TMP1]]
|
|
; CHECK-NEXT: [[MUL_R_I_I:%.*]] = fsub fast float [[MUL_AC_I_I]], [[MUL_BD_I_I]]
|
|
; CHECK-NEXT: store float [[MUL_R_I_I]], ptr [[AGG_RESULT]], align 4
|
|
; CHECK-NEXT: store float [[MUL_I_I_I]], ptr [[_M_VALUE_IMAGP_I_I]], align 4
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
|
|
%ref.tmp = alloca i64, align 8
|
|
%c.sroa.0.0.extract.shift = lshr i64 %c.coerce, 32
|
|
%c.sroa.0.0.extract.trunc = trunc i64 %c.sroa.0.0.extract.shift to i32
|
|
%0 = bitcast i32 %c.sroa.0.0.extract.trunc to float
|
|
%c.sroa.2.0.extract.trunc = trunc i64 %c.coerce to i32
|
|
%1 = bitcast i32 %c.sroa.2.0.extract.trunc to float
|
|
call void @_Z3barSt7complexIfE(ptr nonnull sret(%"struct.std::complex") %ref.tmp, i64 %c.coerce)
|
|
%2 = load i64, ptr %ref.tmp, align 8
|
|
store i64 %2, ptr %agg.result, align 4
|
|
|
|
%3 = lshr i64 %2, 32
|
|
%4 = trunc i64 %3 to i32
|
|
%5 = bitcast i32 %4 to float
|
|
%_M_value.imagp.i.i = getelementptr inbounds %"struct.std::complex", ptr %agg.result, i64 0, i32 0, i32 1
|
|
%6 = trunc i64 %2 to i32
|
|
%7 = bitcast i32 %6 to float
|
|
%mul_ad.i.i = fmul fast float %5, %1
|
|
%mul_bc.i.i = fmul fast float %7, %0
|
|
%mul_i.i.i = fadd fast float %mul_ad.i.i, %mul_bc.i.i
|
|
%mul_ac.i.i = fmul fast float %5, %0
|
|
%mul_bd.i.i = fmul fast float %7, %1
|
|
%mul_r.i.i = fsub fast float %mul_ac.i.i, %mul_bd.i.i
|
|
store float %mul_r.i.i, ptr %agg.result, align 4
|
|
store float %mul_i.i.i, ptr %_M_value.imagp.i.i, align 4
|
|
ret void
|
|
}
|
|
|
|
declare void @_Z3barSt7complexIfE(ptr sret(%"struct.std::complex"), i64)
|
|
|
|
define void @test1(ptr %ptr) {
|
|
; CHECK-LABEL: @test1(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: store i16 -30062, ptr [[PTR:%.*]], align 2
|
|
; CHECK-NEXT: [[BPTR3:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 3
|
|
; CHECK-NEXT: store i8 47, ptr [[BPTR3]], align 1
|
|
; CHECK-NEXT: [[BPTR1:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 1
|
|
; CHECK-NEXT: store i16 2020, ptr [[BPTR1]], align 1
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
|
|
store i32 5, ptr %ptr
|
|
store i8 7, ptr %ptr
|
|
store i16 -30062, ptr %ptr
|
|
%bptr2 = getelementptr inbounds i8, ptr %ptr, i64 2
|
|
store i8 25, ptr %bptr2
|
|
%bptr3 = getelementptr inbounds i8, ptr %ptr, i64 3
|
|
store i8 47, ptr %bptr3
|
|
%bptr1 = getelementptr inbounds i8, ptr %ptr, i64 1
|
|
store i16 2020, ptr %bptr1, align 1
|
|
ret void
|
|
|
|
|
|
}
|
|
|
|
define void @test2(ptr %ptr) {
|
|
; CHECK-LABEL: @test2(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[BPTRM1:%.*]] = getelementptr inbounds i8, ptr [[PTR:%.*]], i64 -1
|
|
; CHECK-NEXT: [[BPTR1:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 1
|
|
; CHECK-NEXT: [[BPTR2:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 2
|
|
; CHECK-NEXT: [[BPTR3:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 3
|
|
; CHECK-NEXT: store i16 1456, ptr [[BPTRM1]], align 1
|
|
; CHECK-NEXT: store i16 1346, ptr [[PTR]], align 1
|
|
; CHECK-NEXT: store i16 1756, ptr [[BPTR1]], align 1
|
|
; CHECK-NEXT: store i16 1126, ptr [[BPTR2]], align 1
|
|
; CHECK-NEXT: store i16 5656, ptr [[BPTR3]], align 1
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
|
|
store i32 5, ptr %ptr
|
|
|
|
%bptrm1 = getelementptr inbounds i8, ptr %ptr, i64 -1
|
|
%bptr1 = getelementptr inbounds i8, ptr %ptr, i64 1
|
|
%bptr2 = getelementptr inbounds i8, ptr %ptr, i64 2
|
|
%bptr3 = getelementptr inbounds i8, ptr %ptr, i64 3
|
|
|
|
|
|
store i16 1456, ptr %bptrm1, align 1
|
|
store i16 1346, ptr %ptr, align 1
|
|
store i16 1756, ptr %bptr1, align 1
|
|
store i16 1126, ptr %bptr2, align 1
|
|
store i16 5656, ptr %bptr3, align 1
|
|
|
|
|
|
|
|
ret void
|
|
|
|
}
|
|
|
|
define signext i8 @test3(ptr %ptr) {
|
|
; CHECK-LABEL: @test3(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: store i32 5, ptr [[PTR:%.*]], align 4
|
|
; CHECK-NEXT: [[BPTRM1:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 -1
|
|
; CHECK-NEXT: [[BPTR1:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 1
|
|
; CHECK-NEXT: [[BPTR2:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 2
|
|
; CHECK-NEXT: [[BPTR3:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 3
|
|
; CHECK-NEXT: [[V:%.*]] = load i8, ptr [[PTR]], align 1
|
|
; CHECK-NEXT: store i16 1456, ptr [[BPTRM1]], align 1
|
|
; CHECK-NEXT: store i16 1346, ptr [[PTR]], align 1
|
|
; CHECK-NEXT: store i16 1756, ptr [[BPTR1]], align 1
|
|
; CHECK-NEXT: store i16 1126, ptr [[BPTR2]], align 1
|
|
; CHECK-NEXT: store i16 5656, ptr [[BPTR3]], align 1
|
|
; CHECK-NEXT: ret i8 [[V]]
|
|
;
|
|
entry:
|
|
|
|
store i32 5, ptr %ptr
|
|
|
|
%bptrm1 = getelementptr inbounds i8, ptr %ptr, i64 -1
|
|
%bptr1 = getelementptr inbounds i8, ptr %ptr, i64 1
|
|
%bptr2 = getelementptr inbounds i8, ptr %ptr, i64 2
|
|
%bptr3 = getelementptr inbounds i8, ptr %ptr, i64 3
|
|
|
|
|
|
%v = load i8, ptr %ptr, align 1
|
|
store i16 1456, ptr %bptrm1, align 1
|
|
store i16 1346, ptr %ptr, align 1
|
|
store i16 1756, ptr %bptr1, align 1
|
|
store i16 1126, ptr %bptr2, align 1
|
|
store i16 5656, ptr %bptr3, align 1
|
|
|
|
|
|
ret i8 %v
|
|
|
|
}
|
|
|
|
%struct.foostruct = type {
|
|
ptr,
|
|
ptr,
|
|
ptr,
|
|
ptr,
|
|
ptr
|
|
}
|
|
declare void @llvm.memset.p0.i64(ptr nocapture, i8, i64, i1)
|
|
declare void @goFunc(ptr)
|
|
declare i32 @fa(ptr, ptr, i32, i8, ptr)
|
|
|
|
; We miss this case, because of an aggressive limit of partial overlap analysis.
|
|
; With a larger partial store limit, we remove the memset.
|
|
define void @test4() {
|
|
; CHECK-LABEL: @test4(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[BANG:%.*]] = alloca [[STRUCT_FOOSTRUCT:%.*]], align 8
|
|
; CHECK-NEXT: store ptr @fa, ptr [[BANG]], align 8
|
|
; CHECK-NEXT: [[V3:%.*]] = getelementptr inbounds [[STRUCT_FOOSTRUCT]], ptr [[BANG]], i64 0, i32 1
|
|
; CHECK-NEXT: store ptr @fa, ptr [[V3]], align 8
|
|
; CHECK-NEXT: [[V4:%.*]] = getelementptr inbounds [[STRUCT_FOOSTRUCT]], ptr [[BANG]], i64 0, i32 2
|
|
; CHECK-NEXT: store ptr @fa, ptr [[V4]], align 8
|
|
; CHECK-NEXT: [[V5:%.*]] = getelementptr inbounds [[STRUCT_FOOSTRUCT]], ptr [[BANG]], i64 0, i32 3
|
|
; CHECK-NEXT: store ptr @fa, ptr [[V5]], align 8
|
|
; CHECK-NEXT: [[V6:%.*]] = getelementptr inbounds [[STRUCT_FOOSTRUCT]], ptr [[BANG]], i64 0, i32 4
|
|
; CHECK-NEXT: store ptr null, ptr [[V6]], align 8
|
|
; CHECK-NEXT: call void @goFunc(ptr [[BANG]])
|
|
; CHECK-NEXT: ret void
|
|
entry:
|
|
|
|
%bang = alloca %struct.foostruct, align 8
|
|
call void @llvm.memset.p0.i64(ptr align 8 %bang, i8 0, i64 40, i1 false)
|
|
store ptr @fa, ptr %bang, align 8
|
|
%v3 = getelementptr inbounds %struct.foostruct, ptr %bang, i64 0, i32 1
|
|
store ptr @fa, ptr %v3, align 8
|
|
%v4 = getelementptr inbounds %struct.foostruct, ptr %bang, i64 0, i32 2
|
|
store ptr @fa, ptr %v4, align 8
|
|
%v5 = getelementptr inbounds %struct.foostruct, ptr %bang, i64 0, i32 3
|
|
store ptr @fa, ptr %v5, align 8
|
|
%v6 = getelementptr inbounds %struct.foostruct, ptr %bang, i64 0, i32 4
|
|
store ptr null, ptr %v6, align 8
|
|
call void @goFunc(ptr %bang)
|
|
ret void
|
|
|
|
}
|
|
|
|
define signext i8 @test5(ptr %ptr) {
|
|
; CHECK-LABEL: @test5(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[BPTR1:%.*]] = getelementptr inbounds i8, ptr [[PTR:%.*]], i64 1
|
|
; CHECK-NEXT: [[BPTR2:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 2
|
|
; CHECK-NEXT: [[BPTR3:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 3
|
|
; CHECK-NEXT: store i16 -1, ptr [[BPTR2]], align 1
|
|
; CHECK-NEXT: store i16 1456, ptr [[BPTR1]], align 1
|
|
; CHECK-NEXT: store i16 1346, ptr [[PTR]], align 1
|
|
; CHECK-NEXT: ret i8 0
|
|
;
|
|
entry:
|
|
|
|
store i32 0, ptr %ptr
|
|
|
|
%bptr1 = getelementptr inbounds i8, ptr %ptr, i64 1
|
|
%bptr2 = getelementptr inbounds i8, ptr %ptr, i64 2
|
|
%bptr3 = getelementptr inbounds i8, ptr %ptr, i64 3
|
|
|
|
|
|
store i16 65535, ptr %bptr2, align 1
|
|
store i16 1456, ptr %bptr1, align 1
|
|
store i16 1346, ptr %ptr, align 1
|
|
|
|
|
|
ret i8 0
|
|
}
|
|
|
|
define signext i8 @test6(ptr %ptr) {
|
|
; CHECK-LABEL: @test6(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[BPTR2:%.*]] = getelementptr inbounds i16, ptr [[PTR:%.*]], i64 1
|
|
; CHECK-NEXT: store i16 1456, ptr [[BPTR2]], align 1
|
|
; CHECK-NEXT: store i16 -1, ptr [[PTR]], align 1
|
|
; CHECK-NEXT: ret i8 0
|
|
;
|
|
entry:
|
|
|
|
store i32 0, ptr %ptr
|
|
|
|
%bptr2 = getelementptr inbounds i16, ptr %ptr, i64 1
|
|
|
|
store i16 1456, ptr %bptr2, align 1
|
|
store i16 65535, ptr %ptr, align 1
|
|
|
|
|
|
ret i8 0
|
|
}
|
|
|
|
define signext i8 @test7(ptr %ptr) {
|
|
; CHECK-LABEL: @test7(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[BPTR2:%.*]] = getelementptr inbounds i16, ptr [[PTR:%.*]], i64 1
|
|
; CHECK-NEXT: [[BPTR3:%.*]] = getelementptr inbounds i16, ptr [[PTR]], i64 2
|
|
; CHECK-NEXT: [[BPTR4:%.*]] = getelementptr inbounds i16, ptr [[PTR]], i64 3
|
|
; CHECK-NEXT: store i16 1346, ptr [[PTR]], align 1
|
|
; CHECK-NEXT: store i16 1756, ptr [[BPTR3]], align 1
|
|
; CHECK-NEXT: store i16 1456, ptr [[BPTR2]], align 1
|
|
; CHECK-NEXT: store i16 5656, ptr [[BPTR4]], align 1
|
|
; CHECK-NEXT: ret i8 0
|
|
;
|
|
entry:
|
|
|
|
store i64 0, ptr %ptr
|
|
|
|
%bptr2 = getelementptr inbounds i16, ptr %ptr, i64 1
|
|
%bptr3 = getelementptr inbounds i16, ptr %ptr, i64 2
|
|
%bptr4 = getelementptr inbounds i16, ptr %ptr, i64 3
|
|
|
|
store i16 1346, ptr %ptr, align 1
|
|
store i16 1756, ptr %bptr3, align 1
|
|
store i16 1456, ptr %bptr2, align 1
|
|
store i16 5656, ptr %bptr4, align 1
|
|
|
|
|
|
ret i8 0
|
|
}
|