summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Target/AMDGPU/R600ISelLowering.cpp14
-rw-r--r--test/CodeGen/R600/icmp-select-sete-reverse-args.ll18
2 files changed, 26 insertions, 6 deletions
diff --git a/lib/Target/AMDGPU/R600ISelLowering.cpp b/lib/Target/AMDGPU/R600ISelLowering.cpp
index 121f49426e5..da1de57777a 100644
--- a/lib/Target/AMDGPU/R600ISelLowering.cpp
+++ b/lib/Target/AMDGPU/R600ISelLowering.cpp
@@ -603,6 +603,14 @@ SDValue R600TargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const
// We need all the operands of SELECT_CC to have the same value type, so if
// necessary we need to change True and False to be the same type as LHS and
// RHS, and then convert the result of the select_cc back to the correct type.
+
+ // Move hardware True/False values to the correct operand.
+ if (isHWTrueValue(False) && isHWFalseValue(True)) {
+ ISD::CondCode CCOpcode = cast<CondCodeSDNode>(CC)->get();
+ std::swap(False, True);
+ CC = DAG.getCondCode(ISD::getSetCCInverse(CCOpcode, CompareVT == MVT::i32));
+ }
+
if (isHWTrueValue(True) && isHWFalseValue(False)) {
if (CompareVT != VT) {
if (VT == MVT::f32 && CompareVT == MVT::i32) {
@@ -636,12 +644,6 @@ SDValue R600TargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const
}
}
- // XXX If True is a hardware TRUE value and False is a hardware FALSE value,
- // we can handle this with a native instruction, but we need to swap true
- // and false and change the conditional.
- if (isHWTrueValue(False) && isHWFalseValue(True)) {
- }
-
// If we make it this for it means we have no native instructions to handle
// this SELECT_CC, so we must lower it.
SDValue HWTrue, HWFalse;
diff --git a/test/CodeGen/R600/icmp-select-sete-reverse-args.ll b/test/CodeGen/R600/icmp-select-sete-reverse-args.ll
new file mode 100644
index 00000000000..aad44d9edf5
--- /dev/null
+++ b/test/CodeGen/R600/icmp-select-sete-reverse-args.ll
@@ -0,0 +1,18 @@
+;RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck %s
+
+;Test that a select with reversed True/False values is correctly lowered
+;to a SETNE_INT. There should only be one SETNE_INT instruction.
+
+;CHECK: SETNE_INT T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}
+;CHECK_NOT: SETNE_INT
+
+define void @test(i32 addrspace(1)* %out, i32 addrspace(1)* %in) {
+entry:
+ %0 = load i32 addrspace(1)* %in
+ %arrayidx1 = getelementptr inbounds i32 addrspace(1)* %in, i32 1
+ %1 = load i32 addrspace(1)* %arrayidx1
+ %cmp = icmp eq i32 %0, %1
+ %value = select i1 %cmp, i32 0, i32 -1
+ store i32 %value, i32 addrspace(1)* %out
+ ret void
+}