Skip to content

Commit c0b3e49

Browse files
authored
[llvm][Mips] Bail on underaligned loads/stores in FastISel. (llvm#106231)
We encountered this problem in Zig, causing all of our `mips(el)-linux-gnueabi*` tests to fail: ziglang/zig#21215 For these unusual cases, let's just bail in `MipsFastISel` since `MipsTargetLowering` can handle them fine. Note: I don't have commit access.
1 parent 7e74472 commit c0b3e49

File tree

2 files changed

+131
-8
lines changed

2 files changed

+131
-8
lines changed

llvm/lib/Target/Mips/MipsFastISel.cpp

+22-8
Original file line numberDiff line numberDiff line change
@@ -881,38 +881,52 @@ bool MipsFastISel::selectLogicalOp(const Instruction *I) {
881881
}
882882

883883
bool MipsFastISel::selectLoad(const Instruction *I) {
884+
const LoadInst *LI = cast<LoadInst>(I);
885+
884886
// Atomic loads need special handling.
885-
if (cast<LoadInst>(I)->isAtomic())
887+
if (LI->isAtomic())
886888
return false;
887889

888890
// Verify we have a legal type before going any further.
889891
MVT VT;
890-
if (!isLoadTypeLegal(I->getType(), VT))
892+
if (!isLoadTypeLegal(LI->getType(), VT))
893+
return false;
894+
895+
// Underaligned loads need special handling.
896+
if (LI->getAlign() < VT.getFixedSizeInBits() / 8 &&
897+
!Subtarget->systemSupportsUnalignedAccess())
891898
return false;
892899

893900
// See if we can handle this address.
894901
Address Addr;
895-
if (!computeAddress(I->getOperand(0), Addr))
902+
if (!computeAddress(LI->getOperand(0), Addr))
896903
return false;
897904

898905
unsigned ResultReg;
899906
if (!emitLoad(VT, ResultReg, Addr))
900907
return false;
901-
updateValueMap(I, ResultReg);
908+
updateValueMap(LI, ResultReg);
902909
return true;
903910
}
904911

905912
bool MipsFastISel::selectStore(const Instruction *I) {
906-
Value *Op0 = I->getOperand(0);
913+
const StoreInst *SI = cast<StoreInst>(I);
914+
915+
Value *Op0 = SI->getOperand(0);
907916
unsigned SrcReg = 0;
908917

909918
// Atomic stores need special handling.
910-
if (cast<StoreInst>(I)->isAtomic())
919+
if (SI->isAtomic())
911920
return false;
912921

913922
// Verify we have a legal type before going any further.
914923
MVT VT;
915-
if (!isLoadTypeLegal(I->getOperand(0)->getType(), VT))
924+
if (!isLoadTypeLegal(SI->getOperand(0)->getType(), VT))
925+
return false;
926+
927+
// Underaligned stores need special handling.
928+
if (SI->getAlign() < VT.getFixedSizeInBits() / 8 &&
929+
!Subtarget->systemSupportsUnalignedAccess())
916930
return false;
917931

918932
// Get the value to be stored into a register.
@@ -922,7 +936,7 @@ bool MipsFastISel::selectStore(const Instruction *I) {
922936

923937
// See if we can handle this address.
924938
Address Addr;
925-
if (!computeAddress(I->getOperand(1), Addr))
939+
if (!computeAddress(SI->getOperand(1), Addr))
926940
return false;
927941

928942
if (!emitStore(VT, SrcReg, Addr))
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
2+
; RUN: llc < %s -march mips -fast-isel -relocation-model pic | FileCheck %s -check-prefixes=MIPS-32
3+
; RUN: llc < %s -march mips64 -fast-isel -relocation-model pic | FileCheck %s -check-prefixes=MIPS-64
4+
; RUN: llc < %s -march mips -mcpu mips32r6 -fast-isel -relocation-model pic | FileCheck %s -check-prefixes=MIPS-32-R6
5+
; RUN: llc < %s -march mips -mcpu mips32r6 -mattr +strict-align -fast-isel -relocation-model pic | FileCheck %s -check-prefixes=MIPS-32-R6-STRICT
6+
; RUN: llc < %s -march mips64 -mcpu mips64r6 -fast-isel -relocation-model pic | FileCheck %s -check-prefixes=MIPS-64-R6
7+
; RUN: llc < %s -march mips64 -mcpu mips64r6 -mattr +strict-align -fast-isel -relocation-model pic | FileCheck %s -check-prefixes=MIPS-64-R6-STRICT
8+
9+
@var = external global i32, align 1
10+
11+
; FastISel should bail on the underaligned load and store, except on r6 with non-strict alignment.
12+
define dso_local ccc i32 @__start() {
13+
; MIPS-32-LABEL: __start:
14+
; MIPS-32: # %bb.0:
15+
; MIPS-32-NEXT: lui $2, %hi(_gp_disp)
16+
; MIPS-32-NEXT: addiu $2, $2, %lo(_gp_disp)
17+
; MIPS-32-NEXT: addu $1, $2, $25
18+
; MIPS-32-NEXT: lw $1, %got(var)($1)
19+
; MIPS-32-NEXT: lwl $2, 0($1)
20+
; MIPS-32-NEXT: lwr $2, 3($1)
21+
; MIPS-32-NEXT: addiu $3, $zero, 42
22+
; MIPS-32-NEXT: swl $3, 0($1)
23+
; MIPS-32-NEXT: jr $ra
24+
; MIPS-32-NEXT: swr $3, 3($1)
25+
;
26+
; MIPS-64-LABEL: __start:
27+
; MIPS-64: # %bb.0:
28+
; MIPS-64-NEXT: lui $1, %hi(%neg(%gp_rel(__start)))
29+
; MIPS-64-NEXT: daddu $1, $1, $25
30+
; MIPS-64-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(__start)))
31+
; MIPS-64-NEXT: ld $1, %got_disp(var)($1)
32+
; MIPS-64-NEXT: lwl $2, 0($1)
33+
; MIPS-64-NEXT: lwr $2, 3($1)
34+
; MIPS-64-NEXT: addiu $3, $zero, 42
35+
; MIPS-64-NEXT: swl $3, 0($1)
36+
; MIPS-64-NEXT: jr $ra
37+
; MIPS-64-NEXT: swr $3, 3($1)
38+
;
39+
; MIPS-32-R6-LABEL: __start:
40+
; MIPS-32-R6: # %bb.0:
41+
; MIPS-32-R6-NEXT: lui $2, %hi(_gp_disp)
42+
; MIPS-32-R6-NEXT: addiu $2, $2, %lo(_gp_disp)
43+
; MIPS-32-R6-NEXT: addu $1, $2, $25
44+
; MIPS-32-R6-NEXT: lw $1, %got(var)($1)
45+
; MIPS-32-R6-NEXT: lw $2, 0($1)
46+
; MIPS-32-R6-NEXT: addiu $3, $zero, 42
47+
; MIPS-32-R6-NEXT: jr $ra
48+
; MIPS-32-R6-NEXT: sw $3, 0($1)
49+
;
50+
; MIPS-32-R6-STRICT-LABEL: __start:
51+
; MIPS-32-R6-STRICT: # %bb.0:
52+
; MIPS-32-R6-STRICT-NEXT: lui $2, %hi(_gp_disp)
53+
; MIPS-32-R6-STRICT-NEXT: addiu $2, $2, %lo(_gp_disp)
54+
; MIPS-32-R6-STRICT-NEXT: addu $1, $2, $25
55+
; MIPS-32-R6-STRICT-NEXT: lw $1, %got(var)($1)
56+
; MIPS-32-R6-STRICT-NEXT: lbu $2, 0($1)
57+
; MIPS-32-R6-STRICT-NEXT: lbu $3, 1($1)
58+
; MIPS-32-R6-STRICT-NEXT: lbu $4, 3($1)
59+
; MIPS-32-R6-STRICT-NEXT: lbu $5, 2($1)
60+
; MIPS-32-R6-STRICT-NEXT: addiu $6, $zero, 42
61+
; MIPS-32-R6-STRICT-NEXT: sb $zero, 2($1)
62+
; MIPS-32-R6-STRICT-NEXT: sb $6, 3($1)
63+
; MIPS-32-R6-STRICT-NEXT: sb $zero, 0($1)
64+
; MIPS-32-R6-STRICT-NEXT: sb $zero, 1($1)
65+
; MIPS-32-R6-STRICT-NEXT: sll $1, $5, 8
66+
; MIPS-32-R6-STRICT-NEXT: or $1, $1, $4
67+
; MIPS-32-R6-STRICT-NEXT: sll $3, $3, 16
68+
; MIPS-32-R6-STRICT-NEXT: sll $2, $2, 24
69+
; MIPS-32-R6-STRICT-NEXT: or $2, $2, $3
70+
; MIPS-32-R6-STRICT-NEXT: jr $ra
71+
; MIPS-32-R6-STRICT-NEXT: or $2, $2, $1
72+
;
73+
; MIPS-64-R6-LABEL: __start:
74+
; MIPS-64-R6: # %bb.0:
75+
; MIPS-64-R6-NEXT: lui $1, %hi(%neg(%gp_rel(__start)))
76+
; MIPS-64-R6-NEXT: daddu $1, $1, $25
77+
; MIPS-64-R6-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(__start)))
78+
; MIPS-64-R6-NEXT: ld $1, %got_disp(var)($1)
79+
; MIPS-64-R6-NEXT: lw $2, 0($1)
80+
; MIPS-64-R6-NEXT: addiu $3, $zero, 42
81+
; MIPS-64-R6-NEXT: jr $ra
82+
; MIPS-64-R6-NEXT: sw $3, 0($1)
83+
;
84+
; MIPS-64-R6-STRICT-LABEL: __start:
85+
; MIPS-64-R6-STRICT: # %bb.0:
86+
; MIPS-64-R6-STRICT-NEXT: lui $1, %hi(%neg(%gp_rel(__start)))
87+
; MIPS-64-R6-STRICT-NEXT: daddu $1, $1, $25
88+
; MIPS-64-R6-STRICT-NEXT: daddiu $1, $1, %lo(%neg(%gp_rel(__start)))
89+
; MIPS-64-R6-STRICT-NEXT: ld $1, %got_disp(var)($1)
90+
; MIPS-64-R6-STRICT-NEXT: lbu $2, 0($1)
91+
; MIPS-64-R6-STRICT-NEXT: lbu $3, 1($1)
92+
; MIPS-64-R6-STRICT-NEXT: lbu $4, 3($1)
93+
; MIPS-64-R6-STRICT-NEXT: lbu $5, 2($1)
94+
; MIPS-64-R6-STRICT-NEXT: addiu $6, $zero, 42
95+
; MIPS-64-R6-STRICT-NEXT: sb $zero, 2($1)
96+
; MIPS-64-R6-STRICT-NEXT: sb $6, 3($1)
97+
; MIPS-64-R6-STRICT-NEXT: sb $zero, 0($1)
98+
; MIPS-64-R6-STRICT-NEXT: sb $zero, 1($1)
99+
; MIPS-64-R6-STRICT-NEXT: sll $1, $5, 8
100+
; MIPS-64-R6-STRICT-NEXT: or $1, $1, $4
101+
; MIPS-64-R6-STRICT-NEXT: sll $3, $3, 16
102+
; MIPS-64-R6-STRICT-NEXT: sll $2, $2, 24
103+
; MIPS-64-R6-STRICT-NEXT: or $2, $2, $3
104+
; MIPS-64-R6-STRICT-NEXT: jr $ra
105+
; MIPS-64-R6-STRICT-NEXT: or $2, $2, $1
106+
%1 = load i32, ptr @var, align 1
107+
store i32 42, ptr @var, align 1
108+
ret i32 %1
109+
}

0 commit comments

Comments
 (0)