Merge lp:~ams-codesourcery/gcc-linaro/widening-multiplies-4.6 into lp:gcc-linaro/4.6

Proposed by Andrew Stubbs
Status: Merged
Approved by: Richard Sandiford
Approved revision: no longer in the source branch.
Merged at revision: 106796
Proposed branch: lp:~ams-codesourcery/gcc-linaro/widening-multiplies-4.6
Merge into: lp:gcc-linaro/4.6
Diff against target: 1272 lines (+740/-140) (has conflicts)
20 files modified
ChangeLog.linaro (+129/-0)
gcc/config/arm/arm.md (+1/-1)
gcc/expr.c (+14/-15)
gcc/genopinit.c (+24/-20)
gcc/optabs.c (+78/-13)
gcc/optabs.h (+52/-0)
gcc/testsuite/gcc.target/arm/no-wmla-1.c (+11/-0)
gcc/testsuite/gcc.target/arm/wmul-10.c (+10/-0)
gcc/testsuite/gcc.target/arm/wmul-11.c (+10/-0)
gcc/testsuite/gcc.target/arm/wmul-12.c (+11/-0)
gcc/testsuite/gcc.target/arm/wmul-13.c (+10/-0)
gcc/testsuite/gcc.target/arm/wmul-5.c (+10/-0)
gcc/testsuite/gcc.target/arm/wmul-6.c (+10/-0)
gcc/testsuite/gcc.target/arm/wmul-7.c (+10/-0)
gcc/testsuite/gcc.target/arm/wmul-8.c (+10/-0)
gcc/testsuite/gcc.target/arm/wmul-9.c (+10/-0)
gcc/testsuite/gcc.target/arm/wmul-bitfield-1.c (+17/-0)
gcc/testsuite/gcc.target/arm/wmul-bitfield-2.c (+17/-0)
gcc/tree-cfg.c (+2/-2)
gcc/tree-ssa-math-opts.c (+304/-89)
Text conflict in ChangeLog.linaro
To merge this branch: bzr merge lp:~ams-codesourcery/gcc-linaro/widening-multiplies-4.6
Reviewer Review Type Date Requested Status
Richard Sandiford Approve
Michael Hope Pending
Review via email: mp+71230@code.launchpad.net

This proposal supersedes a proposal from 2011-08-05.

Description of the change

Widening multiplies optimizations.

The first commit is not approved yet, but the rest are reviewed upstream, and read to commit.

http://<email address hidden>/msg08720.html

UPDATE: Now with an extra bug-fix.

To post a comment you must log in.
Revision history for this message
Linaro Toolchain Builder (cbuild) wrote : Posted in a previous version of this proposal

cbuild has taken a snapshot of this branch at r106781 and queued it for build.

The snapshot is available at:
 http://ex.seabright.co.nz/snapshots/gcc-linaro-4.6+bzr106781~ams-codesourcery~widening-multiplies-4.6.tar.xdelta3.xz

and will be built on the following builders:
 a9-builder armv5-builder i686 x86_64

You can track the build queue at:
 http://ex.seabright.co.nz/helpers/scheduler

cbuild-snapshot: gcc-linaro-4.6+bzr106781~ams-codesourcery~widening-multiplies-4.6
cbuild-ancestor: lp:gcc-linaro/4.6+bzr106774
cbuild-state: check

Revision history for this message
Michael Hope (michaelh1) wrote : Posted in a previous version of this proposal

cbuild had trouble building this on <proposals.Build instance at 0x2b85680>.

See the *failed.txt logs under the build results at:
 http://ex.seabright.co.nz/build/gcc-linaro-4.6+bzr106781~ams-codesourcery~widening-multiplies-4.6/logs/armv7l-natty-cbuild158-ursa3-armv5r2

The test suite results were not checked.

cbuild-checked: armv7l-natty-cbuild158-ursa3-armv5r2

review: Needs Fixing
Revision history for this message
Michael Hope (michaelh1) wrote : Posted in a previous version of this proposal

cbuild had trouble building this on <proposals.Build instance at 0x2141ea8>.

See the *failed.txt logs under the build results at:
 http://ex.seabright.co.nz/build/gcc-linaro-4.6+bzr106781~ams-codesourcery~widening-multiplies-4.6/logs/armv7l-natty-cbuild158-ursa4-cortexa9r1

The test suite results were not checked.

cbuild-checked: armv7l-natty-cbuild158-ursa4-cortexa9r1

review: Needs Fixing
Revision history for this message
Michael Hope (michaelh1) wrote : Posted in a previous version of this proposal

cbuild had trouble building this on <proposals.Build instance at 0x7fe8f501a050>.

See the *failed.txt logs under the build results at:
 http://ex.seabright.co.nz/build/gcc-linaro-4.6+bzr106781~ams-codesourcery~widening-multiplies-4.6/logs/i686-natty-cbuild158-oort2-i686r1

The test suite results were not checked.

cbuild-checked: i686-natty-cbuild158-oort2-i686r1

review: Needs Fixing
Revision history for this message
Michael Hope (michaelh1) wrote : Posted in a previous version of this proposal

cbuild had trouble building this on <proposals.Build instance at 0x7fe8f5028ab8>.

See the *failed.txt logs under the build results at:
 http://ex.seabright.co.nz/build/gcc-linaro-4.6+bzr106781~ams-codesourcery~widening-multiplies-4.6/logs/x86_64-natty-cbuild158-oort1-x86_64r1

The test suite results were not checked.

cbuild-checked: x86_64-natty-cbuild158-oort1-x86_64r1

review: Needs Fixing
Revision history for this message
Linaro Toolchain Builder (cbuild) wrote : Posted in a previous version of this proposal

cbuild has taken a snapshot of this branch at r106782 and queued it for build.

The snapshot is available at:
 http://ex.seabright.co.nz/snapshots/gcc-linaro-4.6+bzr106782~ams-codesourcery~widening-multiplies-4.6.tar.xdelta3.xz

and will be built on the following builders:
 a9-builder armv5-builder i686 x86_64

You can track the build queue at:
 http://ex.seabright.co.nz/helpers/scheduler

cbuild-snapshot: gcc-linaro-4.6+bzr106782~ams-codesourcery~widening-multiplies-4.6
cbuild-ancestor: lp:gcc-linaro/4.6+bzr106774
cbuild-state: check

Revision history for this message
Michael Hope (michaelh1) wrote : Posted in a previous version of this proposal

cbuild had trouble building this on <proposals.Build instance at 0x3fec710>.

See the *failed.txt logs under the build results at:
 http://ex.seabright.co.nz/build/gcc-linaro-4.6+bzr106782~ams-codesourcery~widening-multiplies-4.6/logs/i686-natty-cbuild158-oort6-i686r1

The test suite results were not checked.

cbuild-checked: i686-natty-cbuild158-oort6-i686r1

review: Needs Fixing
Revision history for this message
Michael Hope (michaelh1) wrote : Posted in a previous version of this proposal

cbuild had trouble building this on <proposals.Build instance at 0x2b08c68>.

See the *failed.txt logs under the build results at:
 http://ex.seabright.co.nz/build/gcc-linaro-4.6+bzr106782~ams-codesourcery~widening-multiplies-4.6/logs/x86_64-natty-cbuild158-oort3-x86_64r1

The test suite results were not checked.

cbuild-checked: x86_64-natty-cbuild158-oort3-x86_64r1

review: Needs Fixing
Revision history for this message
Michael Hope (michaelh1) wrote : Posted in a previous version of this proposal

cbuild had trouble building this on armv7l-natty-cbuild158-ursa3-cortexa9r1.

See the *failed.txt logs under the build results at:
 http://ex.seabright.co.nz/build/gcc-linaro-4.6+bzr106782~ams-codesourcery~widening-multiplies-4.6/logs/armv7l-natty-cbuild158-ursa3-cortexa9r1

The test suite results were not checked.

cbuild-checked: armv7l-natty-cbuild158-ursa3-cortexa9r1

review: Needs Fixing
Revision history for this message
Michael Hope (michaelh1) wrote : Posted in a previous version of this proposal

cbuild had trouble building this on armv7l-natty-cbuild158-ursa1-armv5r2.

See the *failed.txt logs under the build results at:
 http://ex.seabright.co.nz/build/gcc-linaro-4.6+bzr106782~ams-codesourcery~widening-multiplies-4.6/logs/armv7l-natty-cbuild158-ursa1-armv5r2

The test suite results were not checked.

cbuild-checked: armv7l-natty-cbuild158-ursa1-armv5r2

review: Needs Fixing
Revision history for this message
Linaro Toolchain Builder (cbuild) wrote : Posted in a previous version of this proposal

cbuild has taken a snapshot of this branch at r106783 and queued it for build.

The snapshot is available at:
 http://ex.seabright.co.nz/snapshots/gcc-linaro-4.6+bzr106783~ams-codesourcery~widening-multiplies-4.6.tar.xdelta3.xz

and will be built on the following builders:
 a9-builder armv5-builder i686 x86_64

You can track the build queue at:
 http://ex.seabright.co.nz/helpers/scheduler

cbuild-snapshot: gcc-linaro-4.6+bzr106783~ams-codesourcery~widening-multiplies-4.6
cbuild-ancestor: lp:gcc-linaro/4.6+bzr106774
cbuild-state: check

Revision history for this message
Michael Hope (michaelh1) wrote : Posted in a previous version of this proposal

cbuild had trouble building this on x86_64-natty-cbuild159-oort1-x86_64r1.

See the *failed.txt logs under the build results at:
 http://ex.seabright.co.nz/build/gcc-linaro-4.6+bzr106783~ams-codesourcery~widening-multiplies-4.6/logs/x86_64-natty-cbuild159-oort1-x86_64r1

The test suite results were not checked.

cbuild-checked: x86_64-natty-cbuild159-oort1-x86_64r1

review: Needs Fixing
Revision history for this message
Michael Hope (michaelh1) wrote : Posted in a previous version of this proposal

cbuild had trouble building this on i686-natty-cbuild159-oort6-i686r1.

See the *failed.txt logs under the build results at:
 http://ex.seabright.co.nz/build/gcc-linaro-4.6+bzr106783~ams-codesourcery~widening-multiplies-4.6/logs/i686-natty-cbuild159-oort6-i686r1

The test suite results were not checked.

cbuild-checked: i686-natty-cbuild159-oort6-i686r1

review: Needs Fixing
Revision history for this message
Michael Hope (michaelh1) wrote : Posted in a previous version of this proposal

cbuild had trouble building this on armv7l-natty-cbuild159-ursa2-cortexa9r1.

See the *failed.txt logs under the build results at:
 http://ex.seabright.co.nz/build/gcc-linaro-4.6+bzr106783~ams-codesourcery~widening-multiplies-4.6/logs/armv7l-natty-cbuild159-ursa2-cortexa9r1

The test suite results were not checked.

cbuild-checked: armv7l-natty-cbuild159-ursa2-cortexa9r1

review: Needs Fixing
Revision history for this message
Linaro Toolchain Builder (cbuild) wrote : Posted in a previous version of this proposal

cbuild has taken a snapshot of this branch at r106784 and queued it for build.

The snapshot is available at:
 http://ex.seabright.co.nz/snapshots/gcc-linaro-4.6+bzr106784~ams-codesourcery~widening-multiplies-4.6.tar.xdelta3.xz

and will be built on the following builders:
 a9-builder armv5-builder i686 x86_64

You can track the build queue at:
 http://ex.seabright.co.nz/helpers/scheduler

cbuild-snapshot: gcc-linaro-4.6+bzr106784~ams-codesourcery~widening-multiplies-4.6
cbuild-ancestor: lp:gcc-linaro/4.6+bzr106774
cbuild-state: check

Revision history for this message
Michael Hope (michaelh1) wrote : Posted in a previous version of this proposal
Download full text (4.0 KiB)

cbuild successfully built this on armv7l-natty-cbuild159-ursa2-cortexa9r1.

The build results are available at:
 http://ex.seabright.co.nz/build/gcc-linaro-4.6+bzr106784~ams-codesourcery~widening-multiplies-4.6/logs/armv7l-natty-cbuild159-ursa2-cortexa9r1

