llvm.org GIT mirror llvm / 3cfe010
Fix the remaining MUL8 and DIV8 to define AX instead of AL,AH. These instructions technically define AL,AH, but a trick in X86ISelDAGToDAG reads AX in order to avoid reading AH with a REX instruction. Fix PR6489. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@97742 91177308-0d34-0410-b5e6-96231b3b80d8 Jakob Stoklund Olesen 9 years ago
2 changed file(s) with 36 addition(s) and 8 deletion(s). Raw diff Collapse all Expand all
10491049 //
10501050
10511051 // Extra precision multiplication
1052 let Defs = [AL,AH,EFLAGS], Uses = [AL] in
1052
1053 // AL is really implied by AX, by the registers in Defs must match the
1054 // SDNode results (i8, i32).
1055 let Defs = [AL,EFLAGS,AX], Uses = [AL] in
10531056 def MUL8r : I<0xF6, MRM4r, (outs), (ins GR8:$src), "mul{b}\t$src",
10541057 // FIXME: Used for 8-bit mul, ignore result upper 8 bits.
10551058 // This probably ought to be moved to a def : Pat<> if the
10671070 "mul{l}\t$src",
10681071 []>; // EAX,EDX = EAX*GR32
10691072
1070 let Defs = [AL,AH,EFLAGS], Uses = [AL] in
1073 let Defs = [AL,EFLAGS,AX], Uses = [AL] in
10711074 def MUL8m : I<0xF6, MRM4m, (outs), (ins i8mem :$src),
10721075 "mul{b}\t$src",
10731076 // FIXME: Used for 8-bit mul, ignore result upper 8 bits.
10891092 }
10901093
10911094 let neverHasSideEffects = 1 in {
1092 let Defs = [AL,AH,EFLAGS], Uses = [AL] in
1095 let Defs = [AL,EFLAGS,AX], Uses = [AL] in
10931096 def IMUL8r : I<0xF6, MRM5r, (outs), (ins GR8:$src), "imul{b}\t$src", []>;
10941097 // AL,AH = AL*GR8
10951098 let Defs = [AX,DX,EFLAGS], Uses = [AX] in
10991102 def IMUL32r : I<0xF7, MRM5r, (outs), (ins GR32:$src), "imul{l}\t$src", []>;
11001103 // EAX,EDX = EAX*GR32
11011104 let mayLoad = 1 in {
1102 let Defs = [AL,AH,EFLAGS], Uses = [AL] in
1105 let Defs = [AL,EFLAGS,AX], Uses = [AL] in
11031106 def IMUL8m : I<0xF6, MRM5m, (outs), (ins i8mem :$src),
11041107 "imul{b}\t$src", []>; // AL,AH = AL*[mem8]
11051108 let Defs = [AX,DX,EFLAGS], Uses = [AX] in
11121115 } // neverHasSideEffects
11131116
11141117 // unsigned division/remainder
1115 let Defs = [AX,EFLAGS], Uses = [AX] in
1118 let Defs = [AL,EFLAGS,AX], Uses = [AX] in
11161119 def DIV8r : I<0xF6, MRM6r, (outs), (ins GR8:$src), // AX/r8 = AL,AH
11171120 "div{b}\t$src", []>;
11181121 let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in
11221125 def DIV32r : I<0xF7, MRM6r, (outs), (ins GR32:$src), // EDX:EAX/r32 = EAX,EDX
11231126 "div{l}\t$src", []>;
11241127 let mayLoad = 1 in {
1125 let Defs = [AL,AH,EFLAGS], Uses = [AX] in
1128 let Defs = [AL,EFLAGS,AX], Uses = [AX] in
11261129 def DIV8m : I<0xF6, MRM6m, (outs), (ins i8mem:$src), // AX/[mem8] = AL,AH
11271130 "div{b}\t$src", []>;
11281131 let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in
11351138 }
11361139
11371140 // Signed division/remainder.
1138 let Defs = [AL,AH,EFLAGS], Uses = [AX] in
1141 let Defs = [AL,EFLAGS,AX], Uses = [AX] in
11391142 def IDIV8r : I<0xF6, MRM7r, (outs), (ins GR8:$src), // AX/r8 = AL,AH
11401143 "idiv{b}\t$src", []>;
11411144 let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in
11451148 def IDIV32r: I<0xF7, MRM7r, (outs), (ins GR32:$src), // EDX:EAX/r32 = EAX,EDX
11461149 "idiv{l}\t$src", []>;
11471150 let mayLoad = 1, mayLoad = 1 in {
1148 let Defs = [AL,AH,EFLAGS], Uses = [AX] in
1151 let Defs = [AL,EFLAGS,AX], Uses = [AX] in
11491152 def IDIV8m : I<0xF6, MRM7m, (outs), (ins i8mem:$src), // AX/[mem8] = AL,AH
11501153 "idiv{b}\t$src", []>;
11511154 let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in
0 ; RUN: llc < %s
1 ; PR6489
2 ;
3 ; This test case produces a MUL8 instruction and then tries to read the result
4 ; from the AX register instead of AH/AL. That confuses live interval analysis.
5 ;
6 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
7 target triple = "x86_64-apple-darwin10.0.0"
8
9 define void @func_56(i64 %p_57, i32*** %p_58) nounwind ssp {
10 for.end:
11 %conv49 = trunc i32 undef to i8 ; [#uses=1]
12 %div.i = udiv i8 %conv49, 5 ; [#uses=1]
13 %conv51 = zext i8 %div.i to i32 ; [#uses=1]
14 %call55 = call i32 @qux(i32 undef, i32 -2) nounwind ; [#uses=1]
15 %rem.i = urem i32 %call55, -1 ; [#uses=1]
16 %cmp57 = icmp uge i32 %conv51, %rem.i ; [#uses=1]
17 %conv58 = zext i1 %cmp57 to i32 ; [#uses=1]
18 %call85 = call i32 @func_35(i32*** undef, i32 undef, i32 %conv58, i32 1247, i32 0) nounwind ; [#uses=0]
19 ret void
20 }
21
22 declare i32 @func_35(i32***, i32, i32, i32, i32)
23
24 declare i32 @qux(i32, i32)