1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -dse -enable-dse-partial-store-merging -S < %s | FileCheck %s 3target datalayout = "E-m:e-i64:64-i128:128-n32:64-S128" 4 5define void @byte_by_byte_replacement(i32 *%ptr) { 6; CHECK-LABEL: @byte_by_byte_replacement( 7; CHECK-NEXT: entry: 8; CHECK-NEXT: store i32 151653132, i32* [[PTR:%.*]] 9; CHECK-NEXT: ret void 10; 11entry: 12 ;; This store's value should be modified as it should be better to use one 13 ;; larger store than several smaller ones. 14 ;; store will turn into 0x090A0B0C == 151653132 15 store i32 305419896, i32* %ptr ; 0x12345678 16 %bptr = bitcast i32* %ptr to i8* 17 %bptr1 = getelementptr inbounds i8, i8* %bptr, i64 1 18 %bptr2 = getelementptr inbounds i8, i8* %bptr, i64 2 19 %bptr3 = getelementptr inbounds i8, i8* %bptr, i64 3 20 21 ;; We should be able to merge these four stores with the i32 above 22 ; value (and bytes) stored before ; 0x12345678 23 store i8 9, i8* %bptr ; 09 24 store i8 10, i8* %bptr1 ; 0A 25 store i8 11, i8* %bptr2 ; 0B 26 store i8 12, i8* %bptr3 ; 0C 27 ; 0x090A0B0C 28 29 ret void 30} 31 32define void @word_replacement(i64 *%ptr) { 33; CHECK-LABEL: @word_replacement( 34; CHECK-NEXT: entry: 35; CHECK-NEXT: store i64 72638273700655232, i64* [[PTR:%.*]] 36; CHECK-NEXT: ret void 37; 38entry: 39 store i64 72623859790382856, i64* %ptr ; 0x0102030405060708 40 41 %wptr = bitcast i64* %ptr to i16* 42 %wptr1 = getelementptr inbounds i16, i16* %wptr, i64 1 43 %wptr3 = getelementptr inbounds i16, i16* %wptr, i64 3 44 45 ;; We should be able to merge these two stores with the i64 one above 46 ; value (and bytes) stored before ; 0x0102030405060708 47 store i16 4128, i16* %wptr1 ; 1020 48 store i16 28800, i16* %wptr3 ; 7080 49 ; 0x0102102005067080 50 51 ret void 52} 53 54 55define void @differently_sized_replacements(i64 *%ptr) { 56; CHECK-LABEL: @differently_sized_replacements( 57; CHECK-NEXT: entry: 58; CHECK-NEXT: store i64 289077004501059343, i64* [[PTR:%.*]] 59; CHECK-NEXT: ret void 60; 61entry: 62 store i64 579005069656919567, i64* %ptr ; 0x08090a0b0c0d0e0f 63 64 %bptr = bitcast i64* %ptr to i8* 65 %bptr6 = getelementptr inbounds i8, i8* %bptr, i64 6 66 %wptr = bitcast i64* %ptr to i16* 67 %wptr2 = getelementptr inbounds i16, i16* %wptr, i64 2 68 %dptr = bitcast i64* %ptr to i32* 69 70 ;; We should be able to merge all these stores with the i64 one above 71 ; value (and bytes) stored before ; 0x08090a0b0c0d0e0f 72 store i8 7, i8* %bptr6 ; 07 73 store i16 1541, i16* %wptr2 ; 0605 74 store i32 67305985, i32* %dptr ; 04030201 75 ; 0x040302010605070f 76 ret void 77} 78 79 80define void @multiple_replacements_to_same_byte(i64 *%ptr) { 81; CHECK-LABEL: @multiple_replacements_to_same_byte( 82; CHECK-NEXT: entry: 83; CHECK-NEXT: store i64 289077004602248719, i64* [[PTR:%.*]] 84; CHECK-NEXT: ret void 85; 86entry: 87 store i64 579005069656919567, i64* %ptr ; 0x08090a0b0c0d0e0f 88 89 %bptr = bitcast i64* %ptr to i8* 90 %bptr3 = getelementptr inbounds i8, i8* %bptr, i64 3 91 %wptr = bitcast i64* %ptr to i16* 92 %wptr1 = getelementptr inbounds i16, i16* %wptr, i64 1 93 %dptr = bitcast i64* %ptr to i32* 94 95 ;; We should be able to merge all these stores with the i64 one above 96 ; value (and bytes) stored before ; 0x08090a0b0c0d0e0f 97 store i8 7, i8* %bptr3 ; 07 98 store i16 1541, i16* %wptr1 ; 0605 99 store i32 67305985, i32* %dptr ; 04030201 100 ; 0x040302010c0d0e0f 101 ret void 102} 103 104define void @merged_merges(i64 *%ptr) { 105; CHECK-LABEL: @merged_merges( 106; CHECK-NEXT: entry: 107; CHECK-NEXT: store i64 289081428418563599, i64* [[PTR:%.*]] 108; CHECK-NEXT: ret void 109; 110entry: 111 store i64 579005069656919567, i64* %ptr ; 0x08090a0b0c0d0e0f 112 113 %bptr = bitcast i64* %ptr to i8* 114 %bptr3 = getelementptr inbounds i8, i8* %bptr, i64 3 115 %wptr = bitcast i64* %ptr to i16* 116 %wptr1 = getelementptr inbounds i16, i16* %wptr, i64 1 117 %dptr = bitcast i64* %ptr to i32* 118 119 ;; We should be able to merge all these stores with the i64 one above 120 ; value (not bytes) stored before ; 0x08090a0b0c0d0e0f 121 store i32 67305985, i32* %dptr ; 04030201 122 store i16 1541, i16* %wptr1 ; 0605 123 store i8 7, i8* %bptr3 ; 07 124 ; 0x040306070c0d0e0f 125 ret void 126} 127 128define signext i8 @shouldnt_merge_since_theres_a_full_overlap(i64 *%ptr) { 129; CHECK-LABEL: @shouldnt_merge_since_theres_a_full_overlap( 130; CHECK-NEXT: entry: 131; CHECK-NEXT: [[BPTR:%.*]] = bitcast i64* [[PTR:%.*]] to i8* 132; CHECK-NEXT: [[BPTRM1:%.*]] = getelementptr inbounds i8, i8* [[BPTR]], i64 -1 133; CHECK-NEXT: [[BPTR3:%.*]] = getelementptr inbounds i8, i8* [[BPTR]], i64 3 134; CHECK-NEXT: [[DPTR:%.*]] = bitcast i8* [[BPTRM1]] to i32* 135; CHECK-NEXT: [[QPTR:%.*]] = bitcast i8* [[BPTR3]] to i64* 136; CHECK-NEXT: store i32 1234, i32* [[DPTR]], align 1 137; CHECK-NEXT: store i64 5678, i64* [[QPTR]], align 1 138; CHECK-NEXT: ret i8 0 139; 140entry: 141 142 store i64 0, i64* %ptr 143 144 %bptr = bitcast i64* %ptr to i8* 145 %bptrm1 = getelementptr inbounds i8, i8* %bptr, i64 -1 146 %bptr3 = getelementptr inbounds i8, i8* %bptr, i64 3 147 %dptr = bitcast i8* %bptrm1 to i32* 148 %qptr = bitcast i8* %bptr3 to i64* 149 150 store i32 1234, i32* %dptr, align 1 151 store i64 5678, i64* %qptr, align 1 152 153 ret i8 0 154} 155 156;; Test case from PR31777 157%union.U = type { i64 } 158 159define void @foo(%union.U* nocapture %u) { 160; CHECK-LABEL: @foo( 161; CHECK-NEXT: entry: 162; CHECK-NEXT: [[I:%.*]] = getelementptr inbounds [[UNION_U:%.*]], %union.U* [[U:%.*]], i64 0, i32 0 163; CHECK-NEXT: store i64 11821949021847552, i64* [[I]], align 8 164; CHECK-NEXT: ret void 165; 166entry: 167 %i = getelementptr inbounds %union.U, %union.U* %u, i64 0, i32 0 168 store i64 0, i64* %i, align 8 169 %s = bitcast %union.U* %u to i16* 170 store i16 42, i16* %s, align 8 171 ret void 172} 173