-PASS: gcc.c-torture/execute/961213-1.c compilation, -O3 -fomit-frame-pointer
-PASS: gcc.c-torture/execute/961213-1.c compilation, -O3 -fomit-frame-pointer -funroll-all-loops -finline-functions
-PASS: gcc.c-torture/execute/961213-1.c compilation, -O3 -fomit-frame-pointer -funroll-loops
-PASS: gcc.c-torture/execute/961213-1.c compilation, -O3 -g
+FAIL: gcc.c-torture/execute/961213-1.c compilation, -O3 -fomit-frame-pointer -funroll-all-loops -finline-functions (internal compiler error)
+FAIL: gcc.c-torture/execute/961213-1.c compilation, -O3 -fomit-frame-pointer -funroll-loops (internal compiler error)
+FAIL: gcc.c-torture/execute/961213-1.c compilation, -O3 -fomit-frame-pointer (internal compiler error)
+FAIL: gcc.c-torture/execute/961213-1.c compilation, -O3 -g (internal compiler error)
-PASS: gcc.c-torture/execute/961213-1.c execution, -O3 -fomit-frame-pointer
-PASS: gcc.c-torture/execute/961213-1.c execution, -O3 -fomit-frame-pointer -funroll-all-loops -finline-functions
-PASS: gcc.c-torture/execute/961213-1.c execution, -O3 -fomit-frame-pointer -funroll-loops
-PASS: gcc.c-torture/execute/961213-1.c execution, -O3 -g
+UNRESOLVED: gcc.c-torture/execute/961213-1.c execution, -O3 -fomit-frame-pointer
+UNRESOLVED: gcc.c-torture/execute/961213-1.c execution, -O3 -fomit-frame-pointer -funroll-all-loops -finline-functions
+UNRESOLVED: gcc.c-torture/execute/961213-1.c execution, -O3 -fomit-frame-pointer -funroll-loops
+UNRESOLVED: gcc.c-torture/execute/961213-1.c execution, -O3 -g
-PASS: gcc.dg/pr46499-1.c execution test
-PASS: gcc.dg/pr46499-1.c (test for excess errors)
+UNRESOLVED: gcc.dg/pr46499-1.c compilation failed to produce executable
+FAIL: gcc.dg/pr46499-1.c (test for excess errors)
+PASS: gcc.target/arm/no-wmla-1.c scan-assembler mul
+PASS: gcc.target/arm/no-wmla-1.c (test for excess errors)
+PASS: gcc.target/arm/wmul-10.c scan-assembler umlal
+PASS: gcc.target/arm/wmul-10.c (test for excess errors)
+PASS: gcc.target/arm/wmul-11.c scan-assembler smull
+PASS: gcc.target/arm/wmul-11.c (test for excess errors)
+PASS: gcc.target/arm/wmul-12.c scan-assembler smlal
+PASS: gcc.target/arm/wmul-12.c (test for excess errors)
+PASS: gcc.target/arm/wmul-13.c scan-assembler smlal
+PASS: gcc.target/arm/wmul-13.c (test for excess errors)
+PASS: gcc.target/arm/wmul-5.c scan-assembler umlal
+PASS: gcc.target/arm/wmul-5.c (test for excess errors)
+PASS: gcc.target/arm/wmul-6.c scan-assembler smlal
+PASS: gcc.target/arm/wmul-6.c (test for excess errors)
+PASS: gcc.target/arm/wmul-7.c scan-assembler umlal
+PASS: gcc.target/arm/wmul-7.c (test for excess errors)
+PASS: gcc.target/arm/wmul-8.c scan-assembler smlal
+PASS: gcc.target/arm/wmul-8.c (test for excess errors)
+PASS: gcc.target/arm/wmul-9.c scan-assembler smlalbb
+PASS: gcc.target/arm/wmul-9.c (test for excess errors)
+PASS: gcc.target/arm/wmul-bitfield-1.c scan-assembler smlalbb
+PAS...

Read more...

Revision history for this message
Michael Hope (michaelh1) wrote : Posted in a previous version of this proposal

cbuild had trouble building this on i686-natty-cbuild159-oort8-i686r1.

See the *failed.txt logs under the build results at:
 http://ex.seabright.co.nz/build/gcc-linaro-4.6+bzr106784~ams-codesourcery~widening-multiplies-4.6/logs/i686-natty-cbuild159-oort8-i686r1

The test suite results were not checked.

cbuild-checked: i686-natty-cbuild159-oort8-i686r1

review: Needs Fixing
Revision history for this message
Michael Hope (michaelh1) wrote : Posted in a previous version of this proposal

cbuild had trouble building this on x86_64-natty-cbuild159-oort3-x86_64r1.

See the *failed.txt logs under the build results at:
 http://ex.seabright.co.nz/build/gcc-linaro-4.6+bzr106784~ams-codesourcery~widening-multiplies-4.6/logs/x86_64-natty-cbuild159-oort3-x86_64r1

The test suite results were not checked.

cbuild-checked: x86_64-natty-cbuild159-oort3-x86_64r1

review: Needs Fixing
Revision history for this message
Michael Hope (michaelh1) wrote : Posted in a previous version of this proposal

cbuild had trouble building this on x86_64-natty-cbuild159-oort3-x86_64r1.

See the *failed.txt logs under the build results at:
 http://ex.seabright.co.nz/build/gcc-linaro-4.6+bzr106784~ams-codesourcery~widening-multiplies-4.6/logs/x86_64-natty-cbuild159-oort3-x86_64r1

The test suite results were not checked.

cbuild-checked: x86_64-natty-cbuild159-oort3-x86_64r1

review: Needs Fixing
Revision history for this message
Linaro Toolchain Builder (cbuild) wrote : Posted in a previous version of this proposal

cbuild has taken a snapshot of this branch at r106785 and queued it for build.

The snapshot is available at:
 http://ex.seabright.co.nz/snapshots/gcc-linaro-4.6+bzr106785~ams-codesourcery~widening-multiplies-4.6.tar.xdelta3.xz

and will be built on the following builders:
 a9-builder armv5-builder i686 x86_64

You can track the build queue at:
 http://ex.seabright.co.nz/helpers/scheduler

cbuild-snapshot: gcc-linaro-4.6+bzr106785~ams-codesourcery~widening-multiplies-4.6
cbuild-ancestor: lp:gcc-linaro/4.6+bzr106774
cbuild-state: check

Revision history for this message
Michael Hope (michaelh1) wrote : Posted in a previous version of this proposal
Download full text (4.2 KiB)

cbuild successfully built this on armv7l-natty-cbuild159-ursa3-armv5r2.

The build results are available at:
 http://ex.seabright.co.nz/build/gcc-linaro-4.6+bzr106785~ams-codesourcery~widening-multiplies-4.6/logs/armv7l-natty-cbuild159-ursa3-armv5r2

-PASS: gcc.c-torture/execute/961213-1.c compilation, -O3 -fomit-frame-pointer
-PASS: gcc.c-torture/execute/961213-1.c compilation, -O3 -fomit-frame-pointer -funroll-all-loops -finline-functions
-PASS: gcc.c-torture/execute/961213-1.c compilation, -O3 -fomit-frame-pointer -funroll-loops
-PASS: gcc.c-torture/execute/961213-1.c compilation, -O3 -g
+FAIL: gcc.c-torture/execute/961213-1.c compilation, -O3 -fomit-frame-pointer (internal compiler error)
+FAIL: gcc.c-torture/execute/961213-1.c compilation, -O3 -fomit-frame-pointer -funroll-all-loops -finline-functions (internal compiler error)
+FAIL: gcc.c-torture/execute/961213-1.c compilation, -O3 -fomit-frame-pointer -funroll-loops (internal compiler error)
+FAIL: gcc.c-torture/execute/961213-1.c compilation, -O3 -g (internal compiler error)
-PASS: gcc.c-torture/execute/961213-1.c execution, -O3 -fomit-frame-pointer
-PASS: gcc.c-torture/execute/961213-1.c execution, -O3 -fomit-frame-pointer -funroll-all-loops -finline-functions
-PASS: gcc.c-torture/execute/961213-1.c execution, -O3 -fomit-frame-pointer -funroll-loops
-PASS: gcc.c-torture/execute/961213-1.c execution, -O3 -g
+UNRESOLVED: gcc.c-torture/execute/961213-1.c execution, -O3 -fomit-frame-pointer
+UNRESOLVED: gcc.c-torture/execute/961213-1.c execution, -O3 -fomit-frame-pointer -funroll-all-loops -finline-functions
+UNRESOLVED: gcc.c-torture/execute/961213-1.c execution, -O3 -fomit-frame-pointer -funroll-loops
+UNRESOLVED: gcc.c-torture/execute/961213-1.c execution, -O3 -g
+PASS: gcc.target/arm/no-wmla-1.c (test for excess errors)
+PASS: gcc.target/arm/no-wmla-1.c scan-assembler mul
+PASS: gcc.target/arm/wmul-10.c (test for excess errors)
+PASS: gcc.target/arm/wmul-10.c scan-assembler umlal
+PASS: gcc.target/arm/wmul-11.c (test for excess errors)
+PASS: gcc.target/arm/wmul-11.c scan-assembler smull
+PASS: gcc.target/arm/wmul-12.c (test for excess errors)
+PASS: gcc.target/arm/wmul-12.c scan-assembler smlal
+PASS: gcc.target/arm/wmul-13.c (test for excess errors)
+PASS: gcc.target/arm/wmul-13.c scan-assembler smlal
+PASS: gcc.target/arm/wmul-5.c (test for excess errors)
+PASS: gcc.target/arm/wmul-5.c scan-assembler umlal
+PASS: gcc.target/arm/wmul-6.c (test for excess errors)
+PASS: gcc.target/arm/wmul-6.c scan-assembler smlal
+PASS: gcc.target/arm/wmul-7.c (test for excess errors)
+PASS: gcc.target/arm/wmul-7.c scan-assembler umlal
+PASS: gcc.target/arm/wmul-8.c (test for excess errors)
+PASS: gcc.target/arm/wmul-8.c scan-assembler smlal
+PASS: gcc.target/arm/wmul-9.c (test for excess errors)
+PASS: gcc.target/arm/wmul-9.c scan-assembler smlalbb
+PASS: gcc.target/arm/wmul-bitfield-1.c (test for excess errors)
+PASS: gcc.target/arm/wmul-bitfield-1.c scan-assembler smlalbb
+PASS: gcc.target/arm/wmul-bitfield-2.c (test for excess errors)
+PASS: gcc.target/arm/wmul-bitfield-2.c scan-assembler smlalbb
-PASS: gfortran.dg/g77/f90-intrins...

Read more...

Revision history for this message
Michael Hope (michaelh1) wrote : Posted in a previous version of this proposal
Download full text (4.2 KiB)

cbuild successfully built this on armv7l-natty-cbuild159-ursa4-cortexa9r1.

The build results are available at:
 http://ex.seabright.co.nz/build/gcc-linaro-4.6+bzr106785~ams-codesourcery~widening-multiplies-4.6/logs/armv7l-natty-cbuild159-ursa4-cortexa9r1

-PASS: gcc.c-torture/execute/961213-1.c compilation, -O3 -fomit-frame-pointer
-PASS: gcc.c-torture/execute/961213-1.c compilation, -O3 -fomit-frame-pointer -funroll-all-loops -finline-functions
-PASS: gcc.c-torture/execute/961213-1.c compilation, -O3 -fomit-frame-pointer -funroll-loops
-PASS: gcc.c-torture/execute/961213-1.c compilation, -O3 -g
+FAIL: gcc.c-torture/execute/961213-1.c compilation, -O3 -fomit-frame-pointer (internal compiler error)
+FAIL: gcc.c-torture/execute/961213-1.c compilation, -O3 -fomit-frame-pointer -funroll-all-loops -finline-functions (internal compiler error)
+FAIL: gcc.c-torture/execute/961213-1.c compilation, -O3 -fomit-frame-pointer -funroll-loops (internal compiler error)
+FAIL: gcc.c-torture/execute/961213-1.c compilation, -O3 -g (internal compiler error)
-PASS: gcc.c-torture/execute/961213-1.c execution, -O3 -fomit-frame-pointer
-PASS: gcc.c-torture/execute/961213-1.c execution, -O3 -fomit-frame-pointer -funroll-all-loops -finline-functions
-PASS: gcc.c-torture/execute/961213-1.c execution, -O3 -fomit-frame-pointer -funroll-loops
-PASS: gcc.c-torture/execute/961213-1.c execution, -O3 -g
+UNRESOLVED: gcc.c-torture/execute/961213-1.c execution, -O3 -fomit-frame-pointer
+UNRESOLVED: gcc.c-torture/execute/961213-1.c execution, -O3 -fomit-frame-pointer -funroll-all-loops -finline-functions
+UNRESOLVED: gcc.c-torture/execute/961213-1.c execution, -O3 -fomit-frame-pointer -funroll-loops
+UNRESOLVED: gcc.c-torture/execute/961213-1.c execution, -O3 -g
+PASS: gcc.target/arm/no-wmla-1.c (test for excess errors)
+PASS: gcc.target/arm/no-wmla-1.c scan-assembler mul
+PASS: gcc.target/arm/wmul-10.c (test for excess errors)
+PASS: gcc.target/arm/wmul-10.c scan-assembler umlal
+PASS: gcc.target/arm/wmul-11.c (test for excess errors)
+PASS: gcc.target/arm/wmul-11.c scan-assembler smull
+PASS: gcc.target/arm/wmul-12.c (test for excess errors)
+PASS: gcc.target/arm/wmul-12.c scan-assembler smlal
+PASS: gcc.target/arm/wmul-13.c (test for excess errors)
+PASS: gcc.target/arm/wmul-13.c scan-assembler smlal
+PASS: gcc.target/arm/wmul-5.c (test for excess errors)
+PASS: gcc.target/arm/wmul-5.c scan-assembler umlal
+PASS: gcc.target/arm/wmul-6.c (test for excess errors)
+PASS: gcc.target/arm/wmul-6.c scan-assembler smlal
+PASS: gcc.target/arm/wmul-7.c (test for excess errors)
+PASS: gcc.target/arm/wmul-7.c scan-assembler umlal
+PASS: gcc.target/arm/wmul-8.c (test for excess errors)
+PASS: gcc.target/arm/wmul-8.c scan-assembler smlal
+PASS: gcc.target/arm/wmul-9.c (test for excess errors)
+PASS: gcc.target/arm/wmul-9.c scan-assembler smlalbb
+PASS: gcc.target/arm/wmul-bitfield-1.c (test for excess errors)
+PASS: gcc.target/arm/wmul-bitfield-1.c scan-assembler smlalbb
+PASS: gcc.target/arm/wmul-bitfield-2.c (test for excess errors)
+PASS: gcc.target/arm/wmul-bitfield-2.c scan-assembler smlalbb
-PASS: gfortran.dg/g77/f90-i...

