소스 검색

Don't emit discard when input is non-negative (#2628)

Vishal Sharma 5 년 전
부모
커밋
82b1625bb5
2개의 변경된 파일46개의 추가작업 그리고 0개의 파일을 삭제
  1. 6 0
      lib/HLSL/HLOperationLower.cpp
  2. 40 0
      tools/clang/test/HLSLFileCheck/hlsl/intrinsics/pixel/clip_constant.hlsl

+ 6 - 0
lib/HLSL/HLOperationLower.cpp

@@ -1594,6 +1594,12 @@ Value *TranslateClip(CallInst *CI, IntrinsicOp IOP, OP::OpCode opcode,
   } else
     cond = Builder.CreateFCmpOLT(arg, hlslOP->GetFloatConst(0));
 
+  /*If discard condition evaluates to false at compile-time, then
+  don't emit the discard instruction.*/
+  if (ConstantInt *constCond = dyn_cast<ConstantInt>(cond))
+    if (!constCond->getLimitedValue())
+      return nullptr;
+
   Constant *opArg = hlslOP->GetU32Const((unsigned)OP::OpCode::Discard);
   Builder.CreateCall(discard, {opArg, cond});
   return nullptr;

+ 40 - 0
tools/clang/test/HLSLFileCheck/hlsl/intrinsics/pixel/clip_constant.hlsl

@@ -0,0 +1,40 @@
+// RUN: %dxc -E main_discard -T ps_6_0 %s | FileCheck -check-prefix=DSCRD %s
+// RUN: %dxc -E main_no_discard -T ps_6_0 %s | FileCheck -check-prefix=NODSCRD %s
+
+// Test that when input to clip() is a compile-time constant,
+// a discard instruction is not emitted when its input is non-negative like FXC.
+
+// Github issue# 2515
+
+float4 main_discard() : SV_Target
+{
+  // DSCRD: dx.op.discard
+  clip(-1);
+  
+  // DSCRD: dx.op.discard
+  clip(float4(-0.001, 10, 1, 0));
+  
+  return 0;
+}
+
+float4 main_no_discard() : SV_Target
+{
+  // NODSCRD-NOT: dx.op.discard
+  clip(float4(1, 0, 0, 1));
+  
+  // NODSCRD-NOT: dx.op.discard
+  clip(float3(0, 0, 0));
+  
+  // NODSCRD-NOT: dx.op.discard
+  clip(float2(0.001, 0.00001));
+  
+  // NODSCRD-NOT: dx.op.discard
+  clip(0);
+  
+  // NODSCRD-NOT: dx.op.discard
+  clip(1);
+  
+  return 0;
+}
+
+