R600: Implement ComputeNumSignBitsForTargetNode for BFE
authorMatt Arsenault <Matthew.Arsenault@amd.com>
Thu, 22 May 2014 18:09:03 +0000 (18:09 +0000)
committerMatt Arsenault <Matthew.Arsenault@amd.com>
Thu, 22 May 2014 18:09:03 +0000 (18:09 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@209460 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/R600/AMDGPUISelLowering.cpp
lib/Target/R600/AMDGPUISelLowering.h
test/CodeGen/R600/sext-in-reg.ll

index 870b39eca75caa8caeb4cc52a30bc737f0cb16be..78e79bc98a6688b169247368ae7446d47b1902a2 100644 (file)
@@ -1539,3 +1539,28 @@ void AMDGPUTargetLowering::computeKnownBitsForTargetNode(
   }
   }
 }
+
+unsigned AMDGPUTargetLowering::ComputeNumSignBitsForTargetNode(
+  SDValue Op,
+  const SelectionDAG &DAG,
+  unsigned Depth) const {
+  switch (Op.getOpcode()) {
+  case AMDGPUISD::BFE_I32: {
+    ConstantSDNode *Width = dyn_cast<ConstantSDNode>(Op.getOperand(2));
+    if (!Width)
+      return 1;
+
+    unsigned SignBits = 32 - Width->getZExtValue() + 1;
+    ConstantSDNode *Offset = dyn_cast<ConstantSDNode>(Op.getOperand(1));
+    if (!Offset || !Offset->isNullValue())
+      return SignBits;
+
+    // TODO: Could probably figure something out with non-0 offsets.
+    unsigned Op0SignBits = DAG.ComputeNumSignBits(Op.getOperand(0), Depth + 1);
+    return std::max(SignBits, Op0SignBits);
+  }
+
+  default:
+    return 1;
+  }
+}
index b876c521d3227af97f2eb1865587bfaaf366bb06..d5d821d9364bd01cd273788b9e14d6736260998c 100644 (file)
@@ -124,6 +124,11 @@ public:
                                      const SelectionDAG &DAG,
                                      unsigned Depth = 0) const override;
 
+  virtual unsigned ComputeNumSignBitsForTargetNode(
+    SDValue Op,
+    const SelectionDAG &DAG,
+    unsigned Depth = 0) const override;
+
 // Functions defined in AMDILISelLowering.cpp
 public:
   bool getTgtMemIntrinsic(IntrinsicInfo &Info,
index 90c4ba6af8f21257ae16352c0d8df5f336a2ef86..d2ab0b928798f33db0b8a537a41dcb258c79b3de 100644 (file)
@@ -379,3 +379,18 @@ define void @sext_in_reg_to_illegal_type(i16 addrspace(1)* nocapture %out, i8 ad
   store i16 %tmp6, i16 addrspace(1)* %out, align 2
   ret void
 }
+
+declare i32 @llvm.AMDGPU.bfe.i32(i32, i32, i32) nounwind readnone
+
+; Make sure there isn't a redundant BFE
+; FUNC-LABEL: @sext_in_reg_i8_to_i32_bfe
+; SI: S_BFE_I32 s{{[0-9]+}}, s{{[0-9]+}}, 0x80000
+; SI-NOT: BFE
+define void @sext_in_reg_i8_to_i32_bfe(i32 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
+  %c = add i32 %a, %b ; add to prevent folding into extload
+  %bfe = call i32 @llvm.AMDGPU.bfe.i32(i32 %c, i32 0, i32 8) nounwind readnone
+  %shl = shl i32 %bfe, 24
+  %ashr = ashr i32 %shl, 24
+  store i32 %ashr, i32 addrspace(1)* %out, align 4
+  ret void
+}