1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -passes=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(ptr %ptr) { 6; CHECK-LABEL: @byte_by_byte_replacement( 7; CHECK-NEXT: entry: 8; CHECK-NEXT: store i32 151653132, ptr [[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, ptr %ptr ; 0x12345678 16 %bptr1 = getelementptr inbounds i8, ptr %ptr, i64 1 17 %bptr2 = getelementptr inbounds i8, ptr %ptr, i64 2 18 %bptr3 = getelementptr inbounds i8, ptr %ptr, i64 3 19 20 ;; We should be able to merge these four stores with the i32 above 21 ; value (and bytes) stored before ; 0x12345678 22 store i8 9, ptr %ptr ; 09 23 store i8 10, ptr %bptr1 ; 0A 24 store i8 11, ptr %bptr2 ; 0B 25 store i8 12, ptr %bptr3 ; 0C 26 ; 0x090A0B0C 27 28 ret void 29} 30 31define void @word_replacement(ptr %ptr) { 32; CHECK-LABEL: @word_replacement( 33; CHECK-NEXT: entry: 34; CHECK-NEXT: store i64 72638273700655232, ptr [[PTR:%.*]] 35; CHECK-NEXT: ret void 36; 37entry: 38 store i64 72623859790382856, ptr %ptr ; 0x0102030405060708 39 40 %wptr1 = getelementptr inbounds i16, ptr %ptr, i64 1 41 %wptr3 = getelementptr inbounds i16, ptr %ptr, i64 3 42 43 ;; We should be able to merge these two stores with the i64 one above 44 ; value (and bytes) stored before ; 0x0102030405060708 45 store i16 4128, ptr %wptr1 ; 1020 46 store i16 28800, ptr %wptr3 ; 7080 47 ; 0x0102102005067080 48 49 ret void 50} 51 52 53define void @differently_sized_replacements(ptr %ptr) { 54; CHECK-LABEL: @differently_sized_replacements( 55; CHECK-NEXT: entry: 56; CHECK-NEXT: store i64 289077004501059343, ptr [[PTR:%.*]] 57; CHECK-NEXT: ret void 58; 59entry: 60 store i64 579005069656919567, ptr %ptr ; 0x08090a0b0c0d0e0f 61 62 %bptr6 = getelementptr inbounds i8, ptr %ptr, i64 6 63 %wptr2 = getelementptr inbounds i16, ptr %ptr, i64 2 64 65 ;; We should be able to merge all these stores with the i64 one above 66 ; value (and bytes) stored before ; 0x08090a0b0c0d0e0f 67 store i8 7, ptr %bptr6 ; 07 68 store i16 1541, ptr %wptr2 ; 0605 69 store i32 67305985, ptr %ptr ; 04030201 70 ; 0x040302010605070f 71 ret void 72} 73 74 75define void @multiple_replacements_to_same_byte(ptr %ptr) { 76; CHECK-LABEL: @multiple_replacements_to_same_byte( 77; CHECK-NEXT: entry: 78; CHECK-NEXT: store i64 289077004602248719, ptr [[PTR:%.*]] 79; CHECK-NEXT: ret void 80; 81entry: 82 store i64 579005069656919567, ptr %ptr ; 0x08090a0b0c0d0e0f 83 84 %bptr3 = getelementptr inbounds i8, ptr %ptr, i64 3 85 %wptr1 = getelementptr inbounds i16, ptr %ptr, i64 1 86 87 ;; We should be able to merge all these stores with the i64 one above 88 ; value (and bytes) stored before ; 0x08090a0b0c0d0e0f 89 store i8 7, ptr %bptr3 ; 07 90 store i16 1541, ptr %wptr1 ; 0605 91 store i32 67305985, ptr %ptr ; 04030201 92 ; 0x040302010c0d0e0f 93 ret void 94} 95 96define void @merged_merges(ptr %ptr) { 97; CHECK-LABEL: @merged_merges( 98; CHECK-NEXT: entry: 99; CHECK-NEXT: store i64 289081428418563599, ptr [[PTR:%.*]] 100; CHECK-NEXT: ret void 101; 102entry: 103 store i64 579005069656919567, ptr %ptr ; 0x08090a0b0c0d0e0f 104 105 %bptr3 = getelementptr inbounds i8, ptr %ptr, i64 3 106 %wptr1 = getelementptr inbounds i16, ptr %ptr, i64 1 107 108 ;; We should be able to merge all these stores with the i64 one above 109 ; value (not bytes) stored before ; 0x08090a0b0c0d0e0f 110 store i32 67305985, ptr %ptr ; 04030201 111 store i16 1541, ptr %wptr1 ; 0605 112 store i8 7, ptr %bptr3 ; 07 113 ; 0x040306070c0d0e0f 114 ret void 115} 116 117define signext i8 @shouldnt_merge_since_theres_a_full_overlap(ptr %ptr) { 118; CHECK-LABEL: @shouldnt_merge_since_theres_a_full_overlap( 119; CHECK-NEXT: entry: 120; CHECK-NEXT: [[BPTRM1:%.*]] = getelementptr inbounds i8, ptr [[PTR:%.*]], i64 -1 121; CHECK-NEXT: [[BPTR3:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 3 122; CHECK-NEXT: store i32 1234, ptr [[BPTRM1]], align 1 123; CHECK-NEXT: store i64 5678, ptr [[BPTR3]], align 1 124; CHECK-NEXT: ret i8 0 125; 126entry: 127 128 store i64 0, ptr %ptr 129 130 %bptrm1 = getelementptr inbounds i8, ptr %ptr, i64 -1 131 %bptr3 = getelementptr inbounds i8, ptr %ptr, i64 3 132 133 store i32 1234, ptr %bptrm1, align 1 134 store i64 5678, ptr %bptr3, align 1 135 136 ret i8 0 137} 138 139;; Test case from PR31777 140%union.U = type { i64 } 141 142define void @foo(ptr nocapture %u) { 143; CHECK-LABEL: @foo( 144; CHECK-NEXT: entry: 145; CHECK-NEXT: store i64 11821949021847552, ptr [[U:%.*]], align 8 146; CHECK-NEXT: ret void 147; 148entry: 149 store i64 0, ptr %u, align 8 150 store i16 42, ptr %u, align 8 151 ret void 152} 153