* [PATCH] Orion NAND: Make dword load asm volatile to avoid GCC optimizing it away @ 2009-07-14 14:41 Simon Kagstrom 2009-07-14 16:40 ` Nicolas Pitre 0 siblings, 1 reply; 7+ messages in thread From: Simon Kagstrom @ 2009-07-14 14:41 UTC (permalink / raw) To: linux-mtd GCC 4.3.3 happily removes the dword load instruction in orion_nand_read_buf. This patch makes the inline assembly volatile to avoid this situation. Signed-off-by: Simon Kagstrom <simon.kagstrom@netinsight.net> --- drivers/mtd/nand/orion_nand.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/mtd/nand/orion_nand.c b/drivers/mtd/nand/orion_nand.c index 7ad9722..3f9b113 100644 --- a/drivers/mtd/nand/orion_nand.c +++ b/drivers/mtd/nand/orion_nand.c @@ -61,7 +61,7 @@ static void orion_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) buf64 = (uint64_t *)buf; while (i < len/8) { uint64_t x; - asm ("ldrd\t%0, [%1]" : "=r" (x) : "r" (io_base)); + asm volatile ("ldrd\t%0, [%1]" : "=r" (x) : "r" (io_base)); buf64[i++] = x; } i *= 8; -- 1.6.0.4 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH] Orion NAND: Make dword load asm volatile to avoid GCC optimizing it away 2009-07-14 14:41 [PATCH] Orion NAND: Make dword load asm volatile to avoid GCC optimizing it away Simon Kagstrom @ 2009-07-14 16:40 ` Nicolas Pitre 2009-08-19 7:45 ` Simon Kagstrom 0 siblings, 1 reply; 7+ messages in thread From: Nicolas Pitre @ 2009-07-14 16:40 UTC (permalink / raw) To: Simon Kagstrom; +Cc: linux-mtd On Tue, 14 Jul 2009, Simon Kagstrom wrote: > GCC 4.3.3 happily removes the dword load instruction in > orion_nand_read_buf. This patch makes the inline assembly volatile to > avoid this situation. If GCC does optimize away this inline asm then this is a serious GCC bug. The inline asm uses an output operand for which a dependency exists on the very next line. If I were you I'd try to find a non broken GCC version instead. > Signed-off-by: Simon Kagstrom <simon.kagstrom@netinsight.net> > --- > drivers/mtd/nand/orion_nand.c | 2 +- > 1 files changed, 1 insertions(+), 1 deletions(-) > > diff --git a/drivers/mtd/nand/orion_nand.c b/drivers/mtd/nand/orion_nand.c > index 7ad9722..3f9b113 100644 > --- a/drivers/mtd/nand/orion_nand.c > +++ b/drivers/mtd/nand/orion_nand.c > @@ -61,7 +61,7 @@ static void orion_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) > buf64 = (uint64_t *)buf; > while (i < len/8) { > uint64_t x; > - asm ("ldrd\t%0, [%1]" : "=r" (x) : "r" (io_base)); > + asm volatile ("ldrd\t%0, [%1]" : "=r" (x) : "r" (io_base)); > buf64[i++] = x; > } > i *= 8; > -- > 1.6.0.4 > > > ______________________________________________________ > Linux MTD discussion mailing list > http://lists.infradead.org/mailman/listinfo/linux-mtd/ > ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] Orion NAND: Make dword load asm volatile to avoid GCC optimizing it away 2009-07-14 16:40 ` Nicolas Pitre @ 2009-08-19 7:45 ` Simon Kagstrom 2009-08-19 14:47 ` Nicolas Pitre 0 siblings, 1 reply; 7+ messages in thread From: Simon Kagstrom @ 2009-08-19 7:45 UTC (permalink / raw) To: Nicolas Pitre; +Cc: linux-mtd On Tue, 14 Jul 2009 12:40:33 -0400 (EDT) Nicolas Pitre <nico@cam.org> wrote: > On Tue, 14 Jul 2009, Simon Kagstrom wrote: > > > GCC 4.3.3 happily removes the dword load instruction in > > orion_nand_read_buf. This patch makes the inline assembly volatile to > > avoid this situation. > > If GCC does optimize away this inline asm then this is a serious GCC > bug. The inline asm uses an output operand for which a dependency > exists on the very next line. I've been away on vacation, sorry for not replying until now. Anyway, I spoke to the GCC people at gcc-help, and they insist that the inlined assembly is wrong. The problem is that GCC doesn't infer from the instruction that it accesses memory, and it can thereby move it out of the loop. So here comes an updated patch. // Simon -- Orion NAND: Clobber memory to make sure that GCC does not move ldrd GCC 4.3.3 happily removes the dword load instruction in orion_nand_read_buf. This patch clobbers memory, and makes the instruction volatile to avoid the issue. I've discussed this at gcc-help, refer to the thread at http://gcc.gnu.org/ml/gcc-help/2009-08/msg00187.html Signed-off-by: Simon Kagstrom <simon.kagstrom@netinsight.net> --- drivers/mtd/nand/orion_nand.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/mtd/nand/orion_nand.c b/drivers/mtd/nand/orion_nand.c index 7ad9722..845f9a9 100644 --- a/drivers/mtd/nand/orion_nand.c +++ b/drivers/mtd/nand/orion_nand.c @@ -61,7 +61,7 @@ static void orion_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) buf64 = (uint64_t *)buf; while (i < len/8) { uint64_t x; - asm ("ldrd\t%0, [%1]" : "=r" (x) : "r" (io_base)); + asm volatile ("ldrd\t%0, [%1]" : "=&r" (x) : "r" (io_base) : "memory"); buf64[i++] = x; } i *= 8; -- 1.6.0.4 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH] Orion NAND: Make dword load asm volatile to avoid GCC optimizing it away 2009-08-19 7:45 ` Simon Kagstrom @ 2009-08-19 14:47 ` Nicolas Pitre 2009-08-20 7:19 ` Simon Kagstrom 0 siblings, 1 reply; 7+ messages in thread From: Nicolas Pitre @ 2009-08-19 14:47 UTC (permalink / raw) To: Simon Kagstrom; +Cc: linux-mtd On Wed, 19 Aug 2009, Simon Kagstrom wrote: > On Tue, 14 Jul 2009 12:40:33 -0400 (EDT) > Nicolas Pitre <nico@cam.org> wrote: > > > On Tue, 14 Jul 2009, Simon Kagstrom wrote: > > > > > GCC 4.3.3 happily removes the dword load instruction in > > > orion_nand_read_buf. This patch makes the inline assembly volatile to > > > avoid this situation. > > > > If GCC does optimize away this inline asm then this is a serious GCC > > bug. The inline asm uses an output operand for which a dependency > > exists on the very next line. > > I've been away on vacation, sorry for not replying until now. > > Anyway, I spoke to the GCC people at gcc-help, and they insist that the > inlined assembly is wrong. The problem is that GCC doesn't infer from > the instruction that it accesses memory, and it can thereby move it out > of the loop. Oh! OK. That's different though. In your initial report you said that the inline asm was _removed_. I can understand why it might be factored out of the loop though, but it cannot be removed entirely. > So here comes an updated patch. > > // Simon > -- > Orion NAND: Clobber memory to make sure that GCC does not move ldrd > > GCC 4.3.3 happily removes the dword load instruction in > orion_nand_read_buf. This patch clobbers memory, and makes the > instruction volatile to avoid the issue. I've discussed this at > gcc-help, refer to the thread at > > http://gcc.gnu.org/ml/gcc-help/2009-08/msg00187.html > > Signed-off-by: Simon Kagstrom <simon.kagstrom@netinsight.net> > --- > drivers/mtd/nand/orion_nand.c | 2 +- > 1 files changed, 1 insertions(+), 1 deletions(-) > > diff --git a/drivers/mtd/nand/orion_nand.c b/drivers/mtd/nand/orion_nand.c > index 7ad9722..845f9a9 100644 > --- a/drivers/mtd/nand/orion_nand.c > +++ b/drivers/mtd/nand/orion_nand.c > @@ -61,7 +61,7 @@ static void orion_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) > buf64 = (uint64_t *)buf; > while (i < len/8) { > uint64_t x; > - asm ("ldrd\t%0, [%1]" : "=r" (x) : "r" (io_base)); > + asm volatile ("ldrd\t%0, [%1]" : "=&r" (x) : "r" (io_base) : "memory"); I think that the early clobber buys you nothing, and the memory clobber is way overkill here. The volatile ought to be all that is needed. Can you confirm that only the addition of volatile makes the code OK? My gcc version is 4.3.2 and that makes no difference what so ever as the code as is produces the correct result already in my case. Nicolas ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] Orion NAND: Make dword load asm volatile to avoid GCC optimizing it away 2009-08-19 14:47 ` Nicolas Pitre @ 2009-08-20 7:19 ` Simon Kagstrom 2009-08-20 16:14 ` Nicolas Pitre 0 siblings, 1 reply; 7+ messages in thread From: Simon Kagstrom @ 2009-08-20 7:19 UTC (permalink / raw) To: Nicolas Pitre; +Cc: linux-mtd On Wed, 19 Aug 2009 10:47:14 -0400 (EDT) Nicolas Pitre <nico@cam.org> wrote: > > Anyway, I spoke to the GCC people at gcc-help, and they insist that the > > inlined assembly is wrong. The problem is that GCC doesn't infer from > > the instruction that it accesses memory, and it can thereby move it out > > of the loop. > > Oh! OK. That's different though. In your initial report you said that > the inline asm was _removed_. I can understand why it might be factored > out of the loop though, but it cannot be removed entirely. Sorry, I'll be careful about wording in the future :-) > > - asm ("ldrd\t%0, [%1]" : "=r" (x) : "r" (io_base)); > > + asm volatile ("ldrd\t%0, [%1]" : "=&r" (x) : "r" (io_base) : "memory"); > > I think that the early clobber buys you nothing, and the memory clobber > is way overkill here. The volatile ought to be all that is needed. Can > you confirm that only the addition of volatile makes the code OK? My > gcc version is 4.3.2 and that makes no difference what so ever as the > code as is produces the correct result already in my case. Yes, it works fine with 4.3.3 and 4.4.1 with this change. So the updated patch can be found below. I belive the early clobber should be there though, since (from the ARM architecture reference manual): If <addressing_mode> performs base register write-back and the base register <Rn> is one of the two destination registers of the instruction, the results are UNPREDICTABLE. it works fine without the early clobber as well, but I'd feel more safe having it in. // Simon -- Orion NAND: Make asm volatile avoid GCC pushing ldrd out of the loop GCC 4.3.3 and 4.4.1 happily moves the dword load instruction out of the loop in orion_nand_read_buf. This patch makes the instruction volatile to avoid the issue. I've discussed this at gcc-help, refer to the thread at http://gcc.gnu.org/ml/gcc-help/2009-08/msg00187.html The early clobber is added to avoid the destination registers and the source register overlapping. Signed-off-by: Simon Kagstrom <simon.kagstrom@netinsight.net> --- drivers/mtd/nand/orion_nand.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/mtd/nand/orion_nand.c b/drivers/mtd/nand/orion_nand.c index 7ad9722..0d9d4bc 100644 --- a/drivers/mtd/nand/orion_nand.c +++ b/drivers/mtd/nand/orion_nand.c @@ -61,7 +61,7 @@ static void orion_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) buf64 = (uint64_t *)buf; while (i < len/8) { uint64_t x; - asm ("ldrd\t%0, [%1]" : "=r" (x) : "r" (io_base)); + asm volatile ("ldrd\t%0, [%1]" : "=&r" (x) : "r" (io_base)); buf64[i++] = x; } i *= 8; -- 1.6.0.4 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH] Orion NAND: Make dword load asm volatile to avoid GCC optimizing it away 2009-08-20 7:19 ` Simon Kagstrom @ 2009-08-20 16:14 ` Nicolas Pitre 2009-08-21 6:07 ` Simon Kagstrom 0 siblings, 1 reply; 7+ messages in thread From: Nicolas Pitre @ 2009-08-20 16:14 UTC (permalink / raw) To: Simon Kagstrom; +Cc: linux-mtd On Thu, 20 Aug 2009, Simon Kagstrom wrote: > On Wed, 19 Aug 2009 10:47:14 -0400 (EDT) > Nicolas Pitre <nico@cam.org> wrote: > > > I think that the early clobber buys you nothing, and the memory clobber > > is way overkill here. The volatile ought to be all that is needed. Can > > you confirm that only the addition of volatile makes the code OK? My > > gcc version is 4.3.2 and that makes no difference what so ever as the > > code as is produces the correct result already in my case. > > Yes, it works fine with 4.3.3 and 4.4.1 with this change. So the > updated patch can be found below. I belive the early clobber should be > there though, since (from the ARM architecture reference manual): > > If <addressing_mode> performs base register write-back and the base > register <Rn> is one of the two destination registers of the > instruction, the results are UNPREDICTABLE. > > it works fine without the early clobber as well, but I'd feel more safe > having it in. But this isn't the case here. We don't perform any writeback. You get a writeback when you have an addressing mode of the form: insn rd, [rn, rm]! insn rd, [rn, #off]! insn rd, [rn], #off but not with: insn rd, [rn, #off] Etc. Still the early clobber shouldn't have any adverse effect either, unlike the memory clobber. Acked-by: Nicolas Pitre <nico@marvell.com> Unless the MTD guys are going to pick this patch and push it to Linus soon I'll carry it in the Orion git repo. > > // Simon > -- > Orion NAND: Make asm volatile avoid GCC pushing ldrd out of the loop > > GCC 4.3.3 and 4.4.1 happily moves the dword load instruction out of the > loop in orion_nand_read_buf. This patch makes the instruction volatile > to avoid the issue. I've discussed this at gcc-help, refer to the thread > at > > http://gcc.gnu.org/ml/gcc-help/2009-08/msg00187.html > > The early clobber is added to avoid the destination registers and the > source register overlapping. > > Signed-off-by: Simon Kagstrom <simon.kagstrom@netinsight.net> > --- > drivers/mtd/nand/orion_nand.c | 2 +- > 1 files changed, 1 insertions(+), 1 deletions(-) > > diff --git a/drivers/mtd/nand/orion_nand.c b/drivers/mtd/nand/orion_nand.c > index 7ad9722..0d9d4bc 100644 > --- a/drivers/mtd/nand/orion_nand.c > +++ b/drivers/mtd/nand/orion_nand.c > @@ -61,7 +61,7 @@ static void orion_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) > buf64 = (uint64_t *)buf; > while (i < len/8) { > uint64_t x; > - asm ("ldrd\t%0, [%1]" : "=r" (x) : "r" (io_base)); > + asm volatile ("ldrd\t%0, [%1]" : "=&r" (x) : "r" (io_base)); > buf64[i++] = x; > } > i *= 8; > -- > 1.6.0.4 > ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] Orion NAND: Make dword load asm volatile to avoid GCC optimizing it away 2009-08-20 16:14 ` Nicolas Pitre @ 2009-08-21 6:07 ` Simon Kagstrom 0 siblings, 0 replies; 7+ messages in thread From: Simon Kagstrom @ 2009-08-21 6:07 UTC (permalink / raw) To: Nicolas Pitre; +Cc: linux-mtd On Thu, 20 Aug 2009 12:14:47 -0400 (EDT) Nicolas Pitre <nico@cam.org> wrote: > > Yes, it works fine with 4.3.3 and 4.4.1 with this change. So the > > updated patch can be found below. I belive the early clobber should be > > there though, since (from the ARM architecture reference manual): > > > > If <addressing_mode> performs base register write-back and the base > > register <Rn> is one of the two destination registers of the > > instruction, the results are UNPREDICTABLE. > > > > it works fine without the early clobber as well, but I'd feel more safe > > having it in. > > But this isn't the case here. We don't perform any writeback. > You get a writeback when you have an addressing mode of the form: > > insn rd, [rn, rm]! > insn rd, [rn, #off]! > insn rd, [rn], #off > > but not with: > > insn rd, [rn, #off] OK, I'm still a beginner on the ARM architecture, so thanks for the explanation! > Still the early clobber shouldn't have any adverse effect either, unlike > the memory clobber. > > Acked-by: Nicolas Pitre <nico@marvell.com> > > Unless the MTD guys are going to pick this patch and push it to Linus > soon I'll carry it in the Orion git repo. Great, thanks! // Simon ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2009-08-21 6:08 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2009-07-14 14:41 [PATCH] Orion NAND: Make dword load asm volatile to avoid GCC optimizing it away Simon Kagstrom 2009-07-14 16:40 ` Nicolas Pitre 2009-08-19 7:45 ` Simon Kagstrom 2009-08-19 14:47 ` Nicolas Pitre 2009-08-20 7:19 ` Simon Kagstrom 2009-08-20 16:14 ` Nicolas Pitre 2009-08-21 6:07 ` Simon Kagstrom
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox