mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 19:23:23 +01:00
Give the rdrand instructions a SideEffect flag and a chain so MachineCSE and MachineLICM don't touch it.
I already had the necessary things in place for IR-level passes but missed the machine passes. llvm-svn: 160137
This commit is contained in:
parent
7c10305e52
commit
558c56f216
@ -9823,8 +9823,8 @@ X86TargetLowering::LowerINTRINSIC_W_CHAIN(SDValue Op, SelectionDAG &DAG) const {
|
||||
case Intrinsic::x86_rdrand_32:
|
||||
case Intrinsic::x86_rdrand_64: {
|
||||
// Emit the node with the right value type.
|
||||
SDValue Result = DAG.getNode(X86ISD::RDRAND, dl,
|
||||
DAG.getVTList(Op->getValueType(0), MVT::Glue));
|
||||
SDVTList VTs = DAG.getVTList(Op->getValueType(0), MVT::Glue, MVT::Other);
|
||||
SDValue Result = DAG.getNode(X86ISD::RDRAND, dl, VTs, Op.getOperand(0));
|
||||
|
||||
// If the value returned by RDRAND was valid (CF=1), return 1. Otherwise
|
||||
// return the value from Rand, which is always 0, casted to i32.
|
||||
@ -9838,7 +9838,7 @@ X86TargetLowering::LowerINTRINSIC_W_CHAIN(SDValue Op, SelectionDAG &DAG) const {
|
||||
|
||||
// Return { result, isValid, chain }.
|
||||
return DAG.getNode(ISD::MERGE_VALUES, dl, Op->getVTList(), Result, isValid,
|
||||
Op.getOperand(0));
|
||||
SDValue(Result.getNode(), 2));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -139,7 +139,8 @@ def X86setcc_c : SDNode<"X86ISD::SETCC_CARRY", SDTX86SetCC_C>;
|
||||
|
||||
def X86sahf : SDNode<"X86ISD::SAHF", SDTX86sahf>;
|
||||
|
||||
def X86rdrand : SDNode<"X86ISD::RDRAND", SDTX86rdrand>;
|
||||
def X86rdrand : SDNode<"X86ISD::RDRAND", SDTX86rdrand,
|
||||
[SDNPHasChain, SDNPSideEffect]>;
|
||||
|
||||
def X86cas : SDNode<"X86ISD::LCMPXCHG_DAG", SDTX86cas,
|
||||
[SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore,
|
||||
|
@ -45,3 +45,41 @@ define i32 @_rdrand64_step(i64* %random_val) {
|
||||
; CHECK: cmovael %e[[T1]], %eax
|
||||
; CHECK: ret
|
||||
}
|
||||
|
||||
; Check that MachineCSE doesn't eliminate duplicate rdrand instructions.
|
||||
define i32 @CSE() nounwind {
|
||||
%rand1 = tail call { i32, i32 } @llvm.x86.rdrand.32() nounwind
|
||||
%v1 = extractvalue { i32, i32 } %rand1, 0
|
||||
%rand2 = tail call { i32, i32 } @llvm.x86.rdrand.32() nounwind
|
||||
%v2 = extractvalue { i32, i32 } %rand2, 0
|
||||
%add = add i32 %v2, %v1
|
||||
ret i32 %add
|
||||
; CHECK: CSE:
|
||||
; CHECK: rdrandl
|
||||
; CHECK: rdrandl
|
||||
}
|
||||
|
||||
; Check that MachineLICM doesn't hoist rdrand instructions.
|
||||
define void @loop(i32* %p, i32 %n) nounwind {
|
||||
entry:
|
||||
%tobool1 = icmp eq i32 %n, 0
|
||||
br i1 %tobool1, label %while.end, label %while.body
|
||||
|
||||
while.body: ; preds = %entry, %while.body
|
||||
%p.addr.03 = phi i32* [ %incdec.ptr, %while.body ], [ %p, %entry ]
|
||||
%n.addr.02 = phi i32 [ %dec, %while.body ], [ %n, %entry ]
|
||||
%dec = add nsw i32 %n.addr.02, -1
|
||||
%incdec.ptr = getelementptr inbounds i32* %p.addr.03, i64 1
|
||||
%rand = tail call { i32, i32 } @llvm.x86.rdrand.32() nounwind
|
||||
%v1 = extractvalue { i32, i32 } %rand, 0
|
||||
store i32 %v1, i32* %p.addr.03, align 4
|
||||
%tobool = icmp eq i32 %dec, 0
|
||||
br i1 %tobool, label %while.end, label %while.body
|
||||
|
||||
while.end: ; preds = %while.body, %entry
|
||||
ret void
|
||||
; CHECK: loop:
|
||||
; CHECK-NOT: rdrandl
|
||||
; CHECK: This Inner Loop Header: Depth=1
|
||||
; CHECK: rdrandl
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user