Browse Source

Use neg+imax for iabs. (#828)

Xiang Li 7 years ago
parent
commit
e9f0425202

+ 8 - 17
lib/HLSL/HLOperationLower.cpp

@@ -1086,21 +1086,6 @@ Value *TranslateWaveReadLaneFirst(CallInst *CI, IntrinsicOp IOP,
                               CI->getOperand(1)->getType(), CI, hlslOP);
                               CI->getOperand(1)->getType(), CI, hlslOP);
 }
 }
 
 
-Value *TranslateIAbs(CallInst *CI) {
-  Type *Ty = CI->getType();
-  Type *EltTy = Ty->getScalarType();
-  unsigned bitWidth = EltTy->getIntegerBitWidth();
-  uint64_t mask = ((uint64_t)1) << (bitWidth - 1);
-  Constant *opMask = ConstantInt::get(EltTy, mask);
-  if (Ty != EltTy) {
-    unsigned size = Ty->getVectorNumElements();
-    opMask = llvm::ConstantVector::getSplat(size, opMask);
-  }
-  IRBuilder<> Builder(CI);
-  return Builder.CreateXor(CI->getArgOperand(HLOperandIndex::kUnaryOpSrc0Idx),
-                           opMask);
-}
-
 Value *TransalteAbs(CallInst *CI, IntrinsicOp IOP, OP::OpCode opcode,
 Value *TransalteAbs(CallInst *CI, IntrinsicOp IOP, OP::OpCode opcode,
                     HLOperationLowerHelper &helper,  HLObjectOperationLowerHelper *pObjHelper, bool &Translated) {
                     HLOperationLowerHelper &helper,  HLObjectOperationLowerHelper *pObjHelper, bool &Translated) {
   hlsl::OP *hlslOP = &helper.hlslOP;
   hlsl::OP *hlslOP = &helper.hlslOP;
@@ -1109,8 +1094,14 @@ Value *TransalteAbs(CallInst *CI, IntrinsicOp IOP, OP::OpCode opcode,
     Value *refArgs[] = {nullptr, CI->getOperand(1)};
     Value *refArgs[] = {nullptr, CI->getOperand(1)};
     return TrivialDxilOperation(DXIL::OpCode::FAbs, refArgs, CI->getType(), CI,
     return TrivialDxilOperation(DXIL::OpCode::FAbs, refArgs, CI->getType(), CI,
                                 hlslOP);
                                 hlslOP);
-  } else
-    return TranslateIAbs(CI);
+  } else {
+    Value *src = CI->getArgOperand(HLOperandIndex::kUnaryOpSrc0Idx);
+    IRBuilder<> Builder(CI);
+    Value *neg = Builder.CreateNeg(src);
+    Value *refArgs[] = {nullptr, src, neg};
+    return TrivialDxilBinaryOperation(DXIL::OpCode::IMax, src, neg, hlslOP,
+                                      Builder);
+  }
 }
 }
 
 
 Value *GenerateCmpNEZero(Value *val, IRBuilder<> Builder) {
 Value *GenerateCmpNEZero(Value *val, IRBuilder<> Builder) {

+ 9 - 0
tools/clang/test/CodeGenHLSL/quick-test/iabs.hlsl

@@ -0,0 +1,9 @@
+// RUN: %dxc -T ps_6_0 -E main %s | FileCheck %s
+
+// Make sure use imax for iabs.
+// CHECK: IMax
+
+int4 main(int4 a : A) : SV_TARGET
+{
+  return abs(a.yxxx);
+}

+ 2 - 1
tools/clang/test/CodeGenHLSL/uint64_1.hlsl

@@ -5,7 +5,8 @@
 // CHECK: sdiv i64
 // CHECK: sdiv i64
 // CHECK: shl i64
 // CHECK: shl i64
 // CHECK: mul i64
 // CHECK: mul i64
-// CHECK: xor i64
+// For iabs.
+// CHECK: IMax
 // CHECK: UMax
 // CHECK: UMax
 // CHECK: UMin
 // CHECK: UMin
 // CHECK: uitofp i64
 // CHECK: uitofp i64