Read more...

Revision history for this message
Michael Hope (michaelh1) wrote : Posted in a previous version of this proposal

cbuild successfully built this on i686-natty-cbuild159-oort6-i686r1.

The build results are available at:
 http://ex.seabright.co.nz/build/gcc-linaro-4.6+bzr106785~ams-codesourcery~widening-multiplies-4.6/logs/i686-natty-cbuild159-oort6-i686r1

-PASS: gfortran.dg/integer_exponentiation_2.f90 -O2 (test for excess errors)
-PASS: gfortran.dg/integer_exponentiation_2.f90 -O2 execution test
+FAIL: gfortran.dg/integer_exponentiation_2.f90 -O2 (internal compiler error)
+FAIL: gfortran.dg/integer_exponentiation_2.f90 -O2 (test for excess errors)
+UNRESOLVED: gfortran.dg/integer_exponentiation_2.f90 -O2 compilation failed to produce executable
-PASS: gfortran.dg/integer_exponentiation_2.f90 -O3 -fomit-frame-pointer (test for excess errors)
-PASS: gfortran.dg/integer_exponentiation_2.f90 -O3 -fomit-frame-pointer execution test
+FAIL: gfortran.dg/integer_exponentiation_2.f90 -O3 -fomit-frame-pointer (internal compiler error)
+FAIL: gfortran.dg/integer_exponentiation_2.f90 -O3 -fomit-frame-pointer (test for excess errors)
+UNRESOLVED: gfortran.dg/integer_exponentiation_2.f90 -O3 -fomit-frame-pointer compilation failed to produce executable
-PASS: gfortran.dg/integer_exponentiation_2.f90 -O3 -fomit-frame-pointer -funroll-all-loops -finline-functions (test for excess errors)
-PASS: gfortran.dg/integer_exponentiation_2.f90 -O3 -fomit-frame-pointer -funroll-all-loops -finline-functions execution test
+FAIL: gfortran.dg/integer_exponentiation_2.f90 -O3 -fomit-frame-pointer -funroll-all-loops -finline-functions (internal compiler error)
+FAIL: gfortran.dg/integer_exponentiation_2.f90 -O3 -fomit-frame-pointer -funroll-all-loops -finline-functions (test for excess errors)
+UNRESOLVED: gfortran.dg/integer_exponentiation_2.f90 -O3 -fomit-frame-pointer -funroll-all-loops -finline-functions compilation failed to produce executable
-PASS: gfortran.dg/integer_exponentiation_2.f90 -O3 -fomit-frame-pointer -funroll-loops (test for excess errors)
-PASS: gfortran.dg/integer_exponentiation_2.f90 -O3 -fomit-frame-pointer -funroll-loops execution test
+FAIL: gfortran.dg/integer_exponentiation_2.f90 -O3 -fomit-frame-pointer -funroll-loops (internal compiler error)
+FAIL: gfortran.dg/integer_exponentiation_2.f90 -O3 -fomit-frame-pointer -funroll-loops (test for excess errors)
+UNRESOLVED: gfortran.dg/integer_exponentiation_2.f90 -O3 -fomit-frame-pointer -funroll-loops compilation failed to produce executable
-PASS: gfortran.dg/integer_exponentiation_2.f90 -O3 -g (test for excess errors)
-PASS: gfortran.dg/integer_exponentiation_2.f90 -O3 -g execution test
+FAIL: gfortran.dg/integer_exponentiation_2.f90 -O3 -g (internal compiler error)
+FAIL: gfortran.dg/integer_exponentiation_2.f90 -O3 -g (test for excess errors)
+UNRESOLVED: gfortran.dg/integer_exponentiation_2.f90 -O3 -g compilation failed to produce executable

The full testsuite results are at:
 http://ex.seabright.co.nz/build/gcc-linaro-4.6+bzr106785~ams-codesourcery~widening-multiplies-4.6/logs/i686-natty-cbuild159-oort6-i686r1/gcc-testsuite.txt

cbuild-checked: i686-natty-cbuild159-oort6-i686r1

Revision history for this message
Michael Hope (michaelh1) wrote : Posted in a previous version of this proposal

cbuild successfully built this on x86_64-natty-cbuild159-oort3-x86_64r1.

The build results are available at:
 http://ex.seabright.co.nz/build/gcc-linaro-4.6+bzr106785~ams-codesourcery~widening-multiplies-4.6/logs/x86_64-natty-cbuild159-oort3-x86_64r1

The testsuite results are the same as the branch point lp:gcc-linaro/4.6+bzr106774

The full testsuite results are at:
 http://ex.seabright.co.nz/build/gcc-linaro-4.6+bzr106785~ams-codesourcery~widening-multiplies-4.6/logs/x86_64-natty-cbuild159-oort3-x86_64r1/gcc-testsuite.txt

cbuild-checked: x86_64-natty-cbuild159-oort3-x86_64r1

Revision history for this message
Michael Hope (michaelh1) wrote : Posted in a previous version of this proposal

Note that the tests pass on a 64 bit host but fail on all 32 bit hosts.

Revision history for this message
Linaro Toolchain Builder (cbuild) wrote :

cbuild has taken a snapshot of this branch at r106787 and queued it for build.

The snapshot is available at:
 http://ex.seabright.co.nz/snapshots/gcc-linaro-4.6+bzr106787~ams-codesourcery~widening-multiplies-4.6.tar.xdelta3.xz

and will be built on the following builders:
 a9-builder armv5-builder i686 x86_64

You can track the build queue at:
 http://ex.seabright.co.nz/helpers/scheduler

cbuild-snapshot: gcc-linaro-4.6+bzr106787~ams-codesourcery~widening-multiplies-4.6
cbuild-ancestor: lp:gcc-linaro/4.6+bzr106774
cbuild-state: check

Revision history for this message
Michael Hope (michaelh1) wrote :

cbuild successfully built this on x86_64-natty-cbuild159-oort1-x86_64r1.

The build results are available at:
 http://ex.seabright.co.nz/build/gcc-linaro-4.6+bzr106787~ams-codesourcery~widening-multiplies-4.6/logs/x86_64-natty-cbuild159-oort1-x86_64r1

The testsuite results are the same as the branch point lp:gcc-linaro/4.6+bzr106774

The full testsuite results are at:
 http://ex.seabright.co.nz/build/gcc-linaro-4.6+bzr106787~ams-codesourcery~widening-multiplies-4.6/logs/x86_64-natty-cbuild159-oort1-x86_64r1/gcc-testsuite.txt

cbuild-checked: x86_64-natty-cbuild159-oort1-x86_64r1

Revision history for this message
Michael Hope (michaelh1) wrote :

cbuild successfully built this on i686-natty-cbuild159-oort2-i686r1.

The build results are available at:
 http://ex.seabright.co.nz/build/gcc-linaro-4.6+bzr106787~ams-codesourcery~widening-multiplies-4.6/logs/i686-natty-cbuild159-oort2-i686r1

The testsuite results are the same as the branch point lp:gcc-linaro/4.6+bzr106774

The full testsuite results are at:
 http://ex.seabright.co.nz/build/gcc-linaro-4.6+bzr106787~ams-codesourcery~widening-multiplies-4.6/logs/i686-natty-cbuild159-oort2-i686r1/gcc-testsuite.txt

cbuild-checked: i686-natty-cbuild159-oort2-i686r1

Revision history for this message
Michael Hope (michaelh1) wrote :

cbuild successfully built this on armv7l-natty-cbuild159-ursa2-cortexa9r1.

The build results are available at:
 http://ex.seabright.co.nz/build/gcc-linaro-4.6+bzr106787~ams-codesourcery~widening-multiplies-4.6/logs/armv7l-natty-cbuild159-ursa2-cortexa9r1

+PASS: gcc.target/arm/no-wmla-1.c (test for excess errors)
+PASS: gcc.target/arm/no-wmla-1.c scan-assembler mul
+PASS: gcc.target/arm/wmul-10.c (test for excess errors)
+PASS: gcc.target/arm/wmul-10.c scan-assembler umlal
+PASS: gcc.target/arm/wmul-11.c (test for excess errors)
+PASS: gcc.target/arm/wmul-11.c scan-assembler smull
+PASS: gcc.target/arm/wmul-12.c (test for excess errors)
+PASS: gcc.target/arm/wmul-12.c scan-assembler smlal
+PASS: gcc.target/arm/wmul-13.c (test for excess errors)
+PASS: gcc.target/arm/wmul-13.c scan-assembler smlal
+PASS: gcc.target/arm/wmul-5.c (test for excess errors)
+PASS: gcc.target/arm/wmul-5.c scan-assembler umlal
+PASS: gcc.target/arm/wmul-6.c (test for excess errors)
+PASS: gcc.target/arm/wmul-6.c scan-assembler smlal
+PASS: gcc.target/arm/wmul-7.c (test for excess errors)
+PASS: gcc.target/arm/wmul-7.c scan-assembler umlal
+PASS: gcc.target/arm/wmul-8.c (test for excess errors)
+PASS: gcc.target/arm/wmul-8.c scan-assembler smlal
+PASS: gcc.target/arm/wmul-9.c (test for excess errors)
+PASS: gcc.target/arm/wmul-9.c scan-assembler smlalbb
+PASS: gcc.target/arm/wmul-bitfield-1.c (test for excess errors)
+PASS: gcc.target/arm/wmul-bitfield-1.c scan-assembler smlalbb
+PASS: gcc.target/arm/wmul-bitfield-2.c (test for excess errors)
+PASS: gcc.target/arm/wmul-bitfield-2.c scan-assembler smlalbb

The full testsuite results are at:
 http://ex.seabright.co.nz/build/gcc-linaro-4.6+bzr106787~ams-codesourcery~widening-multiplies-4.6/logs/armv7l-natty-cbuild159-ursa2-cortexa9r1/gcc-testsuite.txt

cbuild-checked: armv7l-natty-cbuild159-ursa2-cortexa9r1

Revision history for this message
Michael Hope (michaelh1) wrote :

cbuild successfully built this on armv7l-natty-cbuild161-ursa4-armv5r2.

The build results are available at:
 http://ex.seabright.co.nz/build/gcc-linaro-4.6+bzr106787~ams-codesourcery~widening-multiplies-4.6/logs/armv7l-natty-cbuild161-ursa4-armv5r2

+PASS: gcc.target/arm/no-wmla-1.c (test for excess errors)
+PASS: gcc.target/arm/no-wmla-1.c scan-assembler mul
+PASS: gcc.target/arm/wmul-10.c (test for excess errors)
+PASS: gcc.target/arm/wmul-10.c scan-assembler umlal
+PASS: gcc.target/arm/wmul-11.c (test for excess errors)
+PASS: gcc.target/arm/wmul-11.c scan-assembler smull
+PASS: gcc.target/arm/wmul-12.c (test for excess errors)
+PASS: gcc.target/arm/wmul-12.c scan-assembler smlal
+PASS: gcc.target/arm/wmul-13.c (test for excess errors)
+PASS: gcc.target/arm/wmul-13.c scan-assembler smlal
+PASS: gcc.target/arm/wmul-5.c (test for excess errors)
+PASS: gcc.target/arm/wmul-5.c scan-assembler umlal
+PASS: gcc.target/arm/wmul-6.c (test for excess errors)
+PASS: gcc.target/arm/wmul-6.c scan-assembler smlal
+PASS: gcc.target/arm/wmul-7.c (test for excess errors)
+PASS: gcc.target/arm/wmul-7.c scan-assembler umlal
+PASS: gcc.target/arm/wmul-8.c (test for excess errors)
+PASS: gcc.target/arm/wmul-8.c scan-assembler smlal
+PASS: gcc.target/arm/wmul-9.c (test for excess errors)
+PASS: gcc.target/arm/wmul-9.c scan-assembler smlalbb
+PASS: gcc.target/arm/wmul-bitfield-1.c (test for excess errors)
+PASS: gcc.target/arm/wmul-bitfield-1.c scan-assembler smlalbb
+PASS: gcc.target/arm/wmul-bitfield-2.c (test for excess errors)
+PASS: gcc.target/arm/wmul-bitfield-2.c scan-assembler smlalbb

The full testsuite results are at:
 http://ex.seabright.co.nz/build/gcc-linaro-4.6+bzr106787~ams-codesourcery~widening-multiplies-4.6/logs/armv7l-natty-cbuild161-ursa4-armv5r2/gcc-testsuite.txt

cbuild-checked: armv7l-natty-cbuild161-ursa4-armv5r2

Revision history for this message
Ramana Radhakrishnan (ramana) wrote :

Could you point me at the one set of patches that were finally accepted upstream ?

Also, is that one extra bug fix that you say at the top in FSF trunk upstream ?

Ramana

Revision history for this message
Andrew Stubbs (ams-codesourcery) wrote :

The patches are not yet committed upstream. The accepted versions of the patches are in the thread on the gcc-patches@ list, but I have not yet posted the bug-fixed versions.

Here are the originals:
http://gcc.gnu.org/ml/gcc-patches/2011-07/msg01969.html
http://gcc.gnu.org/ml/gcc-patches/2011-07/msg01150.html
http://gcc.gnu.org/ml/gcc-patches/2011-07/msg00825.html
http://gcc.gnu.org/ml/gcc-patches/2011-07/msg01153.html
http://gcc.gnu.org/ml/gcc-patches/2011-07/msg01155.html
http://gcc.gnu.org/ml/gcc-patches/2011-07/msg01157.html
http://gcc.gnu.org/ml/gcc-patches/2011-07/msg01160.html
http://gcc.gnu.org/ml/gcc-patches/2011-07/msg01757.html
http://gcc.gnu.org/ml/gcc-patches/2011-07/msg01972.html

