• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; This tests against a lowering error in a multiply instruction that produces
2; results in a low and high register.  This is usually lowered as a mul
3; instruction whose dest contains the low portion, and a FakeDef of the high
4; portion.  The problem is that if the high portion is unused (e.g. the multiply
5; is followed by a truncation), the FakeDef may be eliminated, and the register
6; allocator may assign the high register to a variable that is live across the
7; mul instruction.  This is incorrect because the mul instruction smashes the
8; register.
9
10; REQUIRES: allow_dump
11
12; RUN: %p2i --target x8632 -i %s --filetype=asm --args -O2 -asm-verbose \
13; RUN:   --split-local-vars=0 \
14; RUN:   --reg-use=eax,edx -reg-reserve | FileCheck --check-prefix=X8632 %s
15; RUN: %p2i --target arm32 -i %s --filetype=asm --args -O2 -asm-verbose \
16; RUN:   | FileCheck --check-prefix=ARM32 %s
17
18define internal i32 @mul(i64 %a, i64 %b, i32 %c) {
19  ; Force an early use of %c.
20  store i32 %c, i32* undef, align 1
21  %m = mul i64 %a, %b
22  %t = trunc i64 %m to i32
23  ; Make many uses of %c to give it high weight.
24  %t1 = add i32 %t, %c
25  %t2 = add i32 %t1, %c
26  %t3 = add i32 %t2, %c
27  ret i32 %t3
28}
29
30; For x8632, we want asm-verbose to print the stack offset assignment for lv$c
31; ("local variable 'c'") in the prolog, and then have at least one use of lv$c
32; in the body, i.e. don't register-allocate edx to %c.
33
34; X8632-LABEL: mul
35; X8632: lv$c =
36; X8632: lv$c
37
38; For arm32, the failure would manifest as a translation error - no register
39; being allocated to the high operand, so we just check for successful
40; translation.
41
42; ARM32-LABEL: mul
43