Skip to content

Commit

Permalink
Do not generate LWL/LWR instructions in the purecap ABI
Browse files Browse the repository at this point in the history
This was happening when lowering function calls with an implicit sret
parameter since the alignment of those loads is set to 1.
Found while compiling IR generated by Rust.
  • Loading branch information
arichardson committed Mar 28, 2019
1 parent 974204c commit d8e6acf
Show file tree
Hide file tree
Showing 2 changed files with 161 additions and 3 deletions.
16 changes: 13 additions & 3 deletions llvm/lib/Target/Mips/MipsISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3178,12 +3178,20 @@ SDValue MipsTargetLowering::lowerLOAD(SDValue Op, SelectionDAG &DAG) const {

// We don't handle capability-releative loads here, so make sure that we
// don't encounter them!
assert(MemVT != CapType);
LD->dump();
LD->getBasePtr()->dump();
assert(!MemVT.isFatPointer());

// Return if load is aligned or if MemVT is neither i32 nor i64.
if ((LD->getAlignment() >= MemVT.getSizeInBits() / 8) ||
((MemVT != MVT::i32) && (MemVT != MVT::i64)))
if ((LD->getAlignment() >= MemVT.getSizeInBits() / 8)) {
return SDValue();
} else if (Subtarget.isABI_CheriPureCap()) {
// Can't use LWL/LWR in pure capability ABI -> fall back to generic code
std::pair<SDValue, SDValue> P = expandUnalignedLoad(LD, DAG);
return DAG.getMergeValues({P.first, P.second}, SDLoc(LD));
} else if (((MemVT != MVT::i32) && (MemVT != MVT::i64))) {
return SDValue();
}

bool IsLittle = Subtarget.isLittle();
EVT VT = Op.getValueType();
Expand All @@ -3192,6 +3200,8 @@ SDValue MipsTargetLowering::lowerLOAD(SDValue Op, SelectionDAG &DAG) const {

assert((VT == MVT::i32) || (VT == MVT::i64));

assert(!Subtarget.isABI_CheriPureCap() && "LWL/LWR not supported in purecap");

// Expand
// (set dst, (i64 (load baseptr)))
// to
Expand Down
148 changes: 148 additions & 0 deletions llvm/test/CodeGen/Mips/cheri/rust-select-ldr.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: sed 's/addrspace(200)/addrspace(0)/g' %s | %cheri_llc -verify-machineinstrs -O0 -o - | FileCheck %s -check-prefix MIPS
; RUN: %cheri_purecap_llc -verify-machineinstrs -O0 -o - %s | %cheri_FileCheck %s -check-prefix PURECAP
; REQUIRES: cheri_is_128
; This rust-derived IR was generating a LDL instruction for the extractvalue of the hidden sret paramter:

declare dso_local i128 @"_ZN3lib6option15Option$LT$T$GT$6unwrap17h50e7a820126dcfe5E"(i64, i128) unnamed_addr addrspace(200) #0

declare dso_local { i64, i128 } @"_ZN63_$LT$main..Counter$u20$as$u20$lib..iter..iterator..Iterator$GT$4next17h229c875ab7438d23E"(i128 addrspace(200)*) unnamed_addr addrspace(200) #0

define internal void @_ZN4main4main17hfe98083a4c87500fE() unnamed_addr addrspace(200) nounwind {
; MIPS-LABEL: _ZN4main4main17hfe98083a4c87500fE:
; MIPS: # %bb.0: # %start
; MIPS-NEXT: daddiu $sp, $sp, -80
; MIPS-NEXT: sd $ra, 72($sp) # 8-byte Folded Spill
; MIPS-NEXT: daddiu $4, $sp, 24
; MIPS-NEXT: daddiu $5, $sp, 48
; MIPS-NEXT: jal _ZN63_$LT$main..Counter$u20$as$u20$lib..iter..iterator..Iterator$GT$4next17h229c875ab7438d23E
; MIPS-NEXT: nop
; MIPS-NEXT: # implicit-def: $a0_64
; MIPS-NEXT: ldl $4, 40($sp)
; MIPS-NEXT: ldr $4, 47($sp)
; MIPS-NEXT: # implicit-def: $a1_64
; MIPS-NEXT: ldl $5, 32($sp)
; MIPS-NEXT: ldr $5, 39($sp)
; MIPS-NEXT: # implicit-def: $at_64
; MIPS-NEXT: ldl $1, 24($sp)
; MIPS-NEXT: ldr $1, 31($sp)
; MIPS-NEXT: sd $4, 16($sp) # 8-byte Folded Spill
; MIPS-NEXT: move $4, $1
; MIPS-NEXT: ld $6, 16($sp) # 8-byte Folded Reload
; MIPS-NEXT: jal _ZN3lib6option15Option$LT$T$GT$6unwrap17h50e7a820126dcfe5E
; MIPS-NEXT: nop
; MIPS-NEXT: sd $2, 8($sp) # 8-byte Folded Spill
; MIPS-NEXT: sd $3, 0($sp) # 8-byte Folded Spill
; MIPS-NEXT: ld $ra, 72($sp) # 8-byte Folded Reload
; MIPS-NEXT: daddiu $sp, $sp, 80
; MIPS-NEXT: jr $ra
; MIPS-NEXT: nop
;
; PURECAP-LABEL: _ZN4main4main17hfe98083a4c87500fE:
; PURECAP: # %bb.0: # %start
; PURECAP-NEXT: cincoffset $c11, $c11, -[[STACKFRAME_SIZE:96|160]]
; PURECAP-NEXT: csc $c17, $zero, [[@EXPR 5 * $CAP_SIZE]]($c11)
; PURECAP-NEXT: lui $1, %hi(%neg(%captab_rel(_ZN4main4main17hfe98083a4c87500fE)))
; PURECAP-NEXT: daddiu $1, $1, %lo(%neg(%captab_rel(_ZN4main4main17hfe98083a4c87500fE)))
; PURECAP-NEXT: cincoffset $c26, $c12, $1
; PURECAP-NEXT: cmove $c12, $c26
; PURECAP-NEXT: cincoffset $c4, $c11, 64
; PURECAP-NEXT: csetbounds $c4, $c4, 16
; PURECAP-NEXT: clcbi $c1, %capcall20(_ZN63_$LT$main..Counter$u20$as$u20$lib..iter..iterator..Iterator$GT$4next17h229c875ab7438d23E)($c12)
; PURECAP-NEXT: cincoffset $c3, $c11, 40
; PURECAP-NEXT: cgetnull $c13
; PURECAP-NEXT: csc $c12, $zero, [[@EXPR 1 * $CAP_SIZE]]($c11)
; PURECAP-NEXT: cmove $c12, $c1
; PURECAP-NEXT: cjalr $c12, $c17
; PURECAP-NEXT: nop
; PURECAP-NEXT: clbu $1, $zero, 47($c11)
; PURECAP-NEXT: clbu $2, $zero, 46($c11)
; PURECAP-NEXT: dsll $2, $2, 8
; PURECAP-NEXT: or $1, $2, $1
; PURECAP-NEXT: clbu $2, $zero, 45($c11)
; PURECAP-NEXT: clbu $3, $zero, 44($c11)
; PURECAP-NEXT: dsll $3, $3, 8
; PURECAP-NEXT: or $2, $3, $2
; PURECAP-NEXT: dsll $2, $2, 16
; PURECAP-NEXT: or $1, $2, $1
; PURECAP-NEXT: clbu $2, $zero, 43($c11)
; PURECAP-NEXT: clbu $3, $zero, 42($c11)
; PURECAP-NEXT: dsll $3, $3, 8
; PURECAP-NEXT: or $2, $3, $2
; PURECAP-NEXT: clbu $3, $zero, 41($c11)
; PURECAP-NEXT: clbu $4, $zero, 40($c11)
; PURECAP-NEXT: dsll $4, $4, 8
; PURECAP-NEXT: or $3, $4, $3
; PURECAP-NEXT: dsll $3, $3, 16
; PURECAP-NEXT: or $2, $3, $2
; PURECAP-NEXT: dsll $2, $2, 32
; PURECAP-NEXT: or $4, $2, $1
; PURECAP-NEXT: clbu $1, $zero, 55($c11)
; PURECAP-NEXT: clbu $2, $zero, 54($c11)
; PURECAP-NEXT: dsll $2, $2, 8
; PURECAP-NEXT: or $1, $2, $1
; PURECAP-NEXT: clbu $2, $zero, 53($c11)
; PURECAP-NEXT: clbu $3, $zero, 52($c11)
; PURECAP-NEXT: dsll $3, $3, 8
; PURECAP-NEXT: or $2, $3, $2
; PURECAP-NEXT: dsll $2, $2, 16
; PURECAP-NEXT: or $1, $2, $1
; PURECAP-NEXT: clbu $2, $zero, 51($c11)
; PURECAP-NEXT: clbu $3, $zero, 50($c11)
; PURECAP-NEXT: dsll $3, $3, 8
; PURECAP-NEXT: or $2, $3, $2
; PURECAP-NEXT: clbu $3, $zero, 49($c11)
; PURECAP-NEXT: clbu $5, $zero, 48($c11)
; PURECAP-NEXT: dsll $5, $5, 8
; PURECAP-NEXT: or $3, $5, $3
; PURECAP-NEXT: dsll $3, $3, 16
; PURECAP-NEXT: or $2, $3, $2
; PURECAP-NEXT: dsll $2, $2, 32
; PURECAP-NEXT: or $5, $2, $1
; PURECAP-NEXT: clbu $1, $zero, 63($c11)
; PURECAP-NEXT: clbu $2, $zero, 62($c11)
; PURECAP-NEXT: dsll $2, $2, 8
; PURECAP-NEXT: or $1, $2, $1
; PURECAP-NEXT: clbu $2, $zero, 61($c11)
; PURECAP-NEXT: clbu $3, $zero, 60($c11)
; PURECAP-NEXT: dsll $3, $3, 8
; PURECAP-NEXT: or $2, $3, $2
; PURECAP-NEXT: dsll $2, $2, 16
; PURECAP-NEXT: or $1, $2, $1
; PURECAP-NEXT: clbu $2, $zero, 59($c11)
; PURECAP-NEXT: clbu $3, $zero, 58($c11)
; PURECAP-NEXT: dsll $3, $3, 8
; PURECAP-NEXT: or $2, $3, $2
; PURECAP-NEXT: clbu $3, $zero, 57($c11)
; PURECAP-NEXT: clbu $6, $zero, 56($c11)
; PURECAP-NEXT: dsll $6, $6, 8
; PURECAP-NEXT: or $3, $6, $3
; PURECAP-NEXT: dsll $3, $3, 16
; PURECAP-NEXT: or $2, $3, $2
; PURECAP-NEXT: dsll $2, $2, 32
; PURECAP-NEXT: or $6, $2, $1
; PURECAP-NEXT: clc $c1, $zero, [[@EXPR 1 * $CAP_SIZE]]($c11)
; PURECAP-NEXT: clcbi $c12, %capcall20(_ZN3lib6option15Option$LT$T$GT$6unwrap17h50e7a820126dcfe5E)($c1)
; PURECAP-NEXT: cgetnull $c13
; PURECAP-NEXT: cjalr $c12, $c17
; PURECAP-NEXT: nop
; PURECAP-NEXT: csd $2, $zero, [[@EXPR STACKFRAME_SIZE - 88]]($c11)
; PURECAP-NEXT: csd $3, $zero, [[@EXPR STACKFRAME_SIZE - 96]]($c11)
; PURECAP-NEXT: clc $c17, $zero, [[@EXPR 5 * $CAP_SIZE]]($c11)
; PURECAP-NEXT: cincoffset $c11, $c11, 96
; PURECAP-NEXT: cjr $c17
; PURECAP-NEXT: nop

; This is an insanely slow sequence of instructions but at least it no longer asserts:
start:
%ctr = alloca i128, align 16, addrspace(200)
%0 = call { i64, i128 } @"_ZN63_$LT$main..Counter$u20$as$u20$lib..iter..iterator..Iterator$GT$4next17h229c875ab7438d23E"(i128 addrspace(200)* align 16 dereferenceable(16) %ctr)
%1 = extractvalue { i64, i128 } %0, 0
%2 = extractvalue { i64, i128 } %0, 1
%3 = call i128 @"_ZN3lib6option15Option$LT$T$GT$6unwrap17h50e7a820126dcfe5E"(i64 %1, i128 %2)
ret void
}

!llvm.module.flags = !{!0}

!0 = !{i32 2, !"RtLibUseGOT", i32 1}

0 comments on commit d8e6acf

Please sign in to comment.