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

Proposed by Andrew Stubbs
Status: Superseded
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
Michael Hope Pending
Review via email: mp+70577@code.launchpad.net

This proposal supersedes a proposal from 2011-07-27.

This proposal has been superseded by a proposal from 2011-08-11.

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 :

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 :
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 :
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 :

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 :

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 :

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

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 15:52:44 +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 15:52:44 +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 15:52:44 +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 15:52:44 +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 15:52:44 +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 15:52:44 +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 15:52:44 +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 15:52:44 +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 15:52:44 +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 15:52:44 +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 15:52:44 +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 15:52:44 +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 15:52:44 +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 15:52:44 +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 15:52:44 +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 15:52:44 +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 15:52:44 +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 15:52:44 +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 15:52:44 +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 15:52:44 +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