Source file test/codegen/arithmetic.go
1 // asmcheck 2 3 // Copyright 2018 The Go Authors. All rights reserved. 4 // Use of this source code is governed by a BSD-style 5 // license that can be found in the LICENSE file. 6 7 package codegen 8 9 // This file contains codegen tests related to arithmetic 10 // simplifications and optimizations on integer types. 11 // For codegen tests on float types, see floats.go. 12 13 // ----------------- // 14 // Addition // 15 // ----------------- // 16 17 func AddLargeConst(a uint64, out []uint64) { 18 // ppc64x/power10:"ADD\t[$]4294967296," 19 // ppc64x/power9:"MOVD\t[$]1", "SLD\t[$]32" "ADD\tR[0-9]*" 20 // ppc64x/power8:"MOVD\t[$]1", "SLD\t[$]32" "ADD\tR[0-9]*" 21 out[0] = a + 0x100000000 22 // ppc64x/power10:"ADD\t[$]-8589934592," 23 // ppc64x/power9:"MOVD\t[$]-1", "SLD\t[$]33" "ADD\tR[0-9]*" 24 // ppc64x/power8:"MOVD\t[$]-1", "SLD\t[$]33" "ADD\tR[0-9]*" 25 out[1] = a + 0xFFFFFFFE00000000 26 } 27 28 // ----------------- // 29 // Subtraction // 30 // ----------------- // 31 32 var ef int 33 34 func SubMem(arr []int, b, c, d int) int { 35 // 386:`SUBL\s[A-Z]+,\s8\([A-Z]+\)` 36 // amd64:`SUBQ\s[A-Z]+,\s16\([A-Z]+\)` 37 arr[2] -= b 38 // 386:`SUBL\s[A-Z]+,\s12\([A-Z]+\)` 39 // amd64:`SUBQ\s[A-Z]+,\s24\([A-Z]+\)` 40 arr[3] -= b 41 // 386:`DECL\s16\([A-Z]+\)` 42 arr[4]-- 43 // 386:`ADDL\s[$]-20,\s20\([A-Z]+\)` 44 arr[5] -= 20 45 // 386:`SUBL\s\([A-Z]+\)\([A-Z]+\*4\),\s[A-Z]+` 46 ef -= arr[b] 47 // 386:`SUBL\s[A-Z]+,\s\([A-Z]+\)\([A-Z]+\*4\)` 48 arr[c] -= b 49 // 386:`ADDL\s[$]-15,\s\([A-Z]+\)\([A-Z]+\*4\)` 50 arr[d] -= 15 51 // 386:`DECL\s\([A-Z]+\)\([A-Z]+\*4\)` 52 arr[b]-- 53 // amd64:`DECQ\s64\([A-Z]+\)` 54 arr[8]-- 55 // 386:"SUBL\t4" 56 // amd64:"SUBQ\t8" 57 return arr[0] - arr[1] 58 } 59 60 func SubFromConst(a int) int { 61 // ppc64x: `SUBC\tR[0-9]+,\s[$]40,\sR` 62 b := 40 - a 63 return b 64 } 65 66 func SubFromConstNeg(a int) int { 67 // ppc64x: `ADD\t[$]40,\sR[0-9]+,\sR` 68 c := 40 - (-a) 69 return c 70 } 71 72 func SubSubFromConst(a int) int { 73 // ppc64x: `ADD\t[$]20,\sR[0-9]+,\sR` 74 c := 40 - (20 - a) 75 return c 76 } 77 78 func AddSubFromConst(a int) int { 79 // ppc64x: `SUBC\tR[0-9]+,\s[$]60,\sR` 80 c := 40 + (20 - a) 81 return c 82 } 83 84 func NegSubFromConst(a int) int { 85 // ppc64x: `ADD\t[$]-20,\sR[0-9]+,\sR` 86 c := -(20 - a) 87 return c 88 } 89 90 func NegAddFromConstNeg(a int) int { 91 // ppc64x: `SUBC\tR[0-9]+,\s[$]40,\sR` 92 c := -(-40 + a) 93 return c 94 } 95 96 func SubSubNegSimplify(a, b int) int { 97 // amd64:"NEGQ" 98 // ppc64x:"NEG" 99 r := (a - b) - a 100 return r 101 } 102 103 func SubAddSimplify(a, b int) int { 104 // amd64:-"SUBQ",-"ADDQ" 105 // ppc64x:-"SUB",-"ADD" 106 r := a + (b - a) 107 return r 108 } 109 110 func SubAddSimplify2(a, b, c int) (int, int, int, int, int, int) { 111 // amd64:-"ADDQ" 112 r := (a + b) - (a + c) 113 // amd64:-"ADDQ" 114 r1 := (a + b) - (c + a) 115 // amd64:-"ADDQ" 116 r2 := (b + a) - (a + c) 117 // amd64:-"ADDQ" 118 r3 := (b + a) - (c + a) 119 // amd64:-"SUBQ" 120 r4 := (a - c) + (c + b) 121 // amd64:-"SUBQ" 122 r5 := (a - c) + (b + c) 123 return r, r1, r2, r3, r4, r5 124 } 125 126 func SubAddNegSimplify(a, b int) int { 127 // amd64:"NEGQ",-"ADDQ",-"SUBQ" 128 // ppc64x:"NEG",-"ADD",-"SUB" 129 r := a - (b + a) 130 return r 131 } 132 133 func AddAddSubSimplify(a, b, c int) int { 134 // amd64:-"SUBQ" 135 // ppc64x:-"SUB" 136 r := a + (b + (c - a)) 137 return r 138 } 139 140 // -------------------- // 141 // Multiplication // 142 // -------------------- // 143 144 func Pow2Muls(n1, n2 int) (int, int) { 145 // amd64:"SHLQ\t[$]5",-"IMULQ" 146 // 386:"SHLL\t[$]5",-"IMULL" 147 // arm:"SLL\t[$]5",-"MUL" 148 // arm64:"LSL\t[$]5",-"MUL" 149 // ppc64x:"SLD\t[$]5",-"MUL" 150 a := n1 * 32 151 152 // amd64:"SHLQ\t[$]6",-"IMULQ" 153 // 386:"SHLL\t[$]6",-"IMULL" 154 // arm:"SLL\t[$]6",-"MUL" 155 // arm64:`NEG\sR[0-9]+<<6,\sR[0-9]+`,-`LSL`,-`MUL` 156 // ppc64x:"SLD\t[$]6","NEG\\sR[0-9]+,\\sR[0-9]+",-"MUL" 157 b := -64 * n2 158 159 return a, b 160 } 161 162 func Mul_96(n int) int { 163 // amd64:`SHLQ\t[$]5`,`LEAQ\t\(.*\)\(.*\*2\),`,-`IMULQ` 164 // 386:`SHLL\t[$]5`,`LEAL\t\(.*\)\(.*\*2\),`,-`IMULL` 165 // arm64:`LSL\t[$]5`,`ADD\sR[0-9]+<<1,\sR[0-9]+`,-`MUL` 166 // arm:`SLL\t[$]5`,`ADD\sR[0-9]+<<1,\sR[0-9]+`,-`MUL` 167 // s390x:`SLD\t[$]5`,`SLD\t[$]6`,-`MULLD` 168 return n * 96 169 } 170 171 func Mul_n120(n int) int { 172 // s390x:`SLD\t[$]3`,`SLD\t[$]7`,-`MULLD` 173 return n * -120 174 } 175 176 func MulMemSrc(a []uint32, b []float32) { 177 // 386:`IMULL\s4\([A-Z]+\),\s[A-Z]+` 178 a[0] *= a[1] 179 // 386/sse2:`MULSS\s4\([A-Z]+\),\sX[0-9]+` 180 // amd64:`MULSS\s4\([A-Z]+\),\sX[0-9]+` 181 b[0] *= b[1] 182 } 183 184 // Multiplications merging tests 185 186 func MergeMuls1(n int) int { 187 // amd64:"IMUL3Q\t[$]46" 188 // 386:"IMUL3L\t[$]46" 189 // ppc64x:"MULLD\t[$]46" 190 return 15*n + 31*n // 46n 191 } 192 193 func MergeMuls2(n int) int { 194 // amd64:"IMUL3Q\t[$]23","(ADDQ\t[$]29)|(LEAQ\t29)" 195 // 386:"IMUL3L\t[$]23","ADDL\t[$]29" 196 // ppc64x/power9:"MADDLD",-"MULLD\t[$]23",-"ADD\t[$]29" 197 // ppc64x/power8:"MULLD\t[$]23","ADD\t[$]29" 198 return 5*n + 7*(n+1) + 11*(n+2) // 23n + 29 199 } 200 201 func MergeMuls3(a, n int) int { 202 // amd64:"ADDQ\t[$]19",-"IMULQ\t[$]19" 203 // 386:"ADDL\t[$]19",-"IMULL\t[$]19" 204 // ppc64x:"ADD\t[$]19",-"MULLD\t[$]19" 205 return a*n + 19*n // (a+19)n 206 } 207 208 func MergeMuls4(n int) int { 209 // amd64:"IMUL3Q\t[$]14" 210 // 386:"IMUL3L\t[$]14" 211 // ppc64x:"MULLD\t[$]14" 212 return 23*n - 9*n // 14n 213 } 214 215 func MergeMuls5(a, n int) int { 216 // amd64:"ADDQ\t[$]-19",-"IMULQ\t[$]19" 217 // 386:"ADDL\t[$]-19",-"IMULL\t[$]19" 218 // ppc64x:"ADD\t[$]-19",-"MULLD\t[$]19" 219 return a*n - 19*n // (a-19)n 220 } 221 222 // -------------- // 223 // Division // 224 // -------------- // 225 226 func DivMemSrc(a []float64) { 227 // 386/sse2:`DIVSD\s8\([A-Z]+\),\sX[0-9]+` 228 // amd64:`DIVSD\s8\([A-Z]+\),\sX[0-9]+` 229 a[0] /= a[1] 230 } 231 232 func Pow2Divs(n1 uint, n2 int) (uint, int) { 233 // 386:"SHRL\t[$]5",-"DIVL" 234 // amd64:"SHRQ\t[$]5",-"DIVQ" 235 // arm:"SRL\t[$]5",-".*udiv" 236 // arm64:"LSR\t[$]5",-"UDIV" 237 // ppc64x:"SRD" 238 a := n1 / 32 // unsigned 239 240 // amd64:"SARQ\t[$]6",-"IDIVQ" 241 // 386:"SARL\t[$]6",-"IDIVL" 242 // arm:"SRA\t[$]6",-".*udiv" 243 // arm64:"ASR\t[$]6",-"SDIV" 244 // ppc64x:"SRAD" 245 b := n2 / 64 // signed 246 247 return a, b 248 } 249 250 // Check that constant divisions get turned into MULs 251 func ConstDivs(n1 uint, n2 int) (uint, int) { 252 // amd64:"MOVQ\t[$]-1085102592571150095","MULQ",-"DIVQ" 253 // 386:"MOVL\t[$]-252645135","MULL",-"DIVL" 254 // arm64:`MOVD`,`UMULH`,-`DIV` 255 // arm:`MOVW`,`MUL`,-`.*udiv` 256 a := n1 / 17 // unsigned 257 258 // amd64:"MOVQ\t[$]-1085102592571150095","IMULQ",-"IDIVQ" 259 // 386:"MOVL\t[$]-252645135","IMULL",-"IDIVL" 260 // arm64:`SMULH`,-`DIV` 261 // arm:`MOVW`,`MUL`,-`.*udiv` 262 b := n2 / 17 // signed 263 264 return a, b 265 } 266 267 func FloatDivs(a []float32) float32 { 268 // amd64:`DIVSS\s8\([A-Z]+\),\sX[0-9]+` 269 // 386/sse2:`DIVSS\s8\([A-Z]+\),\sX[0-9]+` 270 return a[1] / a[2] 271 } 272 273 func Pow2Mods(n1 uint, n2 int) (uint, int) { 274 // 386:"ANDL\t[$]31",-"DIVL" 275 // amd64:"ANDL\t[$]31",-"DIVQ" 276 // arm:"AND\t[$]31",-".*udiv" 277 // arm64:"AND\t[$]31",-"UDIV" 278 // ppc64x:"RLDICL" 279 a := n1 % 32 // unsigned 280 281 // 386:"SHRL",-"IDIVL" 282 // amd64:"SHRQ",-"IDIVQ" 283 // arm:"SRA",-".*udiv" 284 // arm64:"ASR",-"REM" 285 // ppc64x:"SRAD" 286 b := n2 % 64 // signed 287 288 return a, b 289 } 290 291 // Check that signed divisibility checks get converted to AND on low bits 292 func Pow2DivisibleSigned(n1, n2 int) (bool, bool) { 293 // 386:"TESTL\t[$]63",-"DIVL",-"SHRL" 294 // amd64:"TESTQ\t[$]63",-"DIVQ",-"SHRQ" 295 // arm:"AND\t[$]63",-".*udiv",-"SRA" 296 // arm64:"TST\t[$]63",-"UDIV",-"ASR",-"AND" 297 // ppc64x:"RLDICL",-"SRAD" 298 a := n1%64 == 0 // signed divisible 299 300 // 386:"TESTL\t[$]63",-"DIVL",-"SHRL" 301 // amd64:"TESTQ\t[$]63",-"DIVQ",-"SHRQ" 302 // arm:"AND\t[$]63",-".*udiv",-"SRA" 303 // arm64:"TST\t[$]63",-"UDIV",-"ASR",-"AND" 304 // ppc64x:"RLDICL",-"SRAD" 305 b := n2%64 != 0 // signed indivisible 306 307 return a, b 308 } 309 310 // Check that constant modulo divs get turned into MULs 311 func ConstMods(n1 uint, n2 int) (uint, int) { 312 // amd64:"MOVQ\t[$]-1085102592571150095","MULQ",-"DIVQ" 313 // 386:"MOVL\t[$]-252645135","MULL",-"DIVL" 314 // arm64:`MOVD`,`UMULH`,-`DIV` 315 // arm:`MOVW`,`MUL`,-`.*udiv` 316 a := n1 % 17 // unsigned 317 318 // amd64:"MOVQ\t[$]-1085102592571150095","IMULQ",-"IDIVQ" 319 // 386:"MOVL\t[$]-252645135","IMULL",-"IDIVL" 320 // arm64:`SMULH`,-`DIV` 321 // arm:`MOVW`,`MUL`,-`.*udiv` 322 b := n2 % 17 // signed 323 324 return a, b 325 } 326 327 // Check that divisibility checks x%c==0 are converted to MULs and rotates 328 func DivisibleU(n uint) (bool, bool) { 329 // amd64:"MOVQ\t[$]-6148914691236517205","IMULQ","ROLQ\t[$]63",-"DIVQ" 330 // 386:"IMUL3L\t[$]-1431655765","ROLL\t[$]31",-"DIVQ" 331 // arm64:"MOVD\t[$]-6148914691236517205","MOVD\t[$]3074457345618258602","MUL","ROR",-"DIV" 332 // arm:"MUL","CMP\t[$]715827882",-".*udiv" 333 // ppc64x:"MULLD","ROTL\t[$]63" 334 even := n%6 == 0 335 336 // amd64:"MOVQ\t[$]-8737931403336103397","IMULQ",-"ROLQ",-"DIVQ" 337 // 386:"IMUL3L\t[$]678152731",-"ROLL",-"DIVQ" 338 // arm64:"MOVD\t[$]-8737931403336103397","MUL",-"ROR",-"DIV" 339 // arm:"MUL","CMP\t[$]226050910",-".*udiv" 340 // ppc64x:"MULLD",-"ROTL" 341 odd := n%19 == 0 342 343 return even, odd 344 } 345 346 func Divisible(n int) (bool, bool) { 347 // amd64:"IMULQ","ADD","ROLQ\t[$]63",-"DIVQ" 348 // 386:"IMUL3L\t[$]-1431655765","ADDL\t[$]715827882","ROLL\t[$]31",-"DIVQ" 349 // arm64:"MOVD\t[$]-6148914691236517205","MOVD\t[$]3074457345618258602","MUL","ADD\tR","ROR",-"DIV" 350 // arm:"MUL","ADD\t[$]715827882",-".*udiv" 351 // ppc64x/power8:"MULLD","ADD","ROTL\t[$]63" 352 // ppc64x/power9:"MADDLD","ROTL\t[$]63" 353 even := n%6 == 0 354 355 // amd64:"IMULQ","ADD",-"ROLQ",-"DIVQ" 356 // 386:"IMUL3L\t[$]678152731","ADDL\t[$]113025455",-"ROLL",-"DIVQ" 357 // arm64:"MUL","MOVD\t[$]485440633518672410","ADD",-"ROR",-"DIV" 358 // arm:"MUL","ADD\t[$]113025455",-".*udiv" 359 // ppc64x/power8:"MULLD","ADD",-"ROTL" 360 // ppc64x/power9:"MADDLD",-"ROTL" 361 odd := n%19 == 0 362 363 return even, odd 364 } 365 366 // Check that fix-up code is not generated for divisions where it has been proven that 367 // that the divisor is not -1 or that the dividend is > MinIntNN. 368 func NoFix64A(divr int64) (int64, int64) { 369 var d int64 = 42 370 var e int64 = 84 371 if divr > 5 { 372 d /= divr // amd64:-"JMP" 373 e %= divr // amd64:-"JMP" 374 // The following statement is to avoid conflict between the above check 375 // and the normal JMP generated at the end of the block. 376 d += e 377 } 378 return d, e 379 } 380 381 func NoFix64B(divd int64) (int64, int64) { 382 var d int64 383 var e int64 384 var divr int64 = -1 385 if divd > -9223372036854775808 { 386 d = divd / divr // amd64:-"JMP" 387 e = divd % divr // amd64:-"JMP" 388 d += e 389 } 390 return d, e 391 } 392 393 func NoFix32A(divr int32) (int32, int32) { 394 var d int32 = 42 395 var e int32 = 84 396 if divr > 5 { 397 // amd64:-"JMP" 398 // 386:-"JMP" 399 d /= divr 400 // amd64:-"JMP" 401 // 386:-"JMP" 402 e %= divr 403 d += e 404 } 405 return d, e 406 } 407 408 func NoFix32B(divd int32) (int32, int32) { 409 var d int32 410 var e int32 411 var divr int32 = -1 412 if divd > -2147483648 { 413 // amd64:-"JMP" 414 // 386:-"JMP" 415 d = divd / divr 416 // amd64:-"JMP" 417 // 386:-"JMP" 418 e = divd % divr 419 d += e 420 } 421 return d, e 422 } 423 424 func NoFix16A(divr int16) (int16, int16) { 425 var d int16 = 42 426 var e int16 = 84 427 if divr > 5 { 428 // amd64:-"JMP" 429 // 386:-"JMP" 430 d /= divr 431 // amd64:-"JMP" 432 // 386:-"JMP" 433 e %= divr 434 d += e 435 } 436 return d, e 437 } 438 439 func NoFix16B(divd int16) (int16, int16) { 440 var d int16 441 var e int16 442 var divr int16 = -1 443 if divd > -32768 { 444 // amd64:-"JMP" 445 // 386:-"JMP" 446 d = divd / divr 447 // amd64:-"JMP" 448 // 386:-"JMP" 449 e = divd % divr 450 d += e 451 } 452 return d, e 453 } 454 455 // Check that len() and cap() calls divided by powers of two are 456 // optimized into shifts and ands 457 458 func LenDiv1(a []int) int { 459 // 386:"SHRL\t[$]10" 460 // amd64:"SHRQ\t[$]10" 461 // arm64:"LSR\t[$]10",-"SDIV" 462 // arm:"SRL\t[$]10",-".*udiv" 463 // ppc64x:"SRD"\t[$]10" 464 return len(a) / 1024 465 } 466 467 func LenDiv2(s string) int { 468 // 386:"SHRL\t[$]11" 469 // amd64:"SHRQ\t[$]11" 470 // arm64:"LSR\t[$]11",-"SDIV" 471 // arm:"SRL\t[$]11",-".*udiv" 472 // ppc64x:"SRD\t[$]11" 473 return len(s) / (4097 >> 1) 474 } 475 476 func LenMod1(a []int) int { 477 // 386:"ANDL\t[$]1023" 478 // amd64:"ANDL\t[$]1023" 479 // arm64:"AND\t[$]1023",-"SDIV" 480 // arm/6:"AND",-".*udiv" 481 // arm/7:"BFC",-".*udiv",-"AND" 482 // ppc64x:"RLDICL" 483 return len(a) % 1024 484 } 485 486 func LenMod2(s string) int { 487 // 386:"ANDL\t[$]2047" 488 // amd64:"ANDL\t[$]2047" 489 // arm64:"AND\t[$]2047",-"SDIV" 490 // arm/6:"AND",-".*udiv" 491 // arm/7:"BFC",-".*udiv",-"AND" 492 // ppc64x:"RLDICL" 493 return len(s) % (4097 >> 1) 494 } 495 496 func CapDiv(a []int) int { 497 // 386:"SHRL\t[$]12" 498 // amd64:"SHRQ\t[$]12" 499 // arm64:"LSR\t[$]12",-"SDIV" 500 // arm:"SRL\t[$]12",-".*udiv" 501 // ppc64x:"SRD\t[$]12" 502 return cap(a) / ((1 << 11) + 2048) 503 } 504 505 func CapMod(a []int) int { 506 // 386:"ANDL\t[$]4095" 507 // amd64:"ANDL\t[$]4095" 508 // arm64:"AND\t[$]4095",-"SDIV" 509 // arm/6:"AND",-".*udiv" 510 // arm/7:"BFC",-".*udiv",-"AND" 511 // ppc64x:"RLDICL" 512 return cap(a) % ((1 << 11) + 2048) 513 } 514 515 func AddMul(x int) int { 516 // amd64:"LEAQ\t1" 517 return 2*x + 1 518 } 519 520 func MULA(a, b, c uint32) (uint32, uint32, uint32) { 521 // arm:`MULA`,-`MUL\s` 522 // arm64:`MADDW`,-`MULW` 523 r0 := a*b + c 524 // arm:`MULA`,-`MUL\s` 525 // arm64:`MADDW`,-`MULW` 526 r1 := c*79 + a 527 // arm:`ADD`,-`MULA`,-`MUL\s` 528 // arm64:`ADD`,-`MADD`,-`MULW` 529 // ppc64x:`ADD`,-`MULLD` 530 r2 := b*64 + c 531 return r0, r1, r2 532 } 533 534 func MULS(a, b, c uint32) (uint32, uint32, uint32) { 535 // arm/7:`MULS`,-`MUL\s` 536 // arm/6:`SUB`,`MUL\s`,-`MULS` 537 // arm64:`MSUBW`,-`MULW` 538 r0 := c - a*b 539 // arm/7:`MULS`,-`MUL\s` 540 // arm/6:`SUB`,`MUL\s`,-`MULS` 541 // arm64:`MSUBW`,-`MULW` 542 r1 := a - c*79 543 // arm/7:`SUB`,-`MULS`,-`MUL\s` 544 // arm64:`SUB`,-`MSUBW`,-`MULW` 545 // ppc64x:`SUB`,-`MULLD` 546 r2 := c - b*64 547 return r0, r1, r2 548 } 549 550 func addSpecial(a, b, c uint32) (uint32, uint32, uint32) { 551 // amd64:`INCL` 552 a++ 553 // amd64:`DECL` 554 b-- 555 // amd64:`SUBL.*-128` 556 c += 128 557 return a, b, c 558 } 559 560 // Divide -> shift rules usually require fixup for negative inputs. 561 // If the input is non-negative, make sure the fixup is eliminated. 562 func divInt(v int64) int64 { 563 if v < 0 { 564 return 0 565 } 566 // amd64:-`.*SARQ.*63,`, -".*SHRQ", ".*SARQ.*[$]9," 567 return v / 512 568 } 569 570 // The reassociate rules "x - (z + C) -> (x - z) - C" and 571 // "(z + C) -x -> C + (z - x)" can optimize the following cases. 572 func constantFold1(i0, j0, i1, j1, i2, j2, i3, j3 int) (int, int, int, int) { 573 // arm64:"SUB","ADD\t[$]2" 574 // ppc64x:"SUB","ADD\t[$]2" 575 r0 := (i0 + 3) - (j0 + 1) 576 // arm64:"SUB","SUB\t[$]4" 577 // ppc64x:"SUB","ADD\t[$]-4" 578 r1 := (i1 - 3) - (j1 + 1) 579 // arm64:"SUB","ADD\t[$]4" 580 // ppc64x:"SUB","ADD\t[$]4" 581 r2 := (i2 + 3) - (j2 - 1) 582 // arm64:"SUB","SUB\t[$]2" 583 // ppc64x:"SUB","ADD\t[$]-2" 584 r3 := (i3 - 3) - (j3 - 1) 585 return r0, r1, r2, r3 586 } 587 588 // The reassociate rules "x - (z + C) -> (x - z) - C" and 589 // "(C - z) - x -> C - (z + x)" can optimize the following cases. 590 func constantFold2(i0, j0, i1, j1 int) (int, int) { 591 // arm64:"ADD","MOVD\t[$]2","SUB" 592 // ppc64x: `SUBC\tR[0-9]+,\s[$]2,\sR` 593 r0 := (3 - i0) - (j0 + 1) 594 // arm64:"ADD","MOVD\t[$]4","SUB" 595 // ppc64x: `SUBC\tR[0-9]+,\s[$]4,\sR` 596 r1 := (3 - i1) - (j1 - 1) 597 return r0, r1 598 } 599 600 func constantFold3(i, j int) int { 601 // arm64: "MOVD\t[$]30","MUL",-"ADD",-"LSL" 602 // ppc64x:"MULLD\t[$]30","MULLD" 603 r := (5 * i) * (6 * j) 604 return r 605 } 606