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