2012-07-20 3 views
2

gcc 인라인 asm 문에 문제가 있습니다. gcc는 결과가 상수라고 생각하는 것처럼 보입니다. I 생각해보기 : 피연산자 제약 조건을 올바르게 사용하고 있지만이 문제에 대한 두 번째 의견을 제시하고자합니다. 문제가 내 제약 조건을 사용하지 않는 경우 gcc 버그 보고서의 테스트 사례를 격리하려고 시도하지만 주변 코드의 미묘한 변경으로 인해 문제가 사라지기 때문에 어려울 수 있습니다.gcc 인라인 asm 문이 최적화되지 않음 - 잘못된 제약 조건?

문제의 인라인 어셈블리는 한 단어 제수에 의해 두 단어 배당 꽤 평범한 나머지입니다

static inline void 
ularith_div_2ul_ul_ul_r (unsigned long *r, unsigned long a1, 
       const unsigned long a2, const unsigned long b) 
{ 
    ASSERT(a2 < b); /* Or there will be quotient overflow */ 
    __asm__(
      "# ularith_div_2ul_ul_ul_r: divq %0 %1 %2 %3\n\t" 
      "divq %3" 
      : "+a" (a1), "=d" (*r) 
      : "1" (a2), "rm" (b) 
      : "cc"); 
} 

입니다. 입력의 상위 워드, a2 및 나머지 출력 * r은 "1"제약 조건에 의해 동일한 레지스터 % rdx에 연결됩니다. 그래서 상기 입력의 높은 단어, A2, 상수 1UL가

if (s == 1) 
    modpp[0].one = 0; 
else 
    ularith_div_2ul_ul_ul_r(&modpp[0].one, 0UL, 1UL, s); 

경우와 같이 주변의 코드에서

, ularith_div_2ul_ul_ul_r() 효과적으로 호출된다. 효과가 ularith_div_2ul_ul_ul_r() 호출의 결과는 정수 1 인 것으로 가정한다는 것이다

(earlier:) 
     xorl %r8d, %r8d  # cstore.863 
(then:) 
     cmpq $1, -208(%rbp) #, %sfp 
     movl $1, %eax  #, tmp841 
     movq %rsi, -184(%rbp)  # prephitmp.966, MEM[(struct __modulusredcul_t *)&modpp][0].invm 
     cmovne -208(%rbp), %rcx  # prephitmp.966,, %sfp, prephitmp.966 
     cmovne %rax, %r8  # cstore.863,, tmp841, cstore.863 
     movq %r8, -176(%rbp) # cstore.863, MEM[(struct __modulusredcul_t *)&modpp][0].one 

; 같은 GCC -S -fverbose_asm의 얻어진 ASM 출력 보인다 divq는 출력에 나타나지 않습니다.

다양한 변경으로 인해 문제가 사라졌습니다. 다른 컴파일러 플래그, 다른 코드 컨텍스트 또는 asm 블록 표시 __asm__ __volatile__ (...). 출력은 다음 올바르게 divq 명령이 포함되어

#APP 
     # ularith_div_2ul_ul_ul_r: divq %rax %rdx %rdx -208(%rbp)  # a1, tmp590, tmp590, %sfp 
     divq -208(%rbp) # %sfp 
#NO_APP 

그래서, 여기에 인라인 어셈블리들에 대한 내 질문 : 제가 제약 조건 뭔가 잘못을 했습니까?

답변

1

버그는 우분투 버전의 gcc에만 영향을줍니다. 주식 GNU gcc는 우리가 알 수있는 한 영향을받지 않습니다. 이 버그는 Ubuntu 런치 패드에보고되었으며 확인되었습니다 : Bug #1029454

관련 문제