Skip to content

Commit

Permalink
Add constant evaluation for fmod to CodeGen
Browse files Browse the repository at this point in the history
When you use literals with fmod, it generates the hl intrinsic usind double.
During HLOperationLower, this expands to several operations, including DXIL FRC intrinsic.
FRC intrinsic doesn't support double, so GetOpFunc returns nullptr for the overload.
nullptr is blindly used in CreateCall, which crashes trying to deref nullptr.

This change fixes the literal case by adding constant eval to CodeGen for this intrinsic.

It will still crash if non-constant doubles are used explicitly.
Fixing that will require a special path in HLOperationLower to change the generated instruction sequence to something compatible with double.
  • Loading branch information
tex3d committed Mar 14, 2024
1 parent 263a773 commit 9f9d631
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 0 deletions.
9 changes: 9 additions & 0 deletions tools/clang/lib/CodeGen/CGHLSLMSFinishCodeGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2223,6 +2223,15 @@ Value *TryEvalIntrinsic(CallInst *CI, IntrinsicOp intriOp,
};
return EvalTernaryIntrinsic(CI, clampF, clampD, clampI);
} break;
case IntrinsicOp::IOP_fmod: {
auto fmodF = [](float a, float b) -> float {
return a - b * std::truncf(a / b);
};
auto fmodD = [](double a, double b) -> double {
return a - b * std::trunc(a / b);
};
return EvalBinaryIntrinsic(CI, fmodF, fmodD);
} break;
default:
return nullptr;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// RUN: %dxc -T lib_6_x -fcgl %s -E main | %FileCheck %s

// Ensure fmod is constant propagated during codegen
// CHECK: call void {{.*}}results{{.*}}(float 2.500000e+00, float -2.500000e+00, float 2.500000e+00, float -2.500000e+00)
// CHECK: call void {{.*}}results{{.*}}(float 2.500000e+00, float -2.500000e+00, float 2.500000e+00, float -2.500000e+00)

void results(float a, float b, float c, float d);

void main() {
results(
fmod(5.5, 3.0),
fmod(-5.5, 3.0),
fmod(5.5, -3.0),
fmod(-5.5, -3.0));
results(
fmod(5.5f, 3.0f),
fmod(-5.5f, 3.0f),
fmod(5.5f, -3.0f),
fmod(-5.5f, -3.0f));
}

0 comments on commit 9f9d631

Please sign in to comment.