|
| 1 | +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 |
| 2 | +; RUN: opt < %s -passes=infer-alignment -S | FileCheck %s |
| 3 | +%struct.S1 = type { %struct.float3, %struct.float3, i32, i32 } |
| 4 | +%struct.float3 = type { float, float, float } |
| 5 | + |
| 6 | + |
| 7 | +; ------------------------------------------------------------------------------ |
| 8 | +; Test that we can propagate the align 16 to the load and store that are set to align 4 |
| 9 | +; ------------------------------------------------------------------------------ |
| 10 | + |
| 11 | +define void @prop_align(ptr %v, ptr %vout) { |
| 12 | +; CHECK-LABEL: define void @prop_align( |
| 13 | +; CHECK-SAME: ptr [[V:%.*]], ptr [[VOUT:%.*]]) { |
| 14 | +; CHECK-NEXT: [[DOTUNPACK_UNPACK:%.*]] = load float, ptr [[V]], align 16 |
| 15 | +; CHECK-NEXT: [[DOTUNPACK_ELT7:%.*]] = getelementptr inbounds nuw i8, ptr [[V]], i64 4 |
| 16 | +; CHECK-NEXT: [[DOTUNPACK_UNPACK8:%.*]] = load float, ptr [[DOTUNPACK_ELT7]], align 4 |
| 17 | +; CHECK-NEXT: [[DOTUNPACK_ELT9:%.*]] = getelementptr inbounds nuw i8, ptr [[V]], i64 8 |
| 18 | +; CHECK-NEXT: [[DOTUNPACK_UNPACK10:%.*]] = load float, ptr [[DOTUNPACK_ELT9]], align 8 |
| 19 | +; CHECK-NEXT: [[DOTELT1:%.*]] = getelementptr inbounds nuw i8, ptr [[V]], i64 12 |
| 20 | +; CHECK-NEXT: [[DOTUNPACK2_UNPACK:%.*]] = load float, ptr [[DOTELT1]], align 4 |
| 21 | +; CHECK-NEXT: [[DOTUNPACK2_ELT12:%.*]] = getelementptr inbounds nuw i8, ptr [[V]], i64 16 |
| 22 | +; CHECK-NEXT: [[DOTUNPACK2_UNPACK13:%.*]] = load float, ptr [[DOTUNPACK2_ELT12]], align 16 |
| 23 | +; CHECK-NEXT: [[DOTUNPACK2_ELT14:%.*]] = getelementptr inbounds nuw i8, ptr [[V]], i64 20 |
| 24 | +; CHECK-NEXT: [[DOTUNPACK2_UNPACK15:%.*]] = load float, ptr [[DOTUNPACK2_ELT14]], align 4 |
| 25 | +; CHECK-NEXT: [[DOTELT3:%.*]] = getelementptr inbounds nuw i8, ptr [[V]], i64 24 |
| 26 | +; CHECK-NEXT: [[DOTUNPACK4:%.*]] = load i32, ptr [[DOTELT3]], align 8 |
| 27 | +; CHECK-NEXT: [[DOTELT5:%.*]] = getelementptr inbounds nuw i8, ptr [[V]], i64 28 |
| 28 | +; CHECK-NEXT: [[DOTUNPACK6:%.*]] = load i32, ptr [[DOTELT5]], align 4 |
| 29 | +; CHECK-NEXT: store float [[DOTUNPACK_UNPACK]], ptr [[VOUT]], align 16 |
| 30 | +; CHECK-NEXT: [[VOUT_REPACK23:%.*]] = getelementptr inbounds nuw i8, ptr [[VOUT]], i64 4 |
| 31 | +; CHECK-NEXT: store float [[DOTUNPACK_UNPACK8]], ptr [[VOUT_REPACK23]], align 4 |
| 32 | +; CHECK-NEXT: [[VOUT_REPACK25:%.*]] = getelementptr inbounds nuw i8, ptr [[VOUT]], i64 8 |
| 33 | +; CHECK-NEXT: store float [[DOTUNPACK_UNPACK10]], ptr [[VOUT_REPACK25]], align 8 |
| 34 | +; CHECK-NEXT: [[VOUT_REPACK17:%.*]] = getelementptr inbounds nuw i8, ptr [[VOUT]], i64 12 |
| 35 | +; CHECK-NEXT: store float [[DOTUNPACK2_UNPACK]], ptr [[VOUT_REPACK17]], align 4 |
| 36 | +; CHECK-NEXT: [[VOUT_REPACK17_REPACK27:%.*]] = getelementptr inbounds nuw i8, ptr [[VOUT]], i64 16 |
| 37 | +; CHECK-NEXT: store float [[DOTUNPACK2_UNPACK13]], ptr [[VOUT_REPACK17_REPACK27]], align 16 |
| 38 | +; CHECK-NEXT: [[VOUT_REPACK17_REPACK29:%.*]] = getelementptr inbounds nuw i8, ptr [[VOUT]], i64 20 |
| 39 | +; CHECK-NEXT: store float [[DOTUNPACK2_UNPACK15]], ptr [[VOUT_REPACK17_REPACK29]], align 4 |
| 40 | +; CHECK-NEXT: [[VOUT_REPACK19:%.*]] = getelementptr inbounds nuw i8, ptr [[VOUT]], i64 24 |
| 41 | +; CHECK-NEXT: store i32 [[DOTUNPACK4]], ptr [[VOUT_REPACK19]], align 8 |
| 42 | +; CHECK-NEXT: [[VOUT_REPACK21:%.*]] = getelementptr inbounds nuw i8, ptr [[VOUT]], i64 28 |
| 43 | +; CHECK-NEXT: store i32 [[DOTUNPACK6]], ptr [[VOUT_REPACK21]], align 4 |
| 44 | +; CHECK-NEXT: ret void |
| 45 | +; |
| 46 | + %.unpack.unpack = load float, ptr %v, align 16 |
| 47 | + %.unpack.elt7 = getelementptr inbounds nuw i8, ptr %v, i64 4 |
| 48 | + %.unpack.unpack8 = load float, ptr %.unpack.elt7, align 4 |
| 49 | + %.unpack.elt9 = getelementptr inbounds nuw i8, ptr %v, i64 8 |
| 50 | + %.unpack.unpack10 = load float, ptr %.unpack.elt9, align 8 |
| 51 | + %.elt1 = getelementptr inbounds nuw i8, ptr %v, i64 12 |
| 52 | + %.unpack2.unpack = load float, ptr %.elt1, align 4 |
| 53 | + %.unpack2.elt12 = getelementptr inbounds nuw i8, ptr %v, i64 16 |
| 54 | + %.unpack2.unpack13 = load float, ptr %.unpack2.elt12, align 4 |
| 55 | + %.unpack2.elt14 = getelementptr inbounds nuw i8, ptr %v, i64 20 |
| 56 | + %.unpack2.unpack15 = load float, ptr %.unpack2.elt14, align 4 |
| 57 | + %.elt3 = getelementptr inbounds nuw i8, ptr %v, i64 24 |
| 58 | + %.unpack4 = load i32, ptr %.elt3, align 8 |
| 59 | + %.elt5 = getelementptr inbounds nuw i8, ptr %v, i64 28 |
| 60 | + %.unpack6 = load i32, ptr %.elt5, align 4 |
| 61 | + store float %.unpack.unpack, ptr %vout, align 16 |
| 62 | + %vout.repack23 = getelementptr inbounds nuw i8, ptr %vout, i64 4 |
| 63 | + store float %.unpack.unpack8, ptr %vout.repack23, align 4 |
| 64 | + %vout.repack25 = getelementptr inbounds nuw i8, ptr %vout, i64 8 |
| 65 | + store float %.unpack.unpack10, ptr %vout.repack25, align 8 |
| 66 | + %vout.repack17 = getelementptr inbounds nuw i8, ptr %vout, i64 12 |
| 67 | + store float %.unpack2.unpack, ptr %vout.repack17, align 4 |
| 68 | + %vout.repack17.repack27 = getelementptr inbounds nuw i8, ptr %vout, i64 16 |
| 69 | + store float %.unpack2.unpack13, ptr %vout.repack17.repack27, align 4 |
| 70 | + %vout.repack17.repack29 = getelementptr inbounds nuw i8, ptr %vout, i64 20 |
| 71 | + store float %.unpack2.unpack15, ptr %vout.repack17.repack29, align 4 |
| 72 | + %vout.repack19 = getelementptr inbounds nuw i8, ptr %vout, i64 24 |
| 73 | + store i32 %.unpack4, ptr %vout.repack19, align 8 |
| 74 | + %vout.repack21 = getelementptr inbounds nuw i8, ptr %vout, i64 28 |
| 75 | + store i32 %.unpack6, ptr %vout.repack21, align 4 |
| 76 | + ret void |
| 77 | +} |
| 78 | + |
| 79 | +; ------------------------------------------------------------------------------ |
| 80 | +; Test that alignment is not propagated from a source that does not dominate the destination |
| 81 | +; ------------------------------------------------------------------------------ |
| 82 | + |
| 83 | +define void @no_prop_align(ptr %v, ptr %vout, i1 %cond) { |
| 84 | +; CHECK-LABEL: define void @no_prop_align( |
| 85 | +; CHECK-SAME: ptr [[V:%.*]], ptr [[VOUT:%.*]], i1 [[COND:%.*]]) { |
| 86 | +; CHECK-NEXT: br i1 [[COND]], label %[[BRANCH1:.*]], label %[[BRANCH2:.*]] |
| 87 | +; CHECK: [[BRANCH1]]: |
| 88 | +; CHECK-NEXT: [[DOTUNPACK_UNPACK:%.*]] = load float, ptr [[V]], align 16 |
| 89 | +; CHECK-NEXT: [[DOTUNPACK_ELT7:%.*]] = getelementptr inbounds nuw i8, ptr [[V]], i64 4 |
| 90 | +; CHECK-NEXT: [[DOTUNPACK_UNPACK8:%.*]] = load float, ptr [[DOTUNPACK_ELT7]], align 4 |
| 91 | +; CHECK-NEXT: [[DOTUNPACK_ELT9:%.*]] = getelementptr inbounds nuw i8, ptr [[V]], i64 8 |
| 92 | +; CHECK-NEXT: [[DOTUNPACK_UNPACK10:%.*]] = load float, ptr [[DOTUNPACK_ELT9]], align 8 |
| 93 | +; CHECK-NEXT: [[DOTELT1:%.*]] = getelementptr inbounds nuw i8, ptr [[V]], i64 12 |
| 94 | +; CHECK-NEXT: [[DOTUNPACK2_UNPACK:%.*]] = load float, ptr [[DOTELT1]], align 4 |
| 95 | +; CHECK-NEXT: br label %[[END:.*]] |
| 96 | +; CHECK: [[BRANCH2]]: |
| 97 | +; CHECK-NEXT: [[DOTUNPACK2_ELT12:%.*]] = getelementptr inbounds nuw i8, ptr [[V]], i64 16 |
| 98 | +; CHECK-NEXT: [[DOTUNPACK2_UNPACK13:%.*]] = load float, ptr [[DOTUNPACK2_ELT12]], align 4 |
| 99 | +; CHECK-NEXT: [[DOTUNPACK2_ELT14:%.*]] = getelementptr inbounds nuw i8, ptr [[V]], i64 20 |
| 100 | +; CHECK-NEXT: [[DOTUNPACK2_UNPACK15:%.*]] = load float, ptr [[DOTUNPACK2_ELT14]], align 4 |
| 101 | +; CHECK-NEXT: [[DOTELT3:%.*]] = getelementptr inbounds nuw i8, ptr [[V]], i64 24 |
| 102 | +; CHECK-NEXT: [[DOTUNPACK4:%.*]] = load i32, ptr [[DOTELT3]], align 8 |
| 103 | +; CHECK-NEXT: [[DOTELT5:%.*]] = getelementptr inbounds nuw i8, ptr [[V]], i64 28 |
| 104 | +; CHECK-NEXT: [[DOTUNPACK6:%.*]] = load i32, ptr [[DOTELT5]], align 4 |
| 105 | +; CHECK-NEXT: br label %[[END]] |
| 106 | +; CHECK: [[END]]: |
| 107 | +; CHECK-NEXT: ret void |
| 108 | +; |
| 109 | + br i1 %cond, label %branch1, label %branch2 |
| 110 | + |
| 111 | +branch1: |
| 112 | + %.unpack.unpack = load float, ptr %v, align 16 |
| 113 | + %.unpack.elt7 = getelementptr inbounds nuw i8, ptr %v, i64 4 |
| 114 | + %.unpack.unpack8 = load float, ptr %.unpack.elt7, align 4 |
| 115 | + %.unpack.elt9 = getelementptr inbounds nuw i8, ptr %v, i64 8 |
| 116 | + %.unpack.unpack10 = load float, ptr %.unpack.elt9, align 8 |
| 117 | + %.elt1 = getelementptr inbounds nuw i8, ptr %v, i64 12 |
| 118 | + %.unpack2.unpack = load float, ptr %.elt1, align 4 |
| 119 | + br label %end |
| 120 | + |
| 121 | +branch2: |
| 122 | + %.unpack2.elt12 = getelementptr inbounds nuw i8, ptr %v, i64 16 |
| 123 | + %.unpack2.unpack13 = load float, ptr %.unpack2.elt12, align 4 |
| 124 | + %.unpack2.elt14 = getelementptr inbounds nuw i8, ptr %v, i64 20 |
| 125 | + %.unpack2.unpack15 = load float, ptr %.unpack2.elt14, align 4 |
| 126 | + %.elt3 = getelementptr inbounds nuw i8, ptr %v, i64 24 |
| 127 | + %.unpack4 = load i32, ptr %.elt3, align 8 |
| 128 | + %.elt5 = getelementptr inbounds nuw i8, ptr %v, i64 28 |
| 129 | + %.unpack6 = load i32, ptr %.elt5, align 4 |
| 130 | + br label %end |
| 131 | + |
| 132 | +end: |
| 133 | + ret void |
| 134 | +} |
| 135 | + |
| 136 | +; ------------------------------------------------------------------------------ |
| 137 | +; Test that we can propagate to/from negative offset GEPs |
| 138 | +; ------------------------------------------------------------------------------ |
| 139 | + |
| 140 | +define void @prop_align_negative_offset(ptr %v) { |
| 141 | +; CHECK-LABEL: define void @prop_align_negative_offset( |
| 142 | +; CHECK-SAME: ptr [[V:%.*]]) { |
| 143 | +; CHECK-NEXT: [[LOADALIGNED:%.*]] = load float, ptr [[V]], align 16 |
| 144 | +; CHECK-NEXT: [[GEPNEGATIVE:%.*]] = getelementptr inbounds nuw i8, ptr [[V]], i64 -16 |
| 145 | +; CHECK-NEXT: [[LOADUNALIGNED:%.*]] = load float, ptr [[GEPNEGATIVE]], align 16 |
| 146 | +; CHECK-NEXT: ret void |
| 147 | +; |
| 148 | + %loadAligned= load float, ptr %v, align 16 |
| 149 | + %gepNegative = getelementptr inbounds nuw i8, ptr %v, i64 -16 |
| 150 | + %loadUnaligned = load float, ptr %gepNegative, align 4 |
| 151 | + ret void |
| 152 | +} |
| 153 | + |
| 154 | +define void @prop_align_negative_offset_2(ptr %v) { |
| 155 | +; CHECK-LABEL: define void @prop_align_negative_offset_2( |
| 156 | +; CHECK-SAME: ptr [[V:%.*]]) { |
| 157 | +; CHECK-NEXT: [[GEPNEGATIVE:%.*]] = getelementptr inbounds nuw i8, ptr [[V]], i64 -16 |
| 158 | +; CHECK-NEXT: [[LOADALIGNED:%.*]] = load float, ptr [[GEPNEGATIVE]], align 16 |
| 159 | +; CHECK-NEXT: [[LOADUNALIGNED:%.*]] = load float, ptr [[V]], align 16 |
| 160 | +; CHECK-NEXT: ret void |
| 161 | +; |
| 162 | + %gepNegative = getelementptr inbounds nuw i8, ptr %v, i64 -16 |
| 163 | + %loadAligned = load float, ptr %gepNegative, align 16 |
| 164 | + %loadUnaligned= load float, ptr %v, align 4 |
| 165 | + ret void |
| 166 | +} |
| 167 | + |
| 168 | +define void @prop_align_negative_offset_3(ptr %v) { |
| 169 | +; CHECK-LABEL: define void @prop_align_negative_offset_3( |
| 170 | +; CHECK-SAME: ptr [[V:%.*]]) { |
| 171 | +; CHECK-NEXT: [[LOADALIGNED:%.*]] = load float, ptr [[V]], align 16 |
| 172 | +; CHECK-NEXT: [[GEPNEGATIVE:%.*]] = getelementptr inbounds nuw i8, ptr [[V]], i64 -8 |
| 173 | +; CHECK-NEXT: [[LOADUNALIGNED:%.*]] = load float, ptr [[GEPNEGATIVE]], align 8 |
| 174 | +; CHECK-NEXT: ret void |
| 175 | +; |
| 176 | + %loadAligned= load float, ptr %v, align 16 |
| 177 | + %gepNegative = getelementptr inbounds nuw i8, ptr %v, i64 -8 |
| 178 | + %loadUnaligned = load float, ptr %gepNegative, align 4 |
| 179 | + ret void |
| 180 | +} |
| 181 | + |
| 182 | +define void @prop_align_negative_offset_4(ptr %v) { |
| 183 | +; CHECK-LABEL: define void @prop_align_negative_offset_4( |
| 184 | +; CHECK-SAME: ptr [[V:%.*]]) { |
| 185 | +; CHECK-NEXT: [[LOADALIGNED:%.*]] = load float, ptr [[V]], align 16 |
| 186 | +; CHECK-NEXT: [[GEPNEGATIVE:%.*]] = getelementptr inbounds nuw i8, ptr [[V]], i64 -20 |
| 187 | +; CHECK-NEXT: [[LOADUNALIGNED:%.*]] = load float, ptr [[GEPNEGATIVE]], align 4 |
| 188 | +; CHECK-NEXT: ret void |
| 189 | +; |
| 190 | + %loadAligned= load float, ptr %v, align 16 |
| 191 | + %gepNegative = getelementptr inbounds nuw i8, ptr %v, i64 -20 |
| 192 | + %loadUnaligned = load float, ptr %gepNegative, align 4 |
| 193 | + ret void |
| 194 | +} |
0 commit comments