I do not expect them to require further approval. I plan to do some tests on the 4.7 baseline, and then commit the patches and post the new versions with updated context and bug fixes, where they have changed.

Revision history for this message
Ramana Radhakrishnan (ramana) wrote :

I had a quick look through them - the patches that have been committed upstream have been committed slightly different to the revisions here which makes a complete review a bit harder. Also given that there is a bit of churn because of backport conflicts doing a full review is harder in this case.

The testresults look OK. Given I'm not on review duty this week I don't have more time to spend on this.

Ramana

Revision history for this message
Richard Sandiford (rsandifo) wrote :

OK.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'ChangeLog.linaro'
--- ChangeLog.linaro 2011-08-10 23:03:03 +0000
+++ ChangeLog.linaro 2011-08-11 16:16:07 +0000
@@ -1,3 +1,4 @@
1<<<<<<< TREE
12011-08-11 Ramana Radhakrishnan <ramana.radhakrishnan@linaro.org>22011-08-11 Ramana Radhakrishnan <ramana.radhakrishnan@linaro.org>
23
3 gcc/4 gcc/
@@ -185,6 +186,134 @@
185186
186 * gcc.c-torture/compile/20110401-1.c: New test.187 * gcc.c-torture/compile/20110401-1.c: New test.
187188
189=======
1902011-08-05 Andrew Stubbs <ams@codesourcery.com>
191
192 Backport from patches proposed for 4.7:
193
194 2011-07-22 Andrew Stubbs <ams@codesourcery.com>
195
196 gcc/
197 * tree-ssa-math-opts.c (is_widening_mult_rhs_p): Handle constants
198 beyond conversions.
199 (convert_mult_to_widen): Convert constant inputs to the right type.
200 (convert_plusminus_to_widen): Don't automatically reject inputs that
201 are not an SSA_NAME.
202 Convert constant inputs to the right type.
203
204 gcc/testsuite/
205 * gcc.target/arm/wmul-11.c: New file.
206 * gcc.target/arm/wmul-12.c: New file.
207 * gcc.target/arm/wmul-13.c: New file.
208
209 2011-07-21 Andrew Stubbs <ams@codesourcery.com>
210
211 gcc/
212 * tree-ssa-math-opts.c (convert_plusminus_to_widen): Convert add_rhs
213 to the correct type.
214
215 gcc/testsuite/
216 * gcc.target/arm/wmul-10.c: New file.
217
218 2011-06-24 Andrew Stubbs <ams@codesourcery.com>
219
220 gcc/
221 * tree-ssa-math-opts.c (convert_mult_to_widen): Better handle
222 unsigned inputs of different modes.
223 (convert_plusminus_to_widen): Likewise.
224
225 gcc/testsuite/
226 * gcc.target/arm/wmul-9.c: New file.
227 * gcc.target/arm/wmul-bitfield-2.c: New file.
228
229 2011-07-14 Andrew Stubbs <ams@codesourcery.com>
230
231 gcc/
232 * tree-ssa-math-opts.c (is_widening_mult_rhs_p): Add new argument
233 'type'.
234 Use 'type' from caller, not inferred from 'rhs'.
235 Don't reject non-conversion statements. Do return lhs in this case.
236 (is_widening_mult_p): Add new argument 'type'.
237 Use 'type' from caller, not inferred from 'stmt'.
238 Pass type to is_widening_mult_rhs_p.
239 (convert_mult_to_widen): Pass type to is_widening_mult_p.
240 (convert_plusminus_to_widen): Likewise.
241
242 gcc/testsuite/
243 * gcc.target/arm/wmul-8.c: New file.
244
245 2011-07-14 Andrew Stubbs <ams@codesourcery.com>
246
247 gcc/
248 * tree-ssa-math-opts.c (is_widening_mult_p): Remove FIXME.
249 Ensure the the larger type is the first operand.
250
251 gcc/testsuite/
252 * gcc.target/arm/wmul-7.c: New file.
253
254 2011-07-14 Andrew Stubbs <ams@codesourcery.com>
255
256 gcc/
257 * tree-ssa-math-opts.c (convert_mult_to_widen): Convert
258 unsupported unsigned multiplies to signed.
259 (convert_plusminus_to_widen): Likewise.
260
261 gcc/testsuite/
262 * gcc.target/arm/wmul-6.c: New file.
263
264 2011-07-14 Andrew Stubbs <ams@codesourcery.com>
265
266 gcc/
267 * tree-ssa-math-opts.c (convert_plusminus_to_widen): Permit a single
268 conversion statement separating multiply-and-accumulate.
269
270 gcc/testsuite/
271 * gcc.target/arm/wmul-5.c: New file.
272 * gcc.target/arm/no-wmla-1.c: New file.
273
274 2011-07-27 Andrew Stubbs <ams@codesourcery.com>
275
276 gcc/
277 * config/arm/arm.md (maddhidi4): Remove '*' from name.
278 * expr.c (expand_expr_real_2): Use find_widening_optab_handler.
279 * optabs.c (find_widening_optab_handler_and_mode): New function.
280 (expand_widen_pattern_expr): Use find_widening_optab_handler.
281 (expand_binop_directly): Likewise.
282 (expand_binop): Likewise.
283 * optabs.h (find_widening_optab_handler): New macro define.
284 (find_widening_optab_handler_and_mode): New prototype.
285 * tree-cfg.c (verify_gimple_assign_binary): Adjust WIDEN_MULT_EXPR
286 type precision rules.
287 (verify_gimple_assign_ternary): Likewise for WIDEN_MULT_PLUS_EXPR.
288 * tree-ssa-math-opts.c (build_and_insert_cast): New function.
289 (is_widening_mult_rhs_p): Allow widening by more than one mode.
290 Explicitly disallow mis-matched input types.
291 (convert_mult_to_widen): Use find_widening_optab_handler, and cast
292 input types to fit the new handler.
293 (convert_plusminus_to_widen): Likewise.
294
295 gcc/testsuite/
296 * gcc.target/arm/wmul-bitfield-1.c: New file.
297
298 2011-07-27 Andrew Stubbs <ams@codesourcery.com>
299
300 gcc/
301 * expr.c (expand_expr_real_2): Use widening_optab_handler.
302 * genopinit.c (optabs): Use set_widening_optab_handler for $N.
303 (gen_insn): $N now means $a must be wider than $b, not consecutive.
304 * optabs.c (widened_mode): New function.
305 (expand_widen_pattern_expr): Use widening_optab_handler.
306 (expand_binop_directly): Likewise.
307 (expand_binop): Likewise.
308 * optabs.h (widening_optab_handlers): New struct.
309 (optab_d): New member, 'widening'.
310 (widening_optab_handler): New function.
311 (set_widening_optab_handler): New function.
312 * tree-ssa-math-opts.c (convert_mult_to_widen): Use
313 widening_optab_handler.
314 (convert_plusminus_to_widen): Likewise.
315
316>>>>>>> MERGE-SOURCE
1882011-07-13 Richard Sandiford <richard.sandiford@linaro.org>3172011-07-13 Richard Sandiford <richard.sandiford@linaro.org>
189318
190 Backport from mainline:319 Backport from mainline:
191320
=== modified file 'gcc/config/arm/arm.md'
--- gcc/config/arm/arm.md 2011-06-28 12:02:27 +0000
+++ gcc/config/arm/arm.md 2011-08-11 16:16:07 +0000
@@ -1839,7 +1839,7 @@
1839 (set_attr "predicable" "yes")]1839 (set_attr "predicable" "yes")]
1840)1840)
18411841
1842(define_insn "*maddhidi4"1842(define_insn "maddhidi4"
1843 [(set (match_operand:DI 0 "s_register_operand" "=r")1843 [(set (match_operand:DI 0 "s_register_operand" "=r")
1844 (plus:DI1844 (plus:DI
1845 (mult:DI (sign_extend:DI1845 (mult:DI (sign_extend:DI
18461846
=== modified file 'gcc/expr.c'
--- gcc/expr.c 2011-07-14 11:52:32 +0000
+++ gcc/expr.c 2011-08-11 16:16:07 +0000
@@ -7680,18 +7680,16 @@
7680 {7680 {
7681 enum machine_mode innermode = TYPE_MODE (TREE_TYPE (treeop0));7681 enum machine_mode innermode = TYPE_MODE (TREE_TYPE (treeop0));
7682 this_optab = usmul_widen_optab;7682 this_optab = usmul_widen_optab;
7683 if (mode == GET_MODE_2XWIDER_MODE (innermode))7683 if (find_widening_optab_handler (this_optab, mode, innermode, 0)
7684 != CODE_FOR_nothing)
7684 {7685 {
7685 if (optab_handler (this_optab, mode) != CODE_FOR_nothing)7686 if (TYPE_UNSIGNED (TREE_TYPE (treeop0)))
7686 {7687 expand_operands (treeop0, treeop1, NULL_RTX, &op0, &op1,
7687 if (TYPE_UNSIGNED (TREE_TYPE (treeop0)))7688 EXPAND_NORMAL);
7688 expand_operands (treeop0, treeop1, NULL_RTX, &op0, &op1,7689 else
7689 EXPAND_NORMAL);7690 expand_operands (treeop0, treeop1, NULL_RTX, &op1, &op0,
7690 else7691 EXPAND_NORMAL);
7691 expand_operands (treeop0, treeop1, NULL_RTX, &op1, &op0,7692 goto binop3;
7692 EXPAND_NORMAL);
7693 goto binop3;
7694 }
7695 }7693 }
7696 }7694 }
7697 /* Check for a multiplication with matching signedness. */7695 /* Check for a multiplication with matching signedness. */
@@ -7706,10 +7704,10 @@
7706 optab other_optab = zextend_p ? smul_widen_optab : umul_widen_optab;7704 optab other_optab = zextend_p ? smul_widen_optab : umul_widen_optab;
7707 this_optab = zextend_p ? umul_widen_optab : smul_widen_optab;7705 this_optab = zextend_p ? umul_widen_optab : smul_widen_optab;
77087706
7709 if (mode == GET_MODE_2XWIDER_MODE (innermode)7707 if (TREE_CODE (treeop0) != INTEGER_CST)
7710 && TREE_CODE (treeop0) != INTEGER_CST)
7711 {7708 {
7712 if (optab_handler (this_optab, mode) != CODE_FOR_nothing)7709 if (find_widening_optab_handler (this_optab, mode, innermode, 0)
7710 != CODE_FOR_nothing)
7713 {7711 {
7714 expand_operands (treeop0, treeop1, NULL_RTX, &op0, &op1,7712 expand_operands (treeop0, treeop1, NULL_RTX, &op0, &op1,
7715 EXPAND_NORMAL);7713 EXPAND_NORMAL);
@@ -7717,7 +7715,8 @@
7717 unsignedp, this_optab);7715 unsignedp, this_optab);
7718 return REDUCE_BIT_FIELD (temp);7716 return REDUCE_BIT_FIELD (temp);
7719 }7717 }
7720 if (optab_handler (other_optab, mode) != CODE_FOR_nothing7718 if (find_widening_optab_handler (other_optab, mode, innermode, 0)
7719 != CODE_FOR_nothing
7721 && innermode == word_mode)7720 && innermode == word_mode)
7722 {7721 {
7723 rtx htem, hipart;7722 rtx htem, hipart;
77247723
=== modified file 'gcc/genopinit.c'
--- gcc/genopinit.c 2011-05-05 15:43:06 +0000
+++ gcc/genopinit.c 2011-08-11 16:16:07 +0000
@@ -46,10 +46,12 @@
46 used. $A and $B are replaced with the full name of the mode; $a and $b46 used. $A and $B are replaced with the full name of the mode; $a and $b
47 are replaced with the short form of the name, as above.47 are replaced with the short form of the name, as above.
4848
49 If $N is present in the pattern, it means the two modes must be consecutive49 If $N is present in the pattern, it means the two modes must be in
50 widths in the same mode class (e.g, QImode and HImode). $I means that50 the same mode class, and $b must be greater than $a (e.g, QImode
51 only full integer modes should be considered for the next mode, and $F51 and HImode).
52 means that only float modes should be considered.52
53 $I means that only full integer modes should be considered for the
54 next mode, and $F means that only float modes should be considered.
53 $P means that both full and partial integer modes should be considered.55 $P means that both full and partial integer modes should be considered.
54 $Q means that only fixed-point modes should be considered.56 $Q means that only fixed-point modes should be considered.
5557
@@ -99,17 +101,17 @@
99 "set_optab_handler (smulv_optab, $A, CODE_FOR_$(mulv$I$a3$))",101 "set_optab_handler (smulv_optab, $A, CODE_FOR_$(mulv$I$a3$))",
100 "set_optab_handler (umul_highpart_optab, $A, CODE_FOR_$(umul$a3_highpart$))",102 "set_optab_handler (umul_highpart_optab, $A, CODE_FOR_$(umul$a3_highpart$))",
101 "set_optab_handler (smul_highpart_optab, $A, CODE_FOR_$(smul$a3_highpart$))",103 "set_optab_handler (smul_highpart_optab, $A, CODE_FOR_$(smul$a3_highpart$))",
102 "set_optab_handler (smul_widen_optab, $B, CODE_FOR_$(mul$a$b3$)$N)",104 "set_widening_optab_handler (smul_widen_optab, $B, $A, CODE_FOR_$(mul$a$b3$)$N)",
103 "set_optab_handler (umul_widen_optab, $B, CODE_FOR_$(umul$a$b3$)$N)",105 "set_widening_optab_handler (umul_widen_optab, $B, $A, CODE_FOR_$(umul$a$b3$)$N)",
104 "set_optab_handler (usmul_widen_optab, $B, CODE_FOR_$(usmul$a$b3$)$N)",106 "set_widening_optab_handler (usmul_widen_optab, $B, $A, CODE_FOR_$(usmul$a$b3$)$N)",
105 "set_optab_handler (smadd_widen_optab, $B, CODE_FOR_$(madd$a$b4$)$N)",107 "set_widening_optab_handler (smadd_widen_optab, $B, $A, CODE_FOR_$(madd$a$b4$)$N)",
106 "set_optab_handler (umadd_widen_optab, $B, CODE_FOR_$(umadd$a$b4$)$N)",108 "set_widening_optab_handler (umadd_widen_optab, $B, $A, CODE_FOR_$(umadd$a$b4$)$N)",
107 "set_optab_handler (ssmadd_widen_optab, $B, CODE_FOR_$(ssmadd$a$b4$)$N)",109 "set_widening_optab_handler (ssmadd_widen_optab, $B, $A, CODE_FOR_$(ssmadd$a$b4$)$N)",
108 "set_optab_handler (usmadd_widen_optab, $B, CODE_FOR_$(usmadd$a$b4$)$N)",110 "set_widening_optab_handler (usmadd_widen_optab, $B, $A, CODE_FOR_$(usmadd$a$b4$)$N)",
109 "set_optab_handler (smsub_widen_optab, $B, CODE_FOR_$(msub$a$b4$)$N)",111 "set_widening_optab_handler (smsub_widen_optab, $B, $A, CODE_FOR_$(msub$a$b4$)$N)",
110 "set_optab_handler (umsub_widen_optab, $B, CODE_FOR_$(umsub$a$b4$)$N)",112 "set_widening_optab_handler (umsub_widen_optab, $B, $A, CODE_FOR_$(umsub$a$b4$)$N)",
111 "set_optab_handler (ssmsub_widen_optab, $B, CODE_FOR_$(ssmsub$a$b4$)$N)",113 "set_widening_optab_handler (ssmsub_widen_optab, $B, $A, CODE_FOR_$(ssmsub$a$b4$)$N)",
112 "set_optab_handler (usmsub_widen_optab, $B, CODE_FOR_$(usmsub$a$b4$)$N)",114 "set_widening_optab_handler (usmsub_widen_optab, $B, $A, CODE_FOR_$(usmsub$a$b4$)$N)",
113 "set_optab_handler (sdiv_optab, $A, CODE_FOR_$(div$a3$))",115 "set_optab_handler (sdiv_optab, $A, CODE_FOR_$(div$a3$))",
114 "set_optab_handler (ssdiv_optab, $A, CODE_FOR_$(ssdiv$Q$a3$))",116 "set_optab_handler (ssdiv_optab, $A, CODE_FOR_$(ssdiv$Q$a3$))",
115 "set_optab_handler (sdivv_optab, $A, CODE_FOR_$(div$V$I$a3$))",117 "set_optab_handler (sdivv_optab, $A, CODE_FOR_$(div$V$I$a3$))",
@@ -304,7 +306,7 @@
304 {306 {
305 int force_float = 0, force_int = 0, force_partial_int = 0;307 int force_float = 0, force_int = 0, force_partial_int = 0;
306 int force_fixed = 0;308 int force_fixed = 0;
307 int force_consec = 0;309 int force_wider = 0;
308 int matches = 1;310 int matches = 1;
309311
310 for (pp = optabs[pindex]; pp[0] != '$' || pp[1] != '('; pp++)312 for (pp = optabs[pindex]; pp[0] != '$' || pp[1] != '('; pp++)
@@ -322,7 +324,7 @@
322 switch (*++pp)324 switch (*++pp)
323 {325 {
324 case 'N':326 case 'N':
325 force_consec = 1;327 force_wider = 1;
326 break;328 break;
327 case 'I':329 case 'I':
328 force_int = 1;330 force_int = 1;
@@ -391,7 +393,10 @@
391 || mode_class[i] == MODE_VECTOR_FRACT393 || mode_class[i] == MODE_VECTOR_FRACT
392 || mode_class[i] == MODE_VECTOR_UFRACT394 || mode_class[i] == MODE_VECTOR_UFRACT
393 || mode_class[i] == MODE_VECTOR_ACCUM395 || mode_class[i] == MODE_VECTOR_ACCUM
394 || mode_class[i] == MODE_VECTOR_UACCUM))396 || mode_class[i] == MODE_VECTOR_UACCUM)
397 && (! force_wider
398 || *pp == 'a'
399 || m1 < i))
395 break;400 break;
396 }401 }
397402
@@ -411,8 +416,7 @@
411 }416 }
412417
413 if (matches && pp[0] == '$' && pp[1] == ')'418 if (matches && pp[0] == '$' && pp[1] == ')'
414 && *np == 0419 && *np == 0)
415 && (! force_consec || (int) GET_MODE_WIDER_MODE(m1) == m2))
416 break;420 break;
417 }421 }
418422
419423
=== modified file 'gcc/optabs.c'
--- gcc/optabs.c 2011-07-04 14:03:49 +0000
+++ gcc/optabs.c 2011-08-11 16:16:07 +0000
@@ -225,6 +225,61 @@
225 return 1;225 return 1;
226}226}
227227
228228
229/* Given two input operands, OP0 and OP1, determine what the correct from_mode
230 for a widening operation would be. In most cases this would be OP0, but if
231 that's a constant it'll be VOIDmode, which isn't useful. */
232
233static enum machine_mode
234widened_mode (enum machine_mode to_mode, rtx op0, rtx op1)
235{
236 enum machine_mode m0 = GET_MODE (op0);
237 enum machine_mode m1 = GET_MODE (op1);
238 enum machine_mode result;
239
240 if (m0 == VOIDmode && m1 == VOIDmode)
241 return to_mode;
242 else if (m0 == VOIDmode || GET_MODE_SIZE (m0) < GET_MODE_SIZE (m1))
243 result = m1;
244 else
245 result = m0;
246
247 if (GET_MODE_SIZE (result) > GET_MODE_SIZE (to_mode))
248 return to_mode;
249
250 return result;
251}
252
229253
254/* Find a widening optab even if it doesn't widen as much as we want.
255 E.g. if from_mode is HImode, and to_mode is DImode, and there is no
256 direct HI->SI insn, then return SI->DI, if that exists.
257 If PERMIT_NON_WIDENING is non-zero then this can be used with
258 non-widening optabs also. */
259
260enum insn_code
261find_widening_optab_handler_and_mode (optab op, enum machine_mode to_mode,
262 enum machine_mode from_mode,
263 int permit_non_widening,
264 enum machine_mode *found_mode)
265{
266 for (; (permit_non_widening || from_mode != to_mode)
267 && GET_MODE_SIZE (from_mode) <= GET_MODE_SIZE (to_mode)
268 && from_mode != VOIDmode;
269 from_mode = GET_MODE_WIDER_MODE (from_mode))
270 {
271 enum insn_code handler = widening_optab_handler (op, to_mode,
272 from_mode);
273
274 if (handler != CODE_FOR_nothing)
275 {
276 if (found_mode)
277 *found_mode = from_mode;
278 return handler;
279 }
280 }
281
282 return CODE_FOR_nothing;
283}
284
230285
231/* Widen OP to MODE and return the rtx for the widened operand. UNSIGNEDP286/* Widen OP to MODE and return the rtx for the widened operand. UNSIGNEDP
232 says whether OP is signed or unsigned. NO_EXTEND is nonzero if we need287 says whether OP is signed or unsigned. NO_EXTEND is nonzero if we need
233 not actually do a sign-extend or zero-extend, but can leave the288 not actually do a sign-extend or zero-extend, but can leave the
@@ -517,8 +572,9 @@
517 optab_for_tree_code (ops->code, TREE_TYPE (oprnd0), optab_default);572 optab_for_tree_code (ops->code, TREE_TYPE (oprnd0), optab_default);
518 if (ops->code == WIDEN_MULT_PLUS_EXPR573 if (ops->code == WIDEN_MULT_PLUS_EXPR
519 || ops->code == WIDEN_MULT_MINUS_EXPR)574 || ops->code == WIDEN_MULT_MINUS_EXPR)
520 icode = (int) optab_handler (widen_pattern_optab,575 icode = (int) find_widening_optab_handler (widen_pattern_optab,
521 TYPE_MODE (TREE_TYPE (ops->op2)));576 TYPE_MODE (TREE_TYPE (ops->op2)),
577 tmode0, 0);
522 else578 else
523 icode = (int) optab_handler (widen_pattern_optab, tmode0);579 icode = (int) optab_handler (widen_pattern_optab, tmode0);
524 gcc_assert (icode != CODE_FOR_nothing);580 gcc_assert (icode != CODE_FOR_nothing);
@@ -1389,7 +1445,9 @@
1389 rtx target, int unsignedp, enum optab_methods methods,1445 rtx target, int unsignedp, enum optab_methods methods,
1390 rtx last)1446 rtx last)
1391{1447{
1392 int icode = (int) optab_handler (binoptab, mode);1448 enum machine_mode from_mode = widened_mode (mode, op0, op1);
1449 int icode = (int) find_widening_optab_handler (binoptab, mode,
1450 from_mode, 1);
1393 enum machine_mode mode0 = insn_data[icode].operand[1].mode;1451 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
1394 enum machine_mode mode1 = insn_data[icode].operand[2].mode;1452 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
1395 enum machine_mode tmp_mode;1453 enum machine_mode tmp_mode;
@@ -1546,7 +1604,9 @@
1546 /* If we can do it with a three-operand insn, do so. */1604 /* If we can do it with a three-operand insn, do so. */
15471605
1548 if (methods != OPTAB_MUST_WIDEN1606 if (methods != OPTAB_MUST_WIDEN
1549 && optab_handler (binoptab, mode) != CODE_FOR_nothing)1607 && find_widening_optab_handler (binoptab, mode,
1608 widened_mode (mode, op0, op1), 1)
1609 != CODE_FOR_nothing)
1550 {1610 {
1551 temp = expand_binop_directly (mode, binoptab, op0, op1, target,1611 temp = expand_binop_directly (mode, binoptab, op0, op1, target,
1552 unsignedp, methods, last);1612 unsignedp, methods, last);
@@ -1586,8 +1646,9 @@
15861646
1587 if (binoptab == smul_optab1647 if (binoptab == smul_optab
1588 && GET_MODE_WIDER_MODE (mode) != VOIDmode1648 && GET_MODE_WIDER_MODE (mode) != VOIDmode
1589 && (optab_handler ((unsignedp ? umul_widen_optab : smul_widen_optab),1649 && (widening_optab_handler ((unsignedp ? umul_widen_optab
1590 GET_MODE_WIDER_MODE (mode))1650 : smul_widen_optab),
1651 GET_MODE_WIDER_MODE (mode), mode)
1591 != CODE_FOR_nothing))1652 != CODE_FOR_nothing))
1592 {1653 {
1593 temp = expand_binop (GET_MODE_WIDER_MODE (mode),1654 temp = expand_binop (GET_MODE_WIDER_MODE (mode),
@@ -1618,9 +1679,11 @@
1618 if (optab_handler (binoptab, wider_mode) != CODE_FOR_nothing1679 if (optab_handler (binoptab, wider_mode) != CODE_FOR_nothing
1619 || (binoptab == smul_optab1680 || (binoptab == smul_optab
1620 && GET_MODE_WIDER_MODE (wider_mode) != VOIDmode1681 && GET_MODE_WIDER_MODE (wider_mode) != VOIDmode
1621 && (optab_handler ((unsignedp ? umul_widen_optab1682 && (find_widening_optab_handler ((unsignedp
1622 : smul_widen_optab),1683 ? umul_widen_optab
1623 GET_MODE_WIDER_MODE (wider_mode))1684 : smul_widen_optab),
1685 GET_MODE_WIDER_MODE (wider_mode),
1686 mode, 0)
1624 != CODE_FOR_nothing)))1687 != CODE_FOR_nothing)))
1625 {1688 {
1626 rtx xop0 = op0, xop1 = op1;1689 rtx xop0 = op0, xop1 = op1;
@@ -2043,8 +2106,8 @@
2043 && optab_handler (add_optab, word_mode) != CODE_FOR_nothing)2106 && optab_handler (add_optab, word_mode) != CODE_FOR_nothing)
2044 {2107 {
2045 rtx product = NULL_RTX;2108 rtx product = NULL_RTX;
20462109 if (widening_optab_handler (umul_widen_optab, mode, word_mode)
2047 if (optab_handler (umul_widen_optab, mode) != CODE_FOR_nothing)2110 != CODE_FOR_nothing)
2048 {2111 {
2049 product = expand_doubleword_mult (mode, op0, op1, target,2112 product = expand_doubleword_mult (mode, op0, op1, target,
2050 true, methods);2113 true, methods);
@@ -2053,7 +2116,8 @@
2053 }2116 }
20542117
2055 if (product == NULL_RTX2118 if (product == NULL_RTX
2056 && optab_handler (smul_widen_optab, mode) != CODE_FOR_nothing)2119 && widening_optab_handler (smul_widen_optab, mode, word_mode)
2120 != CODE_FOR_nothing)
2057 {2121 {
2058 product = expand_doubleword_mult (mode, op0, op1, target,2122 product = expand_doubleword_mult (mode, op0, op1, target,
2059 false, methods);2123 false, methods);
@@ -2144,7 +2208,8 @@
2144 wider_mode != VOIDmode;2208 wider_mode != VOIDmode;
2145 wider_mode = GET_MODE_WIDER_MODE (wider_mode))2209 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2146 {2210 {
2147 if (optab_handler (binoptab, wider_mode) != CODE_FOR_nothing2211 if (find_widening_optab_handler (binoptab, wider_mode, mode, 1)
2212 != CODE_FOR_nothing
2148 || (methods == OPTAB_LIB2213 || (methods == OPTAB_LIB
2149 && optab_libfunc (binoptab, wider_mode)))2214 && optab_libfunc (binoptab, wider_mode)))
2150 {2215 {
21512216
=== modified file 'gcc/optabs.h'
--- gcc/optabs.h 2011-05-05 15:43:06 +0000
+++ gcc/optabs.h 2011-08-11 16:16:07 +0000
@@ -42,6 +42,11 @@
42 int insn_code;42 int insn_code;
43};43};
4444
45struct widening_optab_handlers
46{
47 struct optab_handlers handlers[NUM_MACHINE_MODES][NUM_MACHINE_MODES];
48};
49
45struct optab_d50struct optab_d
46{51{
47 enum rtx_code code;52 enum rtx_code code;
@@ -50,6 +55,7 @@
50 void (*libcall_gen)(struct optab_d *, const char *name, char suffix,55 void (*libcall_gen)(struct optab_d *, const char *name, char suffix,
51 enum machine_mode);56 enum machine_mode);
52 struct optab_handlers handlers[NUM_MACHINE_MODES];57 struct optab_handlers handlers[NUM_MACHINE_MODES];
58 struct widening_optab_handlers *widening;
53};59};
54typedef struct optab_d * optab;60typedef struct optab_d * optab;
5561
@@ -799,6 +805,15 @@
799extern void emit_unop_insn (int, rtx, rtx, enum rtx_code);805extern void emit_unop_insn (int, rtx, rtx, enum rtx_code);
800extern bool maybe_emit_unop_insn (int, rtx, rtx, enum rtx_code);806extern bool maybe_emit_unop_insn (int, rtx, rtx, enum rtx_code);
801807
808/* Find a widening optab even if it doesn't widen as much as we want. */
809#define find_widening_optab_handler(A,B,C,D) \
810 find_widening_optab_handler_and_mode (A, B, C, D, NULL)
811extern enum insn_code find_widening_optab_handler_and_mode (optab,
812 enum machine_mode,
813 enum machine_mode,
814 int,
815 enum machine_mode *);
816
802/* An extra flag to control optab_for_tree_code's behavior. This is needed to817/* An extra flag to control optab_for_tree_code's behavior. This is needed to
803 distinguish between machines with a vector shift that takes a scalar for the818 distinguish between machines with a vector shift that takes a scalar for the
804 shift amount vs. machines that take a vector for the shift amount. */819 shift amount vs. machines that take a vector for the shift amount. */
@@ -874,6 +889,23 @@
874 + (int) CODE_FOR_nothing);889 + (int) CODE_FOR_nothing);
875}890}
876891
892/* Like optab_handler, but for widening_operations that have a TO_MODE and
893 a FROM_MODE. */
894
895static inline enum insn_code
896widening_optab_handler (optab op, enum machine_mode to_mode,
897 enum machine_mode from_mode)
898{
899 if (to_mode == from_mode || from_mode == VOIDmode)
900 return optab_handler (op, to_mode);
901
902 if (op->widening)
903 return (enum insn_code) (op->widening->handlers[(int) to_mode][(int) from_mode].insn_code
904 + (int) CODE_FOR_nothing);
905
906 return CODE_FOR_nothing;
907}
908
877/* Record that insn CODE should be used to implement mode MODE of OP. */909/* Record that insn CODE should be used to implement mode MODE of OP. */
878910
879static inline void911static inline void
@@ -882,6 +914,26 @@
882 op->handlers[(int) mode].insn_code = (int) code - (int) CODE_FOR_nothing;914 op->handlers[(int) mode].insn_code = (int) code - (int) CODE_FOR_nothing;
883}915}
884916
917/* Like set_optab_handler, but for widening operations that have a TO_MODE
918 and a FROM_MODE. */
919
920static inline void
921set_widening_optab_handler (optab op, enum machine_mode to_mode,
922 enum machine_mode from_mode, enum insn_code code)
923{
924 if (to_mode == from_mode)
925 set_optab_handler (op, to_mode, code);
926 else
927 {
928 if (op->widening == NULL)
929 op->widening = (struct widening_optab_handlers *)
930 xcalloc (1, sizeof (struct widening_optab_handlers));
931
932 op->widening->handlers[(int) to_mode][(int) from_mode].insn_code
933 = (int) code - (int) CODE_FOR_nothing;
934 }
935}
936
885/* Return the insn used to perform conversion OP from mode FROM_MODE937/* Return the insn used to perform conversion OP from mode FROM_MODE
886 to mode TO_MODE; return CODE_FOR_nothing if the target does not have938 to mode TO_MODE; return CODE_FOR_nothing if the target does not have
887 such an insn. */939 such an insn. */
888940
=== added file 'gcc/testsuite/gcc.target/arm/no-wmla-1.c'
--- gcc/testsuite/gcc.target/arm/no-wmla-1.c 1970-01-01 00:00:00 +0000
+++ gcc/testsuite/gcc.target/arm/no-wmla-1.c 2011-08-11 16:16:07 +0000
@@ -0,0 +1,11 @@
1/* { dg-do compile } */
2/* { dg-options "-O2 -march=armv7-a" } */
3
4int
5foo (int a, short b, short c)
6{
7 int bc = b * c;
8 return a + (short)bc;
9}
10
11/* { dg-final { scan-assembler "mul" } } */
012
=== added file 'gcc/testsuite/gcc.target/arm/wmul-10.c'
--- gcc/testsuite/gcc.target/arm/wmul-10.c 1970-01-01 00:00:00 +0000
+++ gcc/testsuite/gcc.target/arm/wmul-10.c 2011-08-11 16:16:07 +0000
@@ -0,0 +1,10 @@
1/* { dg-do compile } */
2/* { dg-options "-O2 -march=armv7-a" } */
3
4unsigned long long
5foo (unsigned short a, unsigned short *b, unsigned short *c)
6{
7 return (unsigned)a + (unsigned long long)*b * (unsigned long long)*c;
8}
9
10/* { dg-final { scan-assembler "umlal" } } */
011
=== added file 'gcc/testsuite/gcc.target/arm/wmul-11.c'
--- gcc/testsuite/gcc.target/arm/wmul-11.c 1970-01-01 00:00:00 +0000
+++ gcc/testsuite/gcc.target/arm/wmul-11.c 2011-08-11 16:16:07 +0000
@@ -0,0 +1,10 @@
1/* { dg-do compile } */
2/* { dg-options "-O2 -march=armv7-a" } */
3
4long long
5foo (int *b)
6{
7 return 10 * (long long)*b;
8}
9
10/* { dg-final { scan-assembler "smull" } } */
011
=== added file 'gcc/testsuite/gcc.target/arm/wmul-12.c'
--- gcc/testsuite/gcc.target/arm/wmul-12.c 1970-01-01 00:00:00 +0000
+++ gcc/testsuite/gcc.target/arm/wmul-12.c 2011-08-11 16:16:07 +0000
@@ -0,0 +1,11 @@
1/* { dg-do compile } */
2/* { dg-options "-O2 -march=armv7-a" } */
3
4long long
5foo (int *b, int *c)
6{
7 int tmp = *b * *c;
8 return 10 + (long long)tmp;
9}
10
11/* { dg-final { scan-assembler "smlal" } } */
012
=== added file 'gcc/testsuite/gcc.target/arm/wmul-13.c'
--- gcc/testsuite/gcc.target/arm/wmul-13.c 1970-01-01 00:00:00 +0000
+++ gcc/testsuite/gcc.target/arm/wmul-13.c 2011-08-11 16:16:07 +0000
@@ -0,0 +1,10 @@
1/* { dg-do compile } */
2/* { dg-options "-O2 -march=armv7-a" } */
3
4long long
5foo (int *a, int *b)
6{
7 return *a + (long long)*b * 10;
8}
9
10/* { dg-final { scan-assembler "smlal" } } */
011
=== added file 'gcc/testsuite/gcc.target/arm/wmul-5.c'
--- gcc/testsuite/gcc.target/arm/wmul-5.c 1970-01-01 00:00:00 +0000
+++ gcc/testsuite/gcc.target/arm/wmul-5.c 2011-08-11 16:16:07 +0000
@@ -0,0 +1,10 @@
1/* { dg-do compile } */
2/* { dg-options "-O2 -march=armv7-a" } */
3
4long long
5foo (long long a, char *b, char *c)
6{
7 return a + *b * *c;
8}
9
10/* { dg-final { scan-assembler "umlal" } } */
011
=== added file 'gcc/testsuite/gcc.target/arm/wmul-6.c'
--- gcc/testsuite/gcc.target/arm/wmul-6.c 1970-01-01 00:00:00 +0000
+++ gcc/testsuite/gcc.target/arm/wmul-6.c 2011-08-11 16:16:07 +0000
@@ -0,0 +1,10 @@
1/* { dg-do compile } */
2/* { dg-options "-O2 -march=armv7-a" } */
3
4long long
5foo (long long a, unsigned char *b, signed char *c)
6{
7 return a + (long long)*b * (long long)*c;
8}
9
10/* { dg-final { scan-assembler "smlal" } } */
011
=== added file 'gcc/testsuite/gcc.target/arm/wmul-7.c'
--- gcc/testsuite/gcc.target/arm/wmul-7.c 1970-01-01 00:00:00 +0000
+++ gcc/testsuite/gcc.target/arm/wmul-7.c 2011-08-11 16:16:07 +0000
@@ -0,0 +1,10 @@
1/* { dg-do compile } */
2/* { dg-options "-O2 -march=armv7-a" } */
3
4unsigned long long
5foo (unsigned long long a, unsigned char *b, unsigned short *c)
6{
7 return a + *b * *c;
8}
9
10/* { dg-final { scan-assembler "umlal" } } */
011
=== added file 'gcc/testsuite/gcc.target/arm/wmul-8.c'
--- gcc/testsuite/gcc.target/arm/wmul-8.c 1970-01-01 00:00:00 +0000
+++ gcc/testsuite/gcc.target/arm/wmul-8.c 2011-08-11 16:16:07 +0000
@@ -0,0 +1,10 @@
1/* { dg-do compile } */
2/* { dg-options "-O2 -march=armv7-a" } */
3
4long long
5foo (long long a, int *b, int *c)
6{
7 return a + *b * *c;
8}
9
10/* { dg-final { scan-assembler "smlal" } } */
011
=== added file 'gcc/testsuite/gcc.target/arm/wmul-9.c'
--- gcc/testsuite/gcc.target/arm/wmul-9.c 1970-01-01 00:00:00 +0000
+++ gcc/testsuite/gcc.target/arm/wmul-9.c 2011-08-11 16:16:07 +0000
@@ -0,0 +1,10 @@
1/* { dg-do compile } */
2/* { dg-options "-O2 -march=armv7-a" } */
3
4long long
5foo (long long a, short *b, char *c)
6{
7 return a + *b * *c;
8}
9
10/* { dg-final { scan-assembler "smlalbb" } } */
011
=== added file 'gcc/testsuite/gcc.target/arm/wmul-bitfield-1.c'
--- gcc/testsuite/gcc.target/arm/wmul-bitfield-1.c 1970-01-01 00:00:00 +0000
+++ gcc/testsuite/gcc.target/arm/wmul-bitfield-1.c 2011-08-11 16:16:07 +0000
@@ -0,0 +1,17 @@
1/* { dg-do compile } */
2/* { dg-options "-O2 -march=armv7-a" } */
3
4struct bf
5{
6 int a : 3;
7 int b : 15;
8 int c : 3;
9};
10
11long long
12foo (long long a, struct bf b, struct bf c)
13{
14 return a + b.b * c.b;
15}
16
17/* { dg-final { scan-assembler "smlalbb" } } */
018
=== added file 'gcc/testsuite/gcc.target/arm/wmul-bitfield-2.c'
--- gcc/testsuite/gcc.target/arm/wmul-bitfield-2.c 1970-01-01 00:00:00 +0000
+++ gcc/testsuite/gcc.target/arm/wmul-bitfield-2.c 2011-08-11 16:16:07 +0000
@@ -0,0 +1,17 @@
1/* { dg-do compile } */
2/* { dg-options "-O2 -march=armv7-a" } */
3
4struct bf
5{
6 int a : 3;
7 unsigned int b : 15;
8 int c : 3;
9};
10
11long long
12foo (long long a, struct bf b, struct bf c)
13{
14 return a + b.b * c.c;
15}
16
17/* { dg-final { scan-assembler "smlalbb" } } */
018
=== modified file 'gcc/tree-cfg.c'
--- gcc/tree-cfg.c 2011-07-01 09:19:21 +0000
+++ gcc/tree-cfg.c 2011-08-11 16:16:07 +0000
@@ -3574,7 +3574,7 @@
3574 case WIDEN_MULT_EXPR:3574 case WIDEN_MULT_EXPR:
3575 if (TREE_CODE (lhs_type) != INTEGER_TYPE)3575 if (TREE_CODE (lhs_type) != INTEGER_TYPE)
3576 return true;3576 return true;
3577 return ((2 * TYPE_PRECISION (rhs1_type) != TYPE_PRECISION (lhs_type))3577 return ((2 * TYPE_PRECISION (rhs1_type) > TYPE_PRECISION (lhs_type))
3578 || (TYPE_PRECISION (rhs1_type) != TYPE_PRECISION (rhs2_type)));3578 || (TYPE_PRECISION (rhs1_type) != TYPE_PRECISION (rhs2_type)));
35793579
3580 case WIDEN_SUM_EXPR:3580 case WIDEN_SUM_EXPR:
@@ -3667,7 +3667,7 @@
3667 && !FIXED_POINT_TYPE_P (rhs1_type))3667 && !FIXED_POINT_TYPE_P (rhs1_type))
3668 || !useless_type_conversion_p (rhs1_type, rhs2_type)3668 || !useless_type_conversion_p (rhs1_type, rhs2_type)
3669 || !useless_type_conversion_p (lhs_type, rhs3_type)3669 || !useless_type_conversion_p (lhs_type, rhs3_type)
3670 || 2 * TYPE_PRECISION (rhs1_type) != TYPE_PRECISION (lhs_type)3670 || 2 * TYPE_PRECISION (rhs1_type) > TYPE_PRECISION (lhs_type)
3671 || TYPE_PRECISION (rhs1_type) != TYPE_PRECISION (rhs2_type))3671 || TYPE_PRECISION (rhs1_type) != TYPE_PRECISION (rhs2_type))
3672 {3672 {
3673 error ("type mismatch in widening multiply-accumulate expression");3673 error ("type mismatch in widening multiply-accumulate expression");
36743674
=== modified file 'gcc/tree-ssa-math-opts.c'
--- gcc/tree-ssa-math-opts.c 2011-03-11 16:36:16 +0000
+++ gcc/tree-ssa-math-opts.c 2011-08-11 16:16:07 +0000
@@ -1266,39 +1266,67 @@
1266 }1266 }
1267};1267};
12681268
1269/* Return true if RHS is a suitable operand for a widening multiplication.1269/* Build a gimple assignment to cast VAL to TARGET. Insert the statement
1270 prior to GSI's current position, and return the fresh SSA name. */
1271
1272static tree
1273build_and_insert_cast (gimple_stmt_iterator *gsi, location_t loc,
1274 tree target, tree val)
1275{
1276 tree result = make_ssa_name (target, NULL);
1277 gimple stmt = gimple_build_assign_with_ops (CONVERT_EXPR, result, val, NULL);
1278 gimple_set_location (stmt, loc);
1279 gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
1280 return result;
1281}
1282
1283/* Return true if RHS is a suitable operand for a widening multiplication,
1284 assuming a target type of TYPE.
1270 There are two cases:1285 There are two cases:
12711286
1272 - RHS makes some value twice as wide. Store that value in *NEW_RHS_OUT1287 - RHS makes some value at least twice as wide. Store that value
1273 if so, and store its type in *TYPE_OUT.1288 in *NEW_RHS_OUT if so, and store its type in *TYPE_OUT.
12741289
1275 - RHS is an integer constant. Store that value in *NEW_RHS_OUT if so,1290 - RHS is an integer constant. Store that value in *NEW_RHS_OUT if so,
1276 but leave *TYPE_OUT untouched. */1291 but leave *TYPE_OUT untouched. */
12771292
1278static bool1293static bool
1279is_widening_mult_rhs_p (tree rhs, tree *type_out, tree *new_rhs_out)1294is_widening_mult_rhs_p (tree type, tree rhs, tree *type_out,
1295 tree *new_rhs_out)
1280{1296{
1281 gimple stmt;1297 gimple stmt;
1282 tree type, type1, rhs1;1298 tree type1, rhs1;
1283 enum tree_code rhs_code;1299 enum tree_code rhs_code;
12841300
1285 if (TREE_CODE (rhs) == SSA_NAME)1301 if (TREE_CODE (rhs) == SSA_NAME)
1286 {1302 {
1287 type = TREE_TYPE (rhs);
1288 stmt = SSA_NAME_DEF_STMT (rhs);1303 stmt = SSA_NAME_DEF_STMT (rhs);
1289 if (!is_gimple_assign (stmt))1304 if (is_gimple_assign (stmt))
1290 return false;1305 {
12911306 rhs_code = gimple_assign_rhs_code (stmt);
1292 rhs_code = gimple_assign_rhs_code (stmt);1307 if (TREE_CODE (type) == INTEGER_TYPE
1293 if (TREE_CODE (type) == INTEGER_TYPE1308 ? !CONVERT_EXPR_CODE_P (rhs_code)
1294 ? !CONVERT_EXPR_CODE_P (rhs_code)1309 : rhs_code != FIXED_CONVERT_EXPR)
1295 : rhs_code != FIXED_CONVERT_EXPR)1310 rhs1 = rhs;
1296 return false;1311 else
12971312 {
1298 rhs1 = gimple_assign_rhs1 (stmt);1313 rhs1 = gimple_assign_rhs1 (stmt);
1314
1315 if (TREE_CODE (rhs1) == INTEGER_CST)
1316 {
1317 *new_rhs_out = rhs1;
1318 *type_out = NULL;
1319 return true;
1320 }
1321 }
1322 }
1323 else
1324 rhs1 = rhs;
1325
1299 type1 = TREE_TYPE (rhs1);1326 type1 = TREE_TYPE (rhs1);
1327
1300 if (TREE_CODE (type1) != TREE_CODE (type)1328 if (TREE_CODE (type1) != TREE_CODE (type)
1301 || TYPE_PRECISION (type1) * 2 != TYPE_PRECISION (type))1329 || TYPE_PRECISION (type1) * 2 > TYPE_PRECISION (type))
1302 return false;1330 return false;
13031331
1304 *new_rhs_out = rhs1;1332 *new_rhs_out = rhs1;
@@ -1316,28 +1344,27 @@
1316 return false;1344 return false;
1317}1345}
13181346
1319/* Return true if STMT performs a widening multiplication. If so,1347/* Return true if STMT performs a widening multiplication, assuming the
1320 store the unwidened types of the operands in *TYPE1_OUT and *TYPE2_OUT1348 output type is TYPE. If so, store the unwidened types of the operands
1321 respectively. Also fill *RHS1_OUT and *RHS2_OUT such that converting1349 in *TYPE1_OUT and *TYPE2_OUT respectively. Also fill *RHS1_OUT and
1322 those operands to types *TYPE1_OUT and *TYPE2_OUT would give the1350 *RHS2_OUT such that converting those operands to types *TYPE1_OUT
1323 operands of the multiplication. */1351 and *TYPE2_OUT would give the operands of the multiplication. */
13241352
1325static bool1353static bool
1326is_widening_mult_p (gimple stmt,1354is_widening_mult_p (tree type, gimple stmt,
1327 tree *type1_out, tree *rhs1_out,1355 tree *type1_out, tree *rhs1_out,
1328 tree *type2_out, tree *rhs2_out)1356 tree *type2_out, tree *rhs2_out)
1329{1357{
1330 tree type;
1331
1332 type = TREE_TYPE (gimple_assign_lhs (stmt));
1333 if (TREE_CODE (type) != INTEGER_TYPE1358 if (TREE_CODE (type) != INTEGER_TYPE
1334 && TREE_CODE (type) != FIXED_POINT_TYPE)1359 && TREE_CODE (type) != FIXED_POINT_TYPE)
1335 return false;1360 return false;
13361361
1337 if (!is_widening_mult_rhs_p (gimple_assign_rhs1 (stmt), type1_out, rhs1_out))1362 if (!is_widening_mult_rhs_p (type, gimple_assign_rhs1 (stmt), type1_out,
1363 rhs1_out))
1338 return false;1364 return false;
13391365
1340 if (!is_widening_mult_rhs_p (gimple_assign_rhs2 (stmt), type2_out, rhs2_out))1366 if (!is_widening_mult_rhs_p (type, gimple_assign_rhs2 (stmt), type2_out,
1367 rhs2_out))
1341 return false;1368 return false;
13421369
1343 if (*type1_out == NULL)1370 if (*type1_out == NULL)
@@ -1354,6 +1381,18 @@
1354 *type2_out = *type1_out;1381 *type2_out = *type1_out;
1355 }1382 }
13561383
1384 /* Ensure that the larger of the two operands comes first. */
1385 if (TYPE_PRECISION (*type1_out) < TYPE_PRECISION (*type2_out))
1386 {
1387 tree tmp;
1388 tmp = *type1_out;
1389 *type1_out = *type2_out;
1390 *type2_out = tmp;
1391 tmp = *rhs1_out;
1392 *rhs1_out = *rhs2_out;
1393 *rhs2_out = tmp;
1394 }
1395
1357 return true;1396 return true;
1358}1397}
13591398
@@ -1362,31 +1401,100 @@
1362 value is true iff we converted the statement. */1401 value is true iff we converted the statement. */
13631402
1364static bool1403static bool
1365convert_mult_to_widen (gimple stmt)1404convert_mult_to_widen (gimple stmt, gimple_stmt_iterator *gsi)
1366{1405{
1367 tree lhs, rhs1, rhs2, type, type1, type2;1406 tree lhs, rhs1, rhs2, type, type1, type2, tmp = NULL;
1368 enum insn_code handler;1407 enum insn_code handler;
1408 enum machine_mode to_mode, from_mode, actual_mode;
1409 optab op;
1410 int actual_precision;
1411 location_t loc = gimple_location (stmt);
1412 bool from_unsigned1, from_unsigned2;
13691413
1370 lhs = gimple_assign_lhs (stmt);1414 lhs = gimple_assign_lhs (stmt);
1371 type = TREE_TYPE (lhs);1415 type = TREE_TYPE (lhs);
1372 if (TREE_CODE (type) != INTEGER_TYPE)1416 if (TREE_CODE (type) != INTEGER_TYPE)
1373 return false;1417 return false;
13741418
1375 if (!is_widening_mult_p (stmt, &type1, &rhs1, &type2, &rhs2))1419 if (!is_widening_mult_p (type, stmt, &type1, &rhs1, &type2, &rhs2))
1376 return false;1420 return false;
13771421
1378 if (TYPE_UNSIGNED (type1) && TYPE_UNSIGNED (type2))1422 to_mode = TYPE_MODE (type);
1379 handler = optab_handler (umul_widen_optab, TYPE_MODE (type));1423 from_mode = TYPE_MODE (type1);
1380 else if (!TYPE_UNSIGNED (type1) && !TYPE_UNSIGNED (type2))1424 from_unsigned1 = TYPE_UNSIGNED (type1);
1381 handler = optab_handler (smul_widen_optab, TYPE_MODE (type));1425 from_unsigned2 = TYPE_UNSIGNED (type2);
1426
1427 if (from_unsigned1 && from_unsigned2)
1428 op = umul_widen_optab;
1429 else if (!from_unsigned1 && !from_unsigned2)
1430 op = smul_widen_optab;
1382 else1431 else
1383 handler = optab_handler (usmul_widen_optab, TYPE_MODE (type));1432 op = usmul_widen_optab;
1433
1434 handler = find_widening_optab_handler_and_mode (op, to_mode, from_mode,
1435 0, &actual_mode);
13841436
1385 if (handler == CODE_FOR_nothing)1437 if (handler == CODE_FOR_nothing)
1386 return false;1438 {
13871439 if (op != smul_widen_optab)
1388 gimple_assign_set_rhs1 (stmt, fold_convert (type1, rhs1));1440 {
1389 gimple_assign_set_rhs2 (stmt, fold_convert (type2, rhs2));1441 /* We can use a signed multiply with unsigned types as long as
1442 there is a wider mode to use, or it is the smaller of the two
1443 types that is unsigned. Note that type1 >= type2, always. */
1444 if ((TYPE_UNSIGNED (type1)
1445 && TYPE_PRECISION (type1) == GET_MODE_PRECISION (from_mode))
1446 || (TYPE_UNSIGNED (type2)
1447 && TYPE_PRECISION (type2) == GET_MODE_PRECISION (from_mode)))
1448 {
1449 from_mode = GET_MODE_WIDER_MODE (from_mode);
1450 if (GET_MODE_SIZE (to_mode) <= GET_MODE_SIZE (from_mode))
1451 return false;
1452 }
1453
1454 op = smul_widen_optab;
1455 handler = find_widening_optab_handler_and_mode (op, to_mode,
1456 from_mode, 0,
1457 &actual_mode);
1458
1459 if (handler == CODE_FOR_nothing)
1460 return false;
1461
1462 from_unsigned1 = from_unsigned2 = false;
1463 }
1464 else
1465 return false;
1466 }
1467
1468 /* Ensure that the inputs to the handler are in the correct precison
1469 for the opcode. This will be the full mode size. */
1470 actual_precision = GET_MODE_PRECISION (actual_mode);
1471 if (actual_precision != TYPE_PRECISION (type1)
1472 || from_unsigned1 != TYPE_UNSIGNED (type1))
1473 {
1474 tmp = create_tmp_var (build_nonstandard_integer_type
1475 (actual_precision, from_unsigned1),
1476 NULL);
1477 rhs1 = build_and_insert_cast (gsi, loc, tmp, rhs1);
1478 }
1479 if (actual_precision != TYPE_PRECISION (type2)
1480 || from_unsigned2 != TYPE_UNSIGNED (type2))
1481 {
1482 /* Reuse the same type info, if possible. */
1483 if (!tmp || from_unsigned1 != from_unsigned2)
1484 tmp = create_tmp_var (build_nonstandard_integer_type
1485 (actual_precision, from_unsigned2),
1486 NULL);
1487 rhs2 = build_and_insert_cast (gsi, loc, tmp, rhs2);
1488 }
1489
1490 /* Handle constants. */
1491 if (TREE_CODE (rhs1) == INTEGER_CST)
1492 rhs1 = fold_convert (type1, rhs1);
1493 if (TREE_CODE (rhs2) == INTEGER_CST)
1494 rhs2 = fold_convert (type2, rhs2);
1495
1496 gimple_assign_set_rhs1 (stmt, rhs1);
1497 gimple_assign_set_rhs2 (stmt, rhs2);
1390 gimple_assign_set_rhs_code (stmt, WIDEN_MULT_EXPR);1498 gimple_assign_set_rhs_code (stmt, WIDEN_MULT_EXPR);
1391 update_stmt (stmt);1499 update_stmt (stmt);
1392 return true;1500 return true;
@@ -1403,11 +1511,17 @@
1403 enum tree_code code)1511 enum tree_code code)
1404{1512{
1405 gimple rhs1_stmt = NULL, rhs2_stmt = NULL;1513 gimple rhs1_stmt = NULL, rhs2_stmt = NULL;
1406 tree type, type1, type2;1514 gimple conv1_stmt = NULL, conv2_stmt = NULL, conv_stmt;
1515 tree type, type1, type2, optype, tmp = NULL;
1407 tree lhs, rhs1, rhs2, mult_rhs1, mult_rhs2, add_rhs;1516 tree lhs, rhs1, rhs2, mult_rhs1, mult_rhs2, add_rhs;
1408 enum tree_code rhs1_code = ERROR_MARK, rhs2_code = ERROR_MARK;1517 enum tree_code rhs1_code = ERROR_MARK, rhs2_code = ERROR_MARK;
1409 optab this_optab;1518 optab this_optab;
1410 enum tree_code wmult_code;1519 enum tree_code wmult_code;
1520 enum insn_code handler;
1521 enum machine_mode to_mode, from_mode, actual_mode;
1522 location_t loc = gimple_location (stmt);
1523 int actual_precision;
1524 bool from_unsigned1, from_unsigned2;
14111525
1412 lhs = gimple_assign_lhs (stmt);1526 lhs = gimple_assign_lhs (stmt);
1413 type = TREE_TYPE (lhs);1527 type = TREE_TYPE (lhs);
@@ -1429,8 +1543,6 @@
1429 if (is_gimple_assign (rhs1_stmt))1543 if (is_gimple_assign (rhs1_stmt))
1430 rhs1_code = gimple_assign_rhs_code (rhs1_stmt);1544 rhs1_code = gimple_assign_rhs_code (rhs1_stmt);
1431 }1545 }
1432 else
1433 return false;
14341546
1435 if (TREE_CODE (rhs2) == SSA_NAME)1547 if (TREE_CODE (rhs2) == SSA_NAME)
1436 {1548 {
@@ -1438,57 +1550,160 @@
1438 if (is_gimple_assign (rhs2_stmt))1550 if (is_gimple_assign (rhs2_stmt))
1439 rhs2_code = gimple_assign_rhs_code (rhs2_stmt);1551 rhs2_code = gimple_assign_rhs_code (rhs2_stmt);
1440 }1552 }
1441 else1553
1442 return false;1554 /* Allow for one conversion statement between the multiply
14431555 and addition/subtraction statement. If there are more than
1444 if (code == PLUS_EXPR && rhs1_code == MULT_EXPR)1556 one conversions then we assume they would invalidate this
1445 {1557 transformation. If that's not the case then they should have
1446 if (!is_widening_mult_p (rhs1_stmt, &type1, &mult_rhs1,1558 been folded before now. */
1447 &type2, &mult_rhs2))1559 if (CONVERT_EXPR_CODE_P (rhs1_code))
1448 return false;1560 {
1449 add_rhs = rhs2;1561 conv1_stmt = rhs1_stmt;
1450 }1562 rhs1 = gimple_assign_rhs1 (rhs1_stmt);
1451 else if (rhs2_code == MULT_EXPR)1563 if (TREE_CODE (rhs1) == SSA_NAME)
1452 {1564 {
1453 if (!is_widening_mult_p (rhs2_stmt, &type1, &mult_rhs1,1565 rhs1_stmt = SSA_NAME_DEF_STMT (rhs1);
1454 &type2, &mult_rhs2))1566 if (is_gimple_assign (rhs1_stmt))
1455 return false;1567 rhs1_code = gimple_assign_rhs_code (rhs1_stmt);
1456 add_rhs = rhs1;1568 }
1457 }1569 else
1458 else if (code == PLUS_EXPR && rhs1_code == WIDEN_MULT_EXPR)1570 return false;
1459 {1571 }
1460 mult_rhs1 = gimple_assign_rhs1 (rhs1_stmt);1572 if (CONVERT_EXPR_CODE_P (rhs2_code))
1461 mult_rhs2 = gimple_assign_rhs2 (rhs1_stmt);1573 {
1462 type1 = TREE_TYPE (mult_rhs1);1574 conv2_stmt = rhs2_stmt;
1463 type2 = TREE_TYPE (mult_rhs2);1575 rhs2 = gimple_assign_rhs1 (rhs2_stmt);
1464 add_rhs = rhs2;1576 if (TREE_CODE (rhs2) == SSA_NAME)
1465 }1577 {
1466 else if (rhs2_code == WIDEN_MULT_EXPR)1578 rhs2_stmt = SSA_NAME_DEF_STMT (rhs2);
1467 {1579 if (is_gimple_assign (rhs2_stmt))
1468 mult_rhs1 = gimple_assign_rhs1 (rhs2_stmt);1580 rhs2_code = gimple_assign_rhs_code (rhs2_stmt);
1469 mult_rhs2 = gimple_assign_rhs2 (rhs2_stmt);1581 }
1470 type1 = TREE_TYPE (mult_rhs1);1582 else
1471 type2 = TREE_TYPE (mult_rhs2);1583 return false;
1472 add_rhs = rhs1;1584 }
1473 }1585
1474 else1586 /* If code is WIDEN_MULT_EXPR then it would seem unnecessary to call
1475 return false;1587 is_widening_mult_p, but we still need the rhs returns.
14761588
1477 if (TYPE_UNSIGNED (type1) != TYPE_UNSIGNED (type2))1589 It might also appear that it would be sufficient to use the existing
1478 return false;1590 operands of the widening multiply, but that would limit the choice of
1591 multiply-and-accumulate instructions. */
1592 if (code == PLUS_EXPR
1593 && (rhs1_code == MULT_EXPR || rhs1_code == WIDEN_MULT_EXPR))
1594 {
1595 if (!is_widening_mult_p (type, rhs1_stmt, &type1, &mult_rhs1,
1596 &type2, &mult_rhs2))
1597 return false;
1598 add_rhs = rhs2;
1599 conv_stmt = conv1_stmt;
1600 }
1601 else if (rhs2_code == MULT_EXPR || rhs2_code == WIDEN_MULT_EXPR)
1602 {
1603 if (!is_widening_mult_p (type, rhs2_stmt, &type1, &mult_rhs1,
1604 &type2, &mult_rhs2))
1605 return false;
1606 add_rhs = rhs1;
1607 conv_stmt = conv2_stmt;
1608 }
1609 else
1610 return false;
1611
1612 to_mode = TYPE_MODE (type);
1613 from_mode = TYPE_MODE (type1);
1614 from_unsigned1 = TYPE_UNSIGNED (type1);
1615 from_unsigned2 = TYPE_UNSIGNED (type2);
1616
1617 /* There's no such thing as a mixed sign madd yet, so use a wider mode. */
1618 if (from_unsigned1 != from_unsigned2)
1619 {
1620 /* We can use a signed multiply with unsigned types as long as
1621 there is a wider mode to use, or it is the smaller of the two
1622 types that is unsigned. Note that type1 >= type2, always. */
1623 if ((from_unsigned1
1624 && TYPE_PRECISION (type1) == GET_MODE_PRECISION (from_mode))
1625 || (from_unsigned2
1626 && TYPE_PRECISION (type2) == GET_MODE_PRECISION (from_mode)))
1627 {
1628 from_mode = GET_MODE_WIDER_MODE (from_mode);
1629 if (GET_MODE_SIZE (from_mode) >= GET_MODE_SIZE (to_mode))
1630 return false;
1631 }
1632
1633 from_unsigned1 = from_unsigned2 = false;
1634 }
1635
1636 /* If there was a conversion between the multiply and addition
1637 then we need to make sure it fits a multiply-and-accumulate.
1638 The should be a single mode change which does not change the
1639 value. */
1640 if (conv_stmt)
1641 {
1642 /* We use the original, unmodified data types for this. */
1643 tree from_type = TREE_TYPE (gimple_assign_rhs1 (conv_stmt));
1644 tree to_type = TREE_TYPE (gimple_assign_lhs (conv_stmt));
1645 int data_size = TYPE_PRECISION (type1) + TYPE_PRECISION (type2);
1646 bool is_unsigned = TYPE_UNSIGNED (type1) && TYPE_UNSIGNED (type2);
1647
1648 if (TYPE_PRECISION (from_type) > TYPE_PRECISION (to_type))
1649 {
1650 /* Conversion is a truncate. */
1651 if (TYPE_PRECISION (to_type) < data_size)
1652 return false;
1653 }
1654 else if (TYPE_PRECISION (from_type) < TYPE_PRECISION (to_type))
1655 {
1656 /* Conversion is an extend. Check it's the right sort. */
1657 if (TYPE_UNSIGNED (from_type) != is_unsigned
1658 && !(is_unsigned && TYPE_PRECISION (from_type) > data_size))
1659 return false;
1660 }
1661 /* else convert is a no-op for our purposes. */
1662 }
14791663
1480 /* Verify that the machine can perform a widening multiply1664 /* Verify that the machine can perform a widening multiply
1481 accumulate in this mode/signedness combination, otherwise1665 accumulate in this mode/signedness combination, otherwise
1482 this transformation is likely to pessimize code. */1666 this transformation is likely to pessimize code. */
1483 this_optab = optab_for_tree_code (wmult_code, type1, optab_default);1667 optype = build_nonstandard_integer_type (from_mode, from_unsigned1);
1484 if (optab_handler (this_optab, TYPE_MODE (type)) == CODE_FOR_nothing)1668 this_optab = optab_for_tree_code (wmult_code, optype, optab_default);
1669 handler = find_widening_optab_handler_and_mode (this_optab, to_mode,
1670 from_mode, 0, &actual_mode);
1671
1672 if (handler == CODE_FOR_nothing)
1485 return false;1673 return false;
14861674
1487 /* ??? May need some type verification here? */1675 /* Ensure that the inputs to the handler are in the correct precison
14881676 for the opcode. This will be the full mode size. */
1489 gimple_assign_set_rhs_with_ops_1 (gsi, wmult_code,1677 actual_precision = GET_MODE_PRECISION (actual_mode);
1490 fold_convert (type1, mult_rhs1),1678 if (actual_precision != TYPE_PRECISION (type1)
1491 fold_convert (type2, mult_rhs2),1679 || from_unsigned1 != TYPE_UNSIGNED (type1))
1680 {
1681 tmp = create_tmp_var (build_nonstandard_integer_type
1682 (actual_precision, from_unsigned1),
1683 NULL);
1684 mult_rhs1 = build_and_insert_cast (gsi, loc, tmp, mult_rhs1);
1685 }
1686 if (actual_precision != TYPE_PRECISION (type2)
1687 || from_unsigned2 != TYPE_UNSIGNED (type2))
1688 {
1689 if (!tmp || from_unsigned1 != from_unsigned2)
1690 tmp = create_tmp_var (build_nonstandard_integer_type
1691 (actual_precision, from_unsigned2),
1692 NULL);
1693 mult_rhs2 = build_and_insert_cast (gsi, loc, tmp, mult_rhs2);
1694 }
1695
1696 if (!useless_type_conversion_p (type, TREE_TYPE (add_rhs)))
1697 add_rhs = build_and_insert_cast (gsi, loc, create_tmp_var (type, NULL),
1698 add_rhs);
1699
1700 /* Handle constants. */
1701 if (TREE_CODE (mult_rhs1) == INTEGER_CST)
1702 rhs1 = fold_convert (type1, mult_rhs1);
1703 if (TREE_CODE (mult_rhs2) == INTEGER_CST)
1704 rhs2 = fold_convert (type2, mult_rhs2);
1705
1706 gimple_assign_set_rhs_with_ops_1 (gsi, wmult_code, mult_rhs1, mult_rhs2,
1492 add_rhs);1707 add_rhs);
1493 update_stmt (gsi_stmt (*gsi));1708 update_stmt (gsi_stmt (*gsi));
1494 return true;1709 return true;
@@ -1696,7 +1911,7 @@
1696 switch (code)1911 switch (code)
1697 {1912 {
1698 case MULT_EXPR:1913 case MULT_EXPR:
1699 if (!convert_mult_to_widen (stmt)1914 if (!convert_mult_to_widen (stmt, &gsi)
1700 && convert_mult_to_fma (stmt,1915 && convert_mult_to_fma (stmt,
1701 gimple_assign_rhs1 (stmt),1916 gimple_assign_rhs1 (stmt),
1702 gimple_assign_rhs2 (stmt)))1917 gimple_assign_rhs2 (stmt)))

Subscribers

People subscribed via source and target branches