Skip to content

Commit

Permalink
Cherry-pick of "Add SPIR-V 1.4 checks" (#6899)
Browse files Browse the repository at this point in the history
One of the patches missing in intel/llvm

Original commit:

KhronosGroup/SPIRV-LLVM-Translator@c5b3c8e3283b

Signed-off-by: Sidorov, Dmitry <dmitry.sidorov@intel.com>
  • Loading branch information
MrSidims authored Oct 18, 2022
1 parent 4189858 commit be0905f
Show file tree
Hide file tree
Showing 12 changed files with 165 additions and 136 deletions.
75 changes: 34 additions & 41 deletions llvm-spirv/lib/SPIRV/SPIRVWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1418,9 +1418,12 @@ LLVMToSPIRVBase::getLoopControl(const BranchInst *Branch,
// PartialCount must not be used with the DontUnroll bit
else if (S == "llvm.loop.unroll.count" &&
!(LoopControl & LoopControlDontUnrollMask)) {
size_t I = getMDOperandAsInt(Node, 1);
ParametersToSort.emplace_back(spv::LoopControlPartialCountMask, I);
LoopControl |= spv::LoopControlPartialCountMask;
if (BM->isAllowedToUseVersion(VersionNumber::SPIRV_1_4)) {
BM->setMinSPIRVVersion(VersionNumber::SPIRV_1_4);
size_t I = getMDOperandAsInt(Node, 1);
ParametersToSort.emplace_back(spv::LoopControlPartialCountMask, I);
LoopControl |= spv::LoopControlPartialCountMask;
}
} else if (S == "llvm.loop.ivdep.enable")
LoopControl |= spv::LoopControlDependencyInfiniteMask;
else if (S == "llvm.loop.ivdep.safelen") {
Expand Down Expand Up @@ -2481,10 +2484,10 @@ bool LLVMToSPIRVBase::transDecoration(Value *V, SPIRVValue *BV) {

if (auto BVO = dyn_cast_or_null<OverflowingBinaryOperator>(V)) {
if (BVO->hasNoSignedWrap()) {
BV->setNoSignedWrap(true);
BV->setNoIntegerDecorationWrap<DecorationNoSignedWrap>(true);
}
if (BVO->hasNoUnsignedWrap()) {
BV->setNoUnsignedWrap(true);
BV->setNoIntegerDecorationWrap<DecorationNoUnsignedWrap>(true);
}
}

Expand Down Expand Up @@ -4610,43 +4613,34 @@ bool LLVMToSPIRVBase::transExecutionMode() {
}
} break;
case spv::ExecutionModeNoGlobalOffsetINTEL: {
if (BM->isAllowedToUseExtension(
ExtensionID::SPV_INTEL_kernel_attributes)) {
BF->addExecutionMode(BM->add(
new SPIRVExecutionMode(BF, static_cast<ExecutionMode>(EMode))));
BM->addExtension(ExtensionID::SPV_INTEL_kernel_attributes);
BM->addCapability(CapabilityKernelAttributesINTEL);
}
if (!BM->isAllowedToUseExtension(
ExtensionID::SPV_INTEL_kernel_attributes))
break;
BF->addExecutionMode(BM->add(
new SPIRVExecutionMode(BF, static_cast<ExecutionMode>(EMode))));
BM->addExtension(ExtensionID::SPV_INTEL_kernel_attributes);
BM->addCapability(CapabilityKernelAttributesINTEL);
} break;
case spv::ExecutionModeVecTypeHint:
case spv::ExecutionModeSubgroupSize:
case spv::ExecutionModeSubgroupsPerWorkgroup: {
unsigned X;
N.get(X);
BF->addExecutionMode(BM->add(
new SPIRVExecutionMode(BF, static_cast<ExecutionMode>(EMode), X)));
} break;
case spv::ExecutionModeSubgroupsPerWorkgroup:
AddSingleArgExecutionMode(static_cast<ExecutionMode>(EMode));
break;
case spv::ExecutionModeNumSIMDWorkitemsINTEL:
case spv::ExecutionModeSchedulerTargetFmaxMhzINTEL:
case spv::ExecutionModeMaxWorkDimINTEL:
case spv::internal::ExecutionModeStreamingInterfaceINTEL: {
if (BM->isAllowedToUseExtension(
ExtensionID::SPV_INTEL_kernel_attributes)) {
unsigned X;
N.get(X);
BF->addExecutionMode(BM->add(new SPIRVExecutionMode(
BF, static_cast<ExecutionMode>(EMode), X)));
BM->addExtension(ExtensionID::SPV_INTEL_kernel_attributes);
BM->addCapability(CapabilityFPGAKernelAttributesINTEL);
}
if (!BM->isAllowedToUseExtension(
ExtensionID::SPV_INTEL_kernel_attributes))
break;
AddSingleArgExecutionMode(static_cast<ExecutionMode>(EMode));
BM->addExtension(ExtensionID::SPV_INTEL_kernel_attributes);
BM->addCapability(CapabilityFPGAKernelAttributesINTEL);
} break;
case spv::ExecutionModeSharedLocalMemorySizeINTEL: {
if (!BM->isAllowedToUseExtension(ExtensionID::SPV_INTEL_vector_compute))
break;
unsigned SLMSize;
N.get(SLMSize);
BF->addExecutionMode(BM->add(new SPIRVExecutionMode(
BF, static_cast<ExecutionMode>(EMode), SLMSize)));
AddSingleArgExecutionMode(static_cast<ExecutionMode>(EMode));
} break;
case spv::ExecutionModeNamedBarrierCountINTEL: {
if (!BM->isAllowedToUseExtension(ExtensionID::SPV_INTEL_vector_compute))
Expand All @@ -4664,12 +4658,14 @@ bool LLVMToSPIRVBase::transExecutionMode() {
case spv::ExecutionModeSignedZeroInfNanPreserve:
case spv::ExecutionModeRoundingModeRTE:
case spv::ExecutionModeRoundingModeRTZ: {
if (!BM->isAllowedToUseExtension(ExtensionID::SPV_KHR_float_controls))
break;
unsigned TargetWidth;
N.get(TargetWidth);
BF->addExecutionMode(BM->add(new SPIRVExecutionMode(
BF, static_cast<ExecutionMode>(EMode), TargetWidth)));
if (BM->isAllowedToUseVersion(VersionNumber::SPIRV_1_4)) {
BM->setMinSPIRVVersion(VersionNumber::SPIRV_1_4);
AddSingleArgExecutionMode(static_cast<ExecutionMode>(EMode));
} else if (BM->isAllowedToUseExtension(
ExtensionID::SPV_KHR_float_controls)) {
BM->addExtension(ExtensionID::SPV_KHR_float_controls);
AddSingleArgExecutionMode(static_cast<ExecutionMode>(EMode));
}
} break;
case spv::ExecutionModeRoundingModeRTPINTEL:
case spv::ExecutionModeRoundingModeRTNINTEL:
Expand All @@ -4678,10 +4674,7 @@ bool LLVMToSPIRVBase::transExecutionMode() {
if (!BM->isAllowedToUseExtension(
ExtensionID::SPV_INTEL_float_controls2))
break;
unsigned TargetWidth;
N.get(TargetWidth);
BF->addExecutionMode(BM->add(new SPIRVExecutionMode(
BF, static_cast<ExecutionMode>(EMode), TargetWidth)));
AddSingleArgExecutionMode(static_cast<ExecutionMode>(EMode));
} break;
case spv::internal::ExecutionModeFastCompositeKernelINTEL: {
if (BM->isAllowedToUseExtension(ExtensionID::SPV_INTEL_fast_composite))
Expand Down
5 changes: 2 additions & 3 deletions llvm-spirv/lib/SPIRV/libSPIRV/SPIRVDecorate.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ class SPIRVDecorateGeneric : public SPIRVAnnotationGeneric {

case DecorationMaxByteOffset:
return static_cast<SPIRVWord>(VersionNumber::SPIRV_1_1);
case DecorationUserSemantic:
return static_cast<SPIRVWord>(VersionNumber::SPIRV_1_4);

default:
return static_cast<SPIRVWord>(VersionNumber::SPIRV_1_0);
Expand Down Expand Up @@ -127,9 +129,6 @@ class SPIRVDecorate : public SPIRVDecorateGeneric {

llvm::Optional<ExtensionID> getRequiredExtension() const override {
switch (static_cast<size_t>(Dec)) {
case DecorationNoSignedWrap:
case DecorationNoUnsignedWrap:
return ExtensionID::SPV_KHR_no_integer_wrap_decoration;
case DecorationRegisterINTEL:
case DecorationMemoryINTEL:
case DecorationNumbanksINTEL:
Expand Down
6 changes: 0 additions & 6 deletions llvm-spirv/lib/SPIRV/libSPIRV/SPIRVEntry.h
Original file line number Diff line number Diff line change
Expand Up @@ -843,12 +843,6 @@ class SPIRVCapability : public SPIRVEntryNoId<OpCapability> {

llvm::Optional<ExtensionID> getRequiredExtension() const override {
switch (static_cast<unsigned>(Kind)) {
case CapabilityDenormPreserve:
case CapabilityDenormFlushToZero:
case CapabilitySignedZeroInfNanPreserve:
case CapabilityRoundingModeRTE:
case CapabilityRoundingModeRTZ:
return ExtensionID::SPV_KHR_float_controls;
case CapabilityRoundToInfinityINTEL:
case CapabilityFloatingPointModeINTEL:
case CapabilityFunctionFloatControlINTEL:
Expand Down
68 changes: 33 additions & 35 deletions llvm-spirv/lib/SPIRV/libSPIRV/SPIRVValue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,45 +75,10 @@ bool SPIRVValue::hasNoSignedWrap() const {
return hasDecorate(DecorationNoSignedWrap);
}

void SPIRVValue::setNoSignedWrap(bool HasNoSignedWrap) {
if (!HasNoSignedWrap) {
eraseDecorate(DecorationNoSignedWrap);
}
if (Module->isAllowedToUseExtension(
ExtensionID::SPV_KHR_no_integer_wrap_decoration)) {
// NoSignedWrap decoration is available only if it is allowed to use SPIR-V
// 1.4 or if SPV_KHR_no_integer_wrap_decoration extension is allowed
// FIXME: update this 'if' to include check for SPIR-V 1.4 once translator
// support this version
addDecorate(new SPIRVDecorate(DecorationNoSignedWrap, this));
SPIRVDBG(spvdbgs() << "Set nsw for obj " << Id << "\n")
} else {
SPIRVDBG(spvdbgs() << "Skip setting nsw for obj " << Id << "\n")
}
}

bool SPIRVValue::hasNoUnsignedWrap() const {
return hasDecorate(DecorationNoUnsignedWrap);
}

void SPIRVValue::setNoUnsignedWrap(bool HasNoUnsignedWrap) {
if (!HasNoUnsignedWrap) {
eraseDecorate(DecorationNoUnsignedWrap);
return;
}
if (Module->isAllowedToUseExtension(
ExtensionID::SPV_KHR_no_integer_wrap_decoration)) {
// NoUnsignedWrap decoration is available only if it is allowed to use
// SPIR-V 1.4 or if SPV_KHR_no_integer_wrap_decoration extension is allowed
// FIXME: update this 'if' to include check for SPIR-V 1.4 once translator
// support this version
addDecorate(new SPIRVDecorate(DecorationNoUnsignedWrap, this));
SPIRVDBG(spvdbgs() << "Set nuw for obj " << Id << "\n")
} else {
SPIRVDBG(spvdbgs() << "Skip setting nuw for obj " << Id << "\n")
}
}

void SPIRVValue::setFPFastMathMode(SPIRVWord M) {
if (M == 0) {
eraseDecorate(DecorationFPFastMathMode);
Expand All @@ -124,6 +89,39 @@ void SPIRVValue::setFPFastMathMode(SPIRVWord M) {
<< "\n")
}

template <spv::Decoration NoIntegerWrapDecoration>
void SPIRVValue::setNoIntegerDecorationWrap(bool HasNoIntegerWrap) {
if (!HasNoIntegerWrap) {
eraseDecorate(NoIntegerWrapDecoration);
return;
}
// NoSignedWrap and NoUnsignedWrap decorations are available only if it is
// allowed to use SPIR-V 1.4 or if SPV_KHR_no_integer_wrap_decoration
// extension is enabled
#ifdef _SPIRVDBG
const std::string InstStr =
NoIntegerWrapDecoration == DecorationNoSignedWrap ? "nsw" : "nuw";
#endif // _SPIRVDBG
if (Module->isAllowedToUseVersion(VersionNumber::SPIRV_1_4)) {
Module->setMinSPIRVVersion(VersionNumber::SPIRV_1_4);
addDecorate(new SPIRVDecorate(NoIntegerWrapDecoration, this));
SPIRVDBG(spvdbgs() << "Set " << InstStr << " for obj " << Id << "\n")
} else if (Module->isAllowedToUseExtension(
ExtensionID::SPV_KHR_no_integer_wrap_decoration)) {
Module->addExtension(ExtensionID::SPV_KHR_no_integer_wrap_decoration);
addDecorate(new SPIRVDecorate(NoIntegerWrapDecoration, this));
SPIRVDBG(spvdbgs() << "Set " << InstStr << " for obj " << Id << "\n")
} else {
SPIRVDBG(spvdbgs() << "Skip setting " << InstStr << " for obj " << Id
<< "\n")
}
}

template void
SPIRVValue::setNoIntegerDecorationWrap<DecorationNoSignedWrap>(bool);
template void
SPIRVValue::setNoIntegerDecorationWrap<DecorationNoUnsignedWrap>(bool);

template <spv::Op OC>
void SPIRVConstantBase<OC>::setWords(const uint64_t *TheValue) {
assert(TheValue && "Nullptr value");
Expand Down
6 changes: 4 additions & 2 deletions llvm-spirv/lib/SPIRV/libSPIRV/SPIRVValue.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,10 @@ class SPIRVValue : public SPIRVEntry {

void setAlignment(SPIRVWord);
void setVolatile(bool IsVolatile);
void setNoSignedWrap(bool HasNoSignedWrap);
void setNoUnsignedWrap(bool HasNoUnsignedWrap);

template <spv::Decoration NoIntegerWrapDecoration>
void setNoIntegerDecorationWrap(bool HasNoIntegerWrap);

void setFPFastMathMode(SPIRVWord FPFastMathMode);

void validate() const override {
Expand Down
14 changes: 12 additions & 2 deletions llvm-spirv/test/exec_mode_float_control_khr.ll
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
; RUN: llvm-as %s -o %t.bc
; RUN: llvm-spirv %t.bc -o %t.spv --spirv-ext=+SPV_KHR_float_controls
; RUN: llvm-spirv %t.bc -o %t.spv --spirv-max-version=1.1 --spirv-ext=+SPV_KHR_float_controls
; RUN: llvm-spirv %t.spv -o %t.spt --to-text
; RUN: FileCheck %s --input-file %t.spt -check-prefix=SPV
; RUN: FileCheck %s --input-file %t.spt -check-prefixes=SPV,SPVEXT
; RUN: llvm-spirv %t.bc -o %t.spv --spirv-max-version=1.4
; RUN: llvm-spirv %t.spv -o %t.spt --to-text
; RUN: FileCheck %s --input-file %t.spt -check-prefixes=SPV,SPV14
; RUN: llvm-spirv %t.bc -o %t.spv --spirv-max-version=1.1
; RUN: llvm-spirv %t.spv -o %t.spt --to-text
; RUN: FileCheck %s --input-file %t.spt -check-prefix=SPV-NEGATIVE

; ModuleID = 'float_control.bc'
source_filename = "float_control.cpp"
Expand Down Expand Up @@ -44,6 +50,10 @@ entry:
!spirv.EntryPoint = !{}
!spirv.ExecutionMode = !{!15, !16, !17, !18, !19, !20, !21, !22, !23, !24, !25, !26, !27, !28, !29}

; SPVEXT-DAG: Extension "SPV_KHR_float_controls"
; SPV14-NOT: Extension "SPV_KHR_float_controls"
; SPV-NEGATIVE-NOT: Extension "SPV_KHR_float_controls"

; SPV-DAG: EntryPoint {{[0-9]+}} [[KERNEL0:[0-9]+]] "k_float_controls_0"
; SPV-DAG: EntryPoint {{[0-9]+}} [[KERNEL1:[0-9]+]] "k_float_controls_1"
; SPV-DAG: EntryPoint {{[0-9]+}} [[KERNEL2:[0-9]+]] "k_float_controls_2"
Expand Down
8 changes: 8 additions & 0 deletions llvm-spirv/test/transcoding/LoopUnroll.ll
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,13 @@
; RUN: FileCheck < %t.spt %s --check-prefix=CHECK-SPIRV
; RUN: llvm-spirv -r -emit-opaque-pointers %t.spv -o %t.rev.bc
; RUN: llvm-dis %t.rev.bc -o - | FileCheck %s --check-prefixes=CHECK-LLVM
; RUN: llvm-spirv %t.bc -o %t.spv --spirv-max-version=1.1
; RUN: llvm-spirv -to-text %t.spv -o %t.spt
; RUN: FileCheck < %t.spt %s --check-prefix=CHECK-SPIRV-NEGATIVE

; Check SPIR-V versions in a format magic number + version
; CHECK-SPIRV: 119734787 66560
; CHECK-SPIRV-NEGATIVE: 119734787 65536

target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024"
target triple = "spir64"
Expand Down Expand Up @@ -115,6 +122,7 @@ while.cond: ; preds = %if.end, %if.then, %
; Per SPIRV spec p3.23 "Unroll" loop control = 0x1
; CHECK-SPIRV: LoopMerge [[#MERGEBLOCK:]] [[#CONTINUE:]] 256 8
; CHECK-SPIRV: BranchConditional [[#]] [[#]] [[#MERGEBLOCK]]
; CHECK-SPIRV-NEGATIVE-NOT: LoopMerge {{.*}} 256
br i1 %cmp, label %while.body, label %while.end

while.body: ; preds = %while.cond
Expand Down
47 changes: 26 additions & 21 deletions llvm-spirv/test/transcoding/NoSignedUnsignedWrap.ll
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,15 @@
; Positive tests:
;
; RUN: llvm-as %s -o %t.bc
; RUN: llvm-spirv %t.bc --spirv-ext=+SPV_KHR_no_integer_wrap_decoration -spirv-text -o - | FileCheck %s --check-prefix=CHECK-SPIRV
; RUN: llvm-spirv %t.bc --spirv-ext=+SPV_KHR_no_integer_wrap_decoration -o %t.spv
; RUN: llvm-spirv %t.bc --spirv-max-version=1.1 --spirv-ext=+SPV_KHR_no_integer_wrap_decoration -spirv-text -o - | FileCheck %s --check-prefixes=CHECK-SPIRV,CHECK-SPIRV-EXT
; RUN: llvm-spirv %t.bc --spirv-max-version=1.1 --spirv-ext=+SPV_KHR_no_integer_wrap_decoration -o %t.spv
; RUN: spirv-val %t.spv
; RUN: llvm-spirv -r %t.spv --spirv-ext=+SPV_KHR_no_integer_wrap_decoration -o %t.rev.bc
; RUN: llvm-spirv -r -emit-opaque-pointers %t.spv --spirv-max-version=1.1 --spirv-ext=+SPV_KHR_no_integer_wrap_decoration -o %t.rev.bc
; RUN: llvm-dis < %t.rev.bc | FileCheck %s --check-prefix=CHECK-LLVM
; RUN: llvm-spirv %t.bc --spirv-max-version=1.4 -spirv-text -o - | FileCheck %s --check-prefixes=CHECK-SPIRV,CHECK-SPIRV-NOEXT
; RUN: llvm-spirv %t.bc --spirv-max-version=1.4 -o %t.spv
; RUN: spirv-val %t.spv
; RUN: llvm-spirv -r -emit-opaque-pointers %t.spv --spirv-max-version=1.4 -o %t.rev.bc
; RUN: llvm-dis < %t.rev.bc | FileCheck %s --check-prefix=CHECK-LLVM
;
; During consumption, any SPIR-V extension must be accepted by default
Expand All @@ -21,29 +26,29 @@
;
; Negative tests:
;
; Check that translator is able to reject SPIR-V if extension is disallowed
;
; RUN: not llvm-spirv -r %t.spv --spirv-ext=-SPV_KHR_no_integer_wrap_decoration -o - 2>&1 | FileCheck %s --check-prefix=CHECK-INVALID-SPIRV
; Check that translator is able to skip nsw/nuw attributes if extension is
; disabled implicitly or explicitly and if max SPIR-V version is lower then 1.4
;
; Check that translator is able to skip nsw/nuw attributes if extension is disabled implicitly or explicitly
;
; RUN: llvm-spirv %t.bc -spirv-text -o - | FileCheck %s --check-prefix=CHECK-SPIRV-NOEXT
; RUN: llvm-spirv %t.bc -o %t.spv
; RUN: llvm-spirv -r %t.spv -o %t.rev.bc
; RUN: llvm-dis < %t.rev.bc | FileCheck %s --check-prefix=CHECK-LLVM-NOEXT
; RUN: llvm-spirv %t.bc --spirv-max-version=1.1 -spirv-text -o - | FileCheck %s --check-prefix=CHECK-SPIRV-NEGATIVE
; RUN: llvm-spirv --spirv-max-version=1.1 %t.bc -o %t.spv
; RUN: llvm-spirv -r -emit-opaque-pointers %t.spv -o %t.rev.bc
; RUN: llvm-dis < %t.rev.bc | FileCheck %s --check-prefix=CHECK-LLVM-NEGATIVE
;
; RUN: llvm-spirv %t.bc --spirv-ext=-SPV_KHR_no_integer_wrap_decoration -spirv-text -o - | FileCheck %s --check-prefix=CHECK-SPIRV-NOEXT
; RUN: llvm-spirv %t.bc --spirv-ext=-SPV_KHR_no_integer_wrap_decoration -o %t.spv
; RUN: llvm-spirv -r %t.spv -o %t.rev.bc
; RUN: llvm-dis < %t.rev.bc | FileCheck %s --check-prefix=CHECK-LLVM-NOEXT
; RUN: llvm-spirv %t.bc --spirv-max-version=1.1 --spirv-ext=-SPV_KHR_no_integer_wrap_decoration -spirv-text -o - | FileCheck %s --check-prefix=CHECK-SPIRV-NEGATIVE
; RUN: llvm-spirv %t.bc --spirv-max-version=1.1 --spirv-ext=-SPV_KHR_no_integer_wrap_decoration -o %t.spv
; RUN: llvm-spirv -r -emit-opaque-pointers %t.spv -o %t.rev.bc
; RUN: llvm-dis < %t.rev.bc | FileCheck %s --check-prefix=CHECK-LLVM-NEGATIVE

; CHECK-SPIRV: Extension "SPV_KHR_no_integer_wrap_decoration"
; Check SPIR-V versions in a format magic number + version
; CHECK-SPIRV-EXT: 119734787 65536
; CHECK-SPIRV-EXT: Extension "SPV_KHR_no_integer_wrap_decoration"
; CHECK-SPIRV-NOEXT: 119734787 66560
; CHECK-SPIRV-DAG: Decorate {{[0-9]+}} NoSignedWrap
; CHECK-SPIRV-DAG: Decorate {{[0-9]+}} NoUnsignedWrap
;
; CHECK-SPIRV-NOEXT-NOT: Extension "SPV_KHR_no_integer_wrap_decoration"
; CHECK-SPIRV-NOEXT-NOT: Decorate {{[0-9]+}} NoSignedWrap
; CHECK-SPIRV-NOEXT-NOT: Decorate {{[0-9]+}} NoUnsignedWrap
; CHECK-SPIRV-NEGATIVE-NOT: Extension "SPV_KHR_no_integer_wrap_decoration"
; CHECK-SPIRV-NEGATIVE-NOT: Decorate {{[0-9]+}} NoSignedWrap
; CHECK-SPIRV-NEGATIVE-NOT: Decorate {{[0-9]+}} NoUnsignedWrap
;
; CHECK-INVALID-SPIRV: input SPIR-V module uses extension 'SPV_KHR_no_integer_wrap_decoration' which were disabled

Expand All @@ -55,7 +60,7 @@ define spir_func i32 @square(i16 zeroext %a) local_unnamed_addr #0 {
entry:
%conv = zext i16 %a to i32
; CHECK-LLVM: mul nuw nsw
; CHECK-LLVM-NOEXT: mul i32
; CHECK-LLVM-NEGATIVE: mul i32
%mul = mul nuw nsw i32 %conv, %conv
ret i32 %mul
}
Expand Down
Loading

0 comments on commit be0905f

Please sign in to comment.