avr-llvm / llvm

[MERGED UPSTREAM] AVR backend for the LLVM compiler library
220 stars 21 forks source link

Jump table lowering error #46

Closed 4ntoine closed 9 years ago

4ntoine commented 9 years ago
./clang -c -g -Os -Wall -ffunction-sections -fdata-sections -mmcu=atmega328p -DF_CPU=16000000L -MMD -DUSB_VID=null -DUSB_PID=null -DARDUINO=105 -I/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino -I/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/variants/standard -I/Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/avr/include --target=avr /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/wiring_analog.c -o /tmp/arduino_test1/wiring_analog.c.o
In file included from /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/wiring_analog.c:27:
In file included from /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/wiring_private.h:30:
/Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/avr/include/stdio.h:724:12: warning: 
      declaration of built-in function 'fprintf' requires inclusion of the header <stdio.h>
      [-Wbuiltin-requires-header]
extern int      fprintf(FILE *__stream, const char *__fmt, ...);
                ^
/Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/avr/include/stdio.h:875:12: warning: 
      declaration of built-in function 'vfscanf' requires inclusion of the header <stdio.h>
      [-Wbuiltin-requires-header]
extern int      vfscanf(FILE *__stream, const char *__fmt, va_list __ap);
                ^
/Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/avr/include/stdio.h:888:12: warning: 
      declaration of built-in function 'fscanf' requires inclusion of the header <stdio.h>
      [-Wbuiltin-requires-header]
extern int      fscanf(FILE *__stream, const char *__fmt, ...);
                ^
