|
| 1 | +; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+sme2 -aarch64-new-sme-abi < %s | FileCheck %s |
| 2 | + |
| 3 | +; This test case was generated by lowering mlir/test/Integration/Dialect/Linalg/CPU/ArmSME/matmul.mlir to LLVM IR. |
| 4 | +; The actual contents of the function are not that important. The main interesting quality here is that many blocks |
| 5 | +; don't directly use ZA. The only blocks that require ZA are the MOPA (and load/stores) in the inner loop, and the |
| 6 | +;`printMemrefF32()` call in the exit block. |
| 7 | +; |
| 8 | +; If ZA states are not propagated in the MachineSMEABIPass block %48 (which is within the outer loop), will |
| 9 | +; have an edge to block %226 (the exit block), which requires ZA in the "saved" state, and an edge to block %51 |
| 10 | +; (which has no preference on ZA state). This means block %48 will also end up in the locally saved state. |
| 11 | +; This is not really what we want, as it means we will save/restore ZA in the outer loop. We can fix this by |
| 12 | +; propagating the "active" state from the inner loop through basic blocks with no preference, to ensure the outer |
| 13 | +; loop is in the "active" state too. |
| 14 | +; |
| 15 | +; If done correctly, the only ZA save/restore should be in the exit block (with all other blocks in the active state). |
| 16 | + |
| 17 | +define void @matmul(ptr %0, ptr %1, i64 %2, i64 %3, i64 %4, i64 %5, i64 %6, ptr %7, ptr %8, i64 %9, i64 %10, i64 %11, i64 %12, i64 %13, ptr %14, ptr %15, i64 %16, i64 %17, i64 %18, i64 %19, i64 %20) #0 { |
| 18 | +; Check for a ZA zero in the entry block, then no uses of TPIDR2_EL0 (for ZA saves/restore) |
| 19 | +; until the exit block (which contains the call to printMemrefF32). |
| 20 | +; |
| 21 | +; CHECK-LABEL: matmul: |
| 22 | +; CHECK: zero {za} |
| 23 | +; CHECK-NOT: TPIDR2_EL0 |
| 24 | +; CHECK: msr TPIDR2_EL0, x{{.*}} |
| 25 | +; CHECK-NOT: .LBB{{.*}} |
| 26 | +; CHECK: bl printMemrefF32 |
| 27 | + %22 = insertvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } poison, ptr %14, 0 |
| 28 | + %23 = insertvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %22, ptr %15, 1 |
| 29 | + %24 = insertvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %23, i64 %16, 2 |
| 30 | + %25 = insertvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %24, i64 %17, 3, 0 |
| 31 | + %26 = insertvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %25, i64 %19, 4, 0 |
| 32 | + %27 = insertvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %26, i64 %18, 3, 1 |
| 33 | + %28 = insertvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %27, i64 %20, 4, 1 |
| 34 | + %29 = insertvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } poison, ptr %7, 0 |
| 35 | + %30 = insertvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %29, ptr %8, 1 |
| 36 | + %31 = insertvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %30, i64 %9, 2 |
| 37 | + %32 = insertvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %31, i64 %10, 3, 0 |
| 38 | + %33 = insertvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %32, i64 %12, 4, 0 |
| 39 | + %34 = insertvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %33, i64 %11, 3, 1 |
| 40 | + %35 = insertvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %34, i64 %13, 4, 1 |
| 41 | + %36 = insertvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } poison, ptr %0, 0 |
| 42 | + %37 = insertvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %36, ptr %1, 1 |
| 43 | + %38 = insertvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %37, i64 %2, 2 |
| 44 | + %39 = insertvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %38, i64 %3, 3, 0 |
| 45 | + %40 = insertvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %39, i64 %5, 4, 0 |
| 46 | + %41 = insertvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %40, i64 %4, 3, 1 |
| 47 | + %42 = insertvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %41, i64 %6, 4, 1 |
| 48 | + %43 = extractvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %42, 3, 0 |
| 49 | + %44 = extractvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %42, 3, 1 |
| 50 | + %45 = extractvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %35, 3, 1 |
| 51 | + %46 = call i64 @llvm.vscale.i64() |
| 52 | + %47 = mul i64 %46, 4 |
| 53 | + br label %48 |
| 54 | + |
| 55 | +48: ; preds = %224, %21 |
| 56 | + %49 = phi i64 [ %225, %224 ], [ 0, %21 ] |
| 57 | + %50 = icmp slt i64 %49, %43 |
| 58 | + br i1 %50, label %51, label %226 |
| 59 | + |
| 60 | +51: ; preds = %48 |
| 61 | + %52 = sub i64 %43, %49 |
| 62 | + %53 = call i64 @llvm.smin.i64(i64 %47, i64 %52) |
| 63 | + %54 = call <vscale x 4 x i32> @llvm.stepvector.nxv4i32() |
| 64 | + %55 = trunc i64 %53 to i32 |
| 65 | + %56 = insertelement <vscale x 4 x i32> poison, i32 %55, i32 0 |
| 66 | + %57 = shufflevector <vscale x 4 x i32> %56, <vscale x 4 x i32> poison, <vscale x 4 x i32> zeroinitializer |
| 67 | + %58 = icmp slt <vscale x 4 x i32> %54, %57 |
| 68 | + br label %59 |
| 69 | + |
| 70 | +59: ; preds = %222, %51 |
| 71 | + %60 = phi i64 [ %223, %222 ], [ 0, %51 ] |
| 72 | + %61 = icmp slt i64 %60, %45 |
| 73 | + br i1 %61, label %62, label %224 |
| 74 | + |
| 75 | +62: ; preds = %59 |
| 76 | + %63 = sub i64 %45, %60 |
| 77 | + %64 = call i64 @llvm.smin.i64(i64 %47, i64 %63) |
| 78 | + %65 = extractvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %28, 0 |
| 79 | + %66 = extractvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %28, 1 |
| 80 | + %67 = insertvalue { ptr, ptr, i64 } poison, ptr %65, 0 |
| 81 | + %68 = insertvalue { ptr, ptr, i64 } %67, ptr %66, 1 |
| 82 | + %69 = insertvalue { ptr, ptr, i64 } %68, i64 0, 2 |
| 83 | + %70 = extractvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %28, 2 |
| 84 | + %71 = extractvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %28, 3, 0 |
| 85 | + %72 = extractvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %28, 3, 1 |
| 86 | + %73 = extractvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %28, 4, 0 |
| 87 | + %74 = extractvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %28, 4, 1 |
| 88 | + %75 = mul nsw i64 %49, %73 |
| 89 | + %76 = add i64 %70, %75 |
| 90 | + %77 = mul nsw i64 %60, %74 |
| 91 | + %78 = add i64 %76, %77 |
| 92 | + %79 = extractvalue { ptr, ptr, i64 } %69, 0 |
| 93 | + %80 = extractvalue { ptr, ptr, i64 } %69, 1 |
| 94 | + %81 = insertvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } poison, ptr %79, 0 |
| 95 | + %82 = insertvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %81, ptr %80, 1 |
| 96 | + %83 = insertvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %82, i64 %78, 2 |
| 97 | + %84 = insertvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %83, i64 %53, 3, 0 |
| 98 | + %85 = insertvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %84, i64 %73, 4, 0 |
| 99 | + %86 = insertvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %85, i64 %64, 3, 1 |
| 100 | + %87 = insertvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %86, i64 %74, 4, 1 |
| 101 | + %88 = call <vscale x 4 x i32> @llvm.stepvector.nxv4i32() |
| 102 | + %89 = trunc i64 %64 to i32 |
| 103 | + %90 = insertelement <vscale x 4 x i32> poison, i32 %89, i32 0 |
| 104 | + %91 = shufflevector <vscale x 4 x i32> %90, <vscale x 4 x i32> poison, <vscale x 4 x i32> zeroinitializer |
| 105 | + %92 = icmp slt <vscale x 4 x i32> %88, %91 |
| 106 | + br label %93 |
| 107 | + |
| 108 | +93: ; preds = %220, %62 |
| 109 | + %94 = phi i64 [ %221, %220 ], [ 0, %62 ] |
| 110 | + %95 = icmp slt i64 %94, %44 |
| 111 | + br i1 %95, label %96, label %222 |
| 112 | + |
| 113 | +96: ; preds = %93 |
| 114 | + %97 = extractvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %42, 0 |
| 115 | + %98 = extractvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %42, 1 |
| 116 | + %99 = insertvalue { ptr, ptr, i64 } poison, ptr %97, 0 |
| 117 | + %100 = insertvalue { ptr, ptr, i64 } %99, ptr %98, 1 |
| 118 | + %101 = insertvalue { ptr, ptr, i64 } %100, i64 0, 2 |
| 119 | + %102 = extractvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %42, 2 |
| 120 | + %103 = extractvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %42, 3, 0 |
| 121 | + %104 = extractvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %42, 3, 1 |
| 122 | + %105 = extractvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %42, 4, 0 |
| 123 | + %106 = extractvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %42, 4, 1 |
| 124 | + %107 = mul nsw i64 %49, %105 |
| 125 | + %108 = add i64 %102, %107 |
| 126 | + %109 = mul nsw i64 %94, %106 |
| 127 | + %110 = add i64 %108, %109 |
| 128 | + %111 = extractvalue { ptr, ptr, i64 } %101, 0 |
| 129 | + %112 = extractvalue { ptr, ptr, i64 } %101, 1 |
| 130 | + %113 = insertvalue { ptr, ptr, i64, [1 x i64], [1 x i64] } poison, ptr %111, 0 |
| 131 | + %114 = insertvalue { ptr, ptr, i64, [1 x i64], [1 x i64] } %113, ptr %112, 1 |
| 132 | + %115 = insertvalue { ptr, ptr, i64, [1 x i64], [1 x i64] } %114, i64 %110, 2 |
| 133 | + %116 = insertvalue { ptr, ptr, i64, [1 x i64], [1 x i64] } %115, i64 %53, 3, 0 |
| 134 | + %117 = insertvalue { ptr, ptr, i64, [1 x i64], [1 x i64] } %116, i64 %105, 4, 0 |
| 135 | + br label %118 |
| 136 | + |
| 137 | +118: ; preds = %133, %96 |
| 138 | + %119 = phi i64 [ %135, %133 ], [ 0, %96 ] |
| 139 | + %120 = phi <vscale x 4 x float> [ %134, %133 ], [ poison, %96 ] |
| 140 | + %121 = icmp slt i64 %119, %47 |
| 141 | + br i1 %121, label %122, label %136 |
| 142 | + |
| 143 | +122: ; preds = %118 |
| 144 | + %123 = extractelement <vscale x 4 x i1> %58, i64 %119 |
| 145 | + br i1 %123, label %124, label %133 |
| 146 | + |
| 147 | +124: ; preds = %122 |
| 148 | + %125 = extractvalue { ptr, ptr, i64, [1 x i64], [1 x i64] } %117, 1 |
| 149 | + %126 = extractvalue { ptr, ptr, i64, [1 x i64], [1 x i64] } %117, 2 |
| 150 | + %127 = getelementptr float, ptr %125, i64 %126 |
| 151 | + %128 = extractvalue { ptr, ptr, i64, [1 x i64], [1 x i64] } %117, 4, 0 |
| 152 | + %129 = mul nuw nsw i64 %119, %128 |
| 153 | + %130 = getelementptr inbounds nuw float, ptr %127, i64 %129 |
| 154 | + %131 = load float, ptr %130, align 4 |
| 155 | + %132 = insertelement <vscale x 4 x float> %120, float %131, i64 %119 |
| 156 | + br label %133 |
| 157 | + |
| 158 | +133: ; preds = %124, %122 |
| 159 | + %134 = phi <vscale x 4 x float> [ %132, %124 ], [ %120, %122 ] |
| 160 | + %135 = add i64 %119, 1 |
| 161 | + br label %118 |
| 162 | + |
| 163 | +136: ; preds = %118 |
| 164 | + %137 = extractvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %35, 0 |
| 165 | + %138 = extractvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %35, 1 |
| 166 | + %139 = insertvalue { ptr, ptr, i64 } poison, ptr %137, 0 |
| 167 | + %140 = insertvalue { ptr, ptr, i64 } %139, ptr %138, 1 |
| 168 | + %141 = insertvalue { ptr, ptr, i64 } %140, i64 0, 2 |
| 169 | + %142 = extractvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %35, 2 |
| 170 | + %143 = extractvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %35, 3, 0 |
| 171 | + %144 = extractvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %35, 3, 1 |
| 172 | + %145 = extractvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %35, 4, 0 |
| 173 | + %146 = extractvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %35, 4, 1 |
| 174 | + %147 = mul nsw i64 %94, %145 |
| 175 | + %148 = add i64 %142, %147 |
| 176 | + %149 = mul nsw i64 %60, %146 |
| 177 | + %150 = add i64 %148, %149 |
| 178 | + %151 = extractvalue { ptr, ptr, i64 } %141, 0 |
| 179 | + %152 = extractvalue { ptr, ptr, i64 } %141, 1 |
| 180 | + %153 = insertvalue { ptr, ptr, i64, [1 x i64], [1 x i64] } poison, ptr %151, 0 |
| 181 | + %154 = insertvalue { ptr, ptr, i64, [1 x i64], [1 x i64] } %153, ptr %152, 1 |
| 182 | + %155 = insertvalue { ptr, ptr, i64, [1 x i64], [1 x i64] } %154, i64 %150, 2 |
| 183 | + %156 = insertvalue { ptr, ptr, i64, [1 x i64], [1 x i64] } %155, i64 %64, 3, 0 |
| 184 | + %157 = insertvalue { ptr, ptr, i64, [1 x i64], [1 x i64] } %156, i64 %146, 4, 0 |
| 185 | + br label %158 |
| 186 | + |
| 187 | +158: ; preds = %173, %136 |
| 188 | + %159 = phi i64 [ %175, %173 ], [ 0, %136 ] |
| 189 | + %160 = phi <vscale x 4 x float> [ %174, %173 ], [ poison, %136 ] |
| 190 | + %161 = icmp slt i64 %159, %47 |
| 191 | + br i1 %161, label %162, label %176 |
| 192 | + |
| 193 | +162: ; preds = %158 |
| 194 | + %163 = extractelement <vscale x 4 x i1> %92, i64 %159 |
| 195 | + br i1 %163, label %164, label %173 |
| 196 | + |
| 197 | +164: ; preds = %162 |
| 198 | + %165 = extractvalue { ptr, ptr, i64, [1 x i64], [1 x i64] } %157, 1 |
| 199 | + %166 = extractvalue { ptr, ptr, i64, [1 x i64], [1 x i64] } %157, 2 |
| 200 | + %167 = getelementptr float, ptr %165, i64 %166 |
| 201 | + %168 = extractvalue { ptr, ptr, i64, [1 x i64], [1 x i64] } %157, 4, 0 |
| 202 | + %169 = mul nuw nsw i64 %159, %168 |
| 203 | + %170 = getelementptr inbounds nuw float, ptr %167, i64 %169 |
| 204 | + %171 = load float, ptr %170, align 4 |
| 205 | + %172 = insertelement <vscale x 4 x float> %160, float %171, i64 %159 |
| 206 | + br label %173 |
| 207 | + |
| 208 | +173: ; preds = %164, %162 |
| 209 | + %174 = phi <vscale x 4 x float> [ %172, %164 ], [ %160, %162 ] |
| 210 | + %175 = add i64 %159, 1 |
| 211 | + br label %158 |
| 212 | + |
| 213 | +176: ; preds = %158 |
| 214 | + %177 = trunc i64 %64 to i32 |
| 215 | + br label %178 |
| 216 | + |
| 217 | +178: ; preds = %181, %176 |
| 218 | + %179 = phi i64 [ %202, %181 ], [ 0, %176 ] |
| 219 | + %180 = icmp slt i64 %179, %47 |
| 220 | + br i1 %180, label %181, label %203 |
| 221 | + |
| 222 | +181: ; preds = %178 |
| 223 | + %182 = icmp ult i64 %179, %53 |
| 224 | + %183 = sext i1 %182 to i32 |
| 225 | + %184 = and i32 %183, %177 |
| 226 | + %185 = sext i32 %184 to i64 |
| 227 | + %186 = call <vscale x 4 x i32> @llvm.stepvector.nxv4i32() |
| 228 | + %187 = trunc i64 %185 to i32 |
| 229 | + %188 = insertelement <vscale x 4 x i32> poison, i32 %187, i32 0 |
| 230 | + %189 = shufflevector <vscale x 4 x i32> %188, <vscale x 4 x i32> poison, <vscale x 4 x i32> zeroinitializer |
| 231 | + %190 = icmp slt <vscale x 4 x i32> %186, %189 |
| 232 | + %191 = extractvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %87, 1 |
| 233 | + %192 = extractvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %87, 2 |
| 234 | + %193 = getelementptr float, ptr %191, i64 %192 |
| 235 | + %194 = extractvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %87, 4, 0 |
| 236 | + %195 = mul i64 %179, %194 |
| 237 | + %196 = extractvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %87, 4, 1 |
| 238 | + %197 = mul i64 0, %196 |
| 239 | + %198 = add i64 %195, %197 |
| 240 | + %199 = getelementptr float, ptr %193, i64 %198 |
| 241 | + %200 = call <vscale x 4 x float> @llvm.masked.load.nxv4f32.p0(ptr %199, i32 4, <vscale x 4 x i1> %190, <vscale x 4 x float> poison) |
| 242 | + %201 = trunc i64 %179 to i32 |
| 243 | + call void @llvm.aarch64.sme.write.horiz.nxv4f32(i32 0, i32 %201, <vscale x 4 x i1> splat (i1 true), <vscale x 4 x float> %200) |
| 244 | + %202 = add i64 %179, 1 |
| 245 | + br label %178 |
| 246 | + |
| 247 | +203: ; preds = %178 |
| 248 | + call void @llvm.aarch64.sme.mopa.nxv4f32(i32 0, <vscale x 4 x i1> %58, <vscale x 4 x i1> %92, <vscale x 4 x float> %120, <vscale x 4 x float> %160) |
| 249 | + %204 = call i64 @llvm.smin.i64(i64 %53, i64 %47) |
| 250 | + br label %205 |
| 251 | + |
| 252 | +205: ; preds = %208, %203 |
| 253 | + %206 = phi i64 [ %219, %208 ], [ 0, %203 ] |
| 254 | + %207 = icmp slt i64 %206, %204 |
| 255 | + br i1 %207, label %208, label %220 |
| 256 | + |
| 257 | +208: ; preds = %205 |
| 258 | + %209 = extractvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %87, 1 |
| 259 | + %210 = extractvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %87, 2 |
| 260 | + %211 = getelementptr float, ptr %209, i64 %210 |
| 261 | + %212 = extractvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %87, 4, 0 |
| 262 | + %213 = mul i64 %206, %212 |
| 263 | + %214 = extractvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %87, 4, 1 |
| 264 | + %215 = mul i64 0, %214 |
| 265 | + %216 = add i64 %213, %215 |
| 266 | + %217 = getelementptr float, ptr %211, i64 %216 |
| 267 | + %218 = trunc i64 %206 to i32 |
| 268 | + call void @llvm.aarch64.sme.st1w.horiz(<vscale x 4 x i1> %92, ptr %217, i32 0, i32 %218) |
| 269 | + %219 = add i64 %206, 1 |
| 270 | + br label %205 |
| 271 | + |
| 272 | +220: ; preds = %205 |
| 273 | + %221 = add i64 %94, 1 |
| 274 | + br label %93 |
| 275 | + |
| 276 | +222: ; preds = %93 |
| 277 | + %223 = add i64 %60, %47 |
| 278 | + br label %59 |
| 279 | + |
| 280 | +224: ; preds = %59 |
| 281 | + %225 = add i64 %49, %47 |
| 282 | + br label %48 |
| 283 | + |
| 284 | +226: ; preds = %48 |
| 285 | + %227 = alloca { ptr, ptr, i64, [2 x i64], [2 x i64] }, i64 1, align 8 |
| 286 | + store { ptr, ptr, i64, [2 x i64], [2 x i64] } %28, ptr %227, align 8 |
| 287 | + %228 = insertvalue { i64, ptr } { i64 2, ptr poison }, ptr %227, 1 |
| 288 | + %229 = extractvalue { i64, ptr } %228, 0 |
| 289 | + %230 = extractvalue { i64, ptr } %228, 1 |
| 290 | + call void @printMemrefF32(i64 %229, ptr %230) |
| 291 | + ret void |
| 292 | +} |
| 293 | + |
| 294 | +declare void @printMemrefF32(i64, ptr) |
| 295 | + |
| 296 | +attributes #0 = { "aarch64_new_za" "aarch64_pstate_sm_body" } |
0 commit comments