fatal error: error in backend: Cannot select: 0x7fd9618e0860: i16 = JumpTable<0> [ID=2]
In function: analogWrite
clang-3.7: error: clang frontend command failed with exit code 70 (use -v to see invocation)
clang version 3.7.0 (https://github.com/avr-llvm/clang.git 98cf874e96493bec6b96f3a8339f11150f4f198b) (llvm/llvm a411aba0af80de3090448dc3e56f39d8627a6647)
Target: avr
Thread model: posix
clang-3.7: note: diagnostic msg: PLEASE submit a bug report to http://llvm.org/bugs/ and include the crash backtrace, preprocessed source, and associated run script.
clang-3.7: note: diagnostic msg: 
********************

PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:
Preprocessed source(s) and associated run script(s) are located at:
clang-3.7: note: diagnostic msg: /var/folders/64/fwfkm1k51zbd4_c5lwpsbljh0000gn/T/wiring_analog-ef1cd4.c
clang-3.7: note: diagnostic msg: /var/folders/64/fwfkm1k51zbd4_c5lwpsbljh0000gn/T/wiring_analog-ef1cd4.sh
clang-3.7: note: diagnostic msg: 
4ntoine commented 9 years ago

wiring_analog.c:

/*
  wiring_analog.c - analog input and output
  Part of Arduino - http://www.arduino.cc/

  Copyright (c) 2005-2006 David A. Mellis

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General
  Public License along with this library; if not, write to the
  Free Software Foundation, Inc., 59 Temple Place, Suite 330,
  Boston, MA  02111-1307  USA

  Modified 28 September 2010 by Mark Sproul

  $Id: wiring.c 248 2007-02-03 15:36:30Z mellis $
*/

#include "wiring_private.h"
#include "pins_arduino.h"

uint8_t analog_reference = DEFAULT;

void analogReference(uint8_t mode)
{
    // can't actually set the register here because the default setting
    // will connect AVCC and the AREF pin, which would cause a short if
    // there's something connected to AREF.
    analog_reference = mode;
}

int analogRead(uint8_t pin)
{
    uint8_t low, high;

#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
    if (pin >= 54) pin -= 54; // allow for channel or pin numbers
#elif defined(__AVR_ATmega32U4__)
    if (pin >= 18) pin -= 18; // allow for channel or pin numbers
#elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega644__) || defined(__AVR_ATmega644A__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__)
    if (pin >= 24) pin -= 24; // allow for channel or pin numbers
#elif defined(analogPinToChannel) && (defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__))
    pin = analogPinToChannel(pin);
#else
    if (pin >= 14) pin -= 14; // allow for channel or pin numbers
#endif

#if defined(__AVR_ATmega32U4__)
    pin = analogPinToChannel(pin);
    ADCSRB = (ADCSRB & ~(1 << MUX5)) | (((pin >> 3) & 0x01) << MUX5);
#elif defined(ADCSRB) && defined(MUX5)
    // the MUX5 bit of ADCSRB selects whether we're reading from channels
    // 0 to 7 (MUX5 low) or 8 to 15 (MUX5 high).
    ADCSRB = (ADCSRB & ~(1 << MUX5)) | (((pin >> 3) & 0x01) << MUX5);
#endif

    // set the analog reference (high two bits of ADMUX) and select the
    // channel (low 4 bits).  this also sets ADLAR (left-adjust result)
    // to 0 (the default).
#if defined(ADMUX)
    ADMUX = (analog_reference << 6) | (pin & 0x07);
#endif

    // without a delay, we seem to read from the wrong channel
    //delay(1);

#if defined(ADCSRA) && defined(ADCL)
    // start the conversion
    sbi(ADCSRA, ADSC);

    // ADSC is cleared when the conversion finishes
    while (bit_is_set(ADCSRA, ADSC));

    // we have to read ADCL first; doing so locks both ADCL
    // and ADCH until ADCH is read.  reading ADCL second would
    // cause the results of each conversion to be discarded,
    // as ADCL and ADCH would be locked when it completed.
    low  = ADCL;
    high = ADCH;
#else
    // we dont have an ADC, return 0
    low  = 0;
    high = 0;
#endif

    // combine the two bytes
    return (high << 8) | low;
}

// Right now, PWM output only works on the pins with
// hardware support.  These are defined in the appropriate
// pins_*.c file.  For the rest of the pins, we default
// to digital output.
void analogWrite(uint8_t pin, int val)
{
    // We need to make sure the PWM output is enabled for those pins
    // that support it, as we turn it off when digitally reading or
    // writing with them.  Also, make sure the pin is in output mode
    // for consistenty with Wiring, which doesn't require a pinMode
    // call for the analog output pins.
    pinMode(pin, OUTPUT);
    if (val == 0)
    {
        digitalWrite(pin, LOW);
    }
    else if (val == 255)
    {
        digitalWrite(pin, HIGH);
    }
    else
    {
        switch(digitalPinToTimer(pin))
        {
            // XXX fix needed for atmega8
            #if defined(TCCR0) && defined(COM00) && !defined(__AVR_ATmega8__)
            case TIMER0A:
                // connect pwm to pin on timer 0
                sbi(TCCR0, COM00);
                OCR0 = val; // set pwm duty
                break;
            #endif

            #if defined(TCCR0A) && defined(COM0A1)
            case TIMER0A:
                // connect pwm to pin on timer 0, channel A
                sbi(TCCR0A, COM0A1);
                OCR0A = val; // set pwm duty
                break;
            #endif

            #if defined(TCCR0A) && defined(COM0B1)
            case TIMER0B:
                // connect pwm to pin on timer 0, channel B
                sbi(TCCR0A, COM0B1);
                OCR0B = val; // set pwm duty
                break;
            #endif

            #if defined(TCCR1A) && defined(COM1A1)
            case TIMER1A:
                // connect pwm to pin on timer 1, channel A
                sbi(TCCR1A, COM1A1);
                OCR1A = val; // set pwm duty
                break;
            #endif

            #if defined(TCCR1A) && defined(COM1B1)
            case TIMER1B:
                // connect pwm to pin on timer 1, channel B
                sbi(TCCR1A, COM1B1);
                OCR1B = val; // set pwm duty
                break;
            #endif

            #if defined(TCCR2) && defined(COM21)
            case TIMER2:
                // connect pwm to pin on timer 2
                sbi(TCCR2, COM21);
                OCR2 = val; // set pwm duty
                break;
            #endif

            #if defined(TCCR2A) && defined(COM2A1)
            case TIMER2A:
                // connect pwm to pin on timer 2, channel A
                sbi(TCCR2A, COM2A1);
                OCR2A = val; // set pwm duty
                break;
            #endif

            #if defined(TCCR2A) && defined(COM2B1)
            case TIMER2B:
                // connect pwm to pin on timer 2, channel B
                sbi(TCCR2A, COM2B1);
                OCR2B = val; // set pwm duty
                break;
            #endif

            #if defined(TCCR3A) && defined(COM3A1)
            case TIMER3A:
                // connect pwm to pin on timer 3, channel A
                sbi(TCCR3A, COM3A1);
                OCR3A = val; // set pwm duty
                break;
            #endif

            #if defined(TCCR3A) && defined(COM3B1)
            case TIMER3B:
                // connect pwm to pin on timer 3, channel B
                sbi(TCCR3A, COM3B1);
                OCR3B = val; // set pwm duty
                break;
            #endif

            #if defined(TCCR3A) && defined(COM3C1)
            case TIMER3C:
                // connect pwm to pin on timer 3, channel C
                sbi(TCCR3A, COM3C1);
                OCR3C = val; // set pwm duty
                break;
            #endif

            #if defined(TCCR4A)
            case TIMER4A:
                //connect pwm to pin on timer 4, channel A
                sbi(TCCR4A, COM4A1);
                #if defined(COM4A0)     // only used on 32U4
                cbi(TCCR4A, COM4A0);
                #endif
                OCR4A = val;    // set pwm duty
                break;
            #endif

            #if defined(TCCR4A) && defined(COM4B1)
            case TIMER4B:
                // connect pwm to pin on timer 4, channel B
                sbi(TCCR4A, COM4B1);
                OCR4B = val; // set pwm duty
                break;
            #endif

            #if defined(TCCR4A) && defined(COM4C1)
            case TIMER4C:
                // connect pwm to pin on timer 4, channel C
                sbi(TCCR4A, COM4C1);
                OCR4C = val; // set pwm duty
                break;
            #endif

            #if defined(TCCR4C) && defined(COM4D1)
            case TIMER4D:               
                // connect pwm to pin on timer 4, channel D
                sbi(TCCR4C, COM4D1);
                #if defined(COM4D0)     // only used on 32U4
                cbi(TCCR4C, COM4D0);
                #endif
                OCR4D = val;    // set pwm duty
                break;
            #endif

            #if defined(TCCR5A) && defined(COM5A1)
            case TIMER5A:
                // connect pwm to pin on timer 5, channel A
                sbi(TCCR5A, COM5A1);
                OCR5A = val; // set pwm duty
                break;
            #endif

            #if defined(TCCR5A) && defined(COM5B1)
            case TIMER5B:
                // connect pwm to pin on timer 5, channel B
                sbi(TCCR5A, COM5B1);
                OCR5B = val; // set pwm duty
                break;
            #endif

            #if defined(TCCR5A) && defined(COM5C1)
            case TIMER5C:
                // connect pwm to pin on timer 5, channel C
                sbi(TCCR5A, COM5C1);
                OCR5C = val; // set pwm duty
                break;
            #endif

            case NOT_ON_TIMER:
            default:
                if (val < 128) {
                    digitalWrite(pin, LOW);
                } else {
                    digitalWrite(pin, HIGH);
                }
        }
    }
}
4ntoine commented 9 years ago

EDIT (by @dylanmckay): this case is fixed in a29503819340b48e537ba6ae7e2848ec91f4b020.

One more case:

MBA-Anton:bin asmirnov$ ./clang -c -g -Os -Wall -ffunction-sections -fdata-sections -mmcu=atmega328p -DF_CPU=16000000L -MMD -DUSB_VID=null -DUSB_PID=null -DARDUINO=105 -I/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino -I/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/variants/standard -I/Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/avr/include --target=avr /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/Stream.cpp -o /tmp/arduino_test1/Stream.cpp.o
In file included from /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/Stream.cpp:23:
In file included from /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/Arduino.h:193:
In file included from /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/HardwareSerial.h:28:
In file included from /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/Stream.h:26:
In file included from /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/Print.h:27:
In file included from /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/Printable.h:23:
/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/new.h:10:8: warning: 
      'operator new' is missing exception specification 'throw(std::bad_alloc)'
void * operator new(size_t size);
       ^
                                 throw(std::bad_alloc)
/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/new.h:11:8: warning: 
      'operator new[]' is missing exception specification 'throw(std::bad_alloc)'
void * operator new[](size_t size);
       ^
                                   throw(std::bad_alloc)
/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/new.h:12:6: warning: 
      'operator delete' is missing exception specification 'throw()'
void operator delete(void * ptr);
     ^
                                 throw()
/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/new.h:13:6: warning: 
      'operator delete[]' is missing exception specification 'throw()'
void operator delete[](void * ptr);
     ^
                                   throw()
fatal error: error in backend: Cannot select: 0x7fdb83266260: glue = AVRISD::TST 0x7fdb832667b0 [ORD=9] [ID=32]
      dbg:/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/Stream.cpp:36:9
  0x7fdb832667b0: i8 = truncate 0x7fdb84031d50 [ORD=9] [ID=31] dbg:/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/Stream.cpp:36:9
    0x7fdb84031d50: i16 = AVRISD::LSR 0x7fdb84031c40 [ORD=9] [ID=30] dbg:/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/Stream.cpp:36:9
      0x7fdb84031c40: i16 = AVRISD::LSR 0x7fdb84031b30 [ORD=9] [ID=29] dbg:/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/Stream.cpp:36:9
        0x7fdb84031b30: i16 = AVRISD::LSR 0x7fdb84031a20 [ORD=9] [ID=28] dbg:/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/Stream.cpp:36:9
          0x7fdb84031a20: i16 = AVRISD::LSR 0x7fdb84031910 [ORD=9] [ID=27] dbg:/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/Stream.cpp:36:9
            0x7fdb84031910: i16 = AVRISD::LSR 0x7fdb84031800 [ORD=9] [ID=26] dbg:/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/Stream.cpp:36:9
              0x7fdb84031800: i16 = AVRISD::LSR 0x7fdb831db240 [ORD=9] [ID=25] dbg:/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/Stream.cpp:36:9
                0x7fdb831db240: i16 = AVRISD::LSR 0x7fdb831db020 [ORD=9] [ID=23] dbg:/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/Stream.cpp:36:9
                  0x7fdb831db020: i16 = AVRISD::LSR 0x7fdb83266480 [ORD=9] [ID=21] dbg:/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/Stream.cpp:36:9

In function: _ZN6Stream9timedReadEv
clang-3.7: error: clang frontend command failed with exit code 70 (use -v to see invocation)
clang version 3.7.0 (https://github.com/avr-llvm/clang.git 98cf874e96493bec6b96f3a8339f11150f4f198b) (llvm/llvm a411aba0af80de3090448dc3e56f39d8627a6647)
Target: avr
Thread model: posix
clang-3.7: note: diagnostic msg: PLEASE submit a bug report to http://llvm.org/bugs/ and include the crash backtrace, preprocessed source, and associated run script.
clang-3.7: note: diagnostic msg: 
********************

PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:
Preprocessed source(s) and associated run script(s) are located at:
clang-3.7: note: diagnostic msg: /var/folders/64/fwfkm1k51zbd4_c5lwpsbljh0000gn/T/Stream-81ac6d.cpp
clang-3.7: note: diagnostic msg: /var/folders/64/fwfkm1k51zbd4_c5lwpsbljh0000gn/T/Stream-81ac6d.sh
clang-3.7: note: diagnostic msg: 

********************
4ntoine commented 9 years ago

clang-3.7: note: diagnostic msg: /var/folders/64/fwfkm1k51zbd4_c5lwpsbljh0000gn/T/Stream-81ac6d.cpp clang-3.7: note: diagnostic msg: /var/folders/64/fwfkm1k51zbd4_c5lwpsbljh0000gn/T/Stream-81ac6d.sh:

download here: http://dropmefiles.com/juTT4 within 14 days

4ntoine commented 9 years ago

EDIT (@dylanmckay): this case is fixed in a29503819340b48e537ba6ae7e2848ec91f4b020.

one more case:

MBA-Anton:bin asmirnov$ ./clang -c -g -Os -Wall -ffunction-sections -fdata-sections -mmcu=atmega328p -DF_CPU=16000000L -MMD -DUSB_VID=null -DUSB_PID=null -DARDUINO=105 -I/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino -I/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/variants/standard -I/Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/avr/include --target=avr /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/Tone.cpp -o /tmp/arduino_test1/Tone.cpp.o
In file included from /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/Tone.cpp:37:
In file included from /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/Arduino.h:193:
In file included from /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/HardwareSerial.h:28:
In file included from /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/Stream.h:26:
In file included from /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/Print.h:27:
In file included from /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/Printable.h:23:
/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/new.h:10:8: warning: 
      'operator new' is missing exception specification 'throw(std::bad_alloc)'
void * operator new(size_t size);
       ^
                                 throw(std::bad_alloc)
/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/new.h:11:8: warning: 
      'operator new[]' is missing exception specification 'throw(std::bad_alloc)'
void * operator new[](size_t size);
       ^
                                   throw(std::bad_alloc)
/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/new.h:12:6: warning: 
      'operator delete' is missing exception specification 'throw()'
void operator delete(void * ptr);
     ^
                                 throw()
/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/new.h:13:6: warning: 
      'operator delete[]' is missing exception specification 'throw()'
void operator delete[](void * ptr);
     ^
                                   throw()
fatal error: error in backend: Cannot select: 0x7fd0db9d6b70: glue = AVRISD::TST 0x7fd0db9d94c0 [ORD=5] [ID=7]
      dbg:/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/Tone.cpp:250:7
  0x7fd0db9d94c0: i8,ch = CopyFromReg 0x7fd0db4837b0, 0x7fd0db9de350 [ORD=3] [ID=6] dbg:/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/Tone.cpp:250:7
    0x7fd0db9de350: i8 = Register %vreg3 [ID=1]
In function: _Z4tonehjm
clang-3.7: error: clang frontend command failed with exit code 70 (use -v to see invocation)
clang version 3.7.0 (https://github.com/avr-llvm/clang.git 98cf874e96493bec6b96f3a8339f11150f4f198b) (llvm/llvm a411aba0af80de3090448dc3e56f39d8627a6647)
Target: avr
Thread model: posix
clang-3.7: note: diagnostic msg: PLEASE submit a bug report to http://llvm.org/bugs/ and include the crash backtrace, preprocessed source, and associated run script.
clang-3.7: note: diagnostic msg: 
********************

PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:
Preprocessed source(s) and associated run script(s) are located at:
clang-3.7: note: diagnostic msg: /var/folders/64/fwfkm1k51zbd4_c5lwpsbljh0000gn/T/Tone-554ef3.cpp
clang-3.7: note: diagnostic msg: /var/folders/64/fwfkm1k51zbd4_c5lwpsbljh0000gn/T/Tone-554ef3.sh
clang-3.7: note: diagnostic msg: 

********************
4ntoine commented 9 years ago

files to test: http://dropmefiles.com/EkDYY

dylanmckay commented 9 years ago

The AVR backend does not support jump tables yet. That is probably the root of this problem.

dylanmckay commented 9 years ago

It looks like you have two different bugs from your three test cases. One jump table instruction selection error, and two TST Rd related instruction selection errors.

dylanmckay commented 9 years ago

None of the bugs present in this issue exist anymore.