| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,87 @@ | ||
| #include "CIRGenTypes.h" | ||
|
|
||
| #include "CIRGenModule.h" | ||
|
|
||
| #include "clang/AST/ASTContext.h" | ||
| #include "clang/AST/Type.h" | ||
|
|
||
| using namespace clang; | ||
| using namespace clang::CIRGen; | ||
|
|
||
| CIRGenTypes::CIRGenTypes(CIRGenModule &genModule) | ||
| : cgm(genModule), context(genModule.getASTContext()) {} | ||
|
|
||
| CIRGenTypes::~CIRGenTypes() {} | ||
|
|
||
| mlir::Type CIRGenTypes::convertType(QualType type) { | ||
| type = context.getCanonicalType(type); | ||
| const Type *ty = type.getTypePtr(); | ||
|
|
||
| // For types that haven't been implemented yet or are otherwise unsupported, | ||
| // report an error and return 'int'. | ||
|
|
||
| mlir::Type resultType = nullptr; | ||
| switch (ty->getTypeClass()) { | ||
| case Type::Builtin: { | ||
| switch (cast<BuiltinType>(ty)->getKind()) { | ||
| // Signed types. | ||
| case BuiltinType::Char_S: | ||
| case BuiltinType::Int: | ||
| case BuiltinType::Int128: | ||
| case BuiltinType::Long: | ||
| case BuiltinType::LongLong: | ||
| case BuiltinType::SChar: | ||
| case BuiltinType::Short: | ||
| case BuiltinType::WChar_S: | ||
| resultType = cir::IntType::get(cgm.getBuilder().getContext(), | ||
| context.getTypeSize(ty), | ||
| /*isSigned=*/true); | ||
| break; | ||
| // Unsigned types. | ||
| case BuiltinType::Char8: | ||
| case BuiltinType::Char16: | ||
| case BuiltinType::Char32: | ||
| case BuiltinType::Char_U: | ||
| case BuiltinType::UChar: | ||
| case BuiltinType::UInt: | ||
| case BuiltinType::UInt128: | ||
| case BuiltinType::ULong: | ||
| case BuiltinType::ULongLong: | ||
| case BuiltinType::UShort: | ||
| case BuiltinType::WChar_U: | ||
| resultType = cir::IntType::get(cgm.getBuilder().getContext(), | ||
| context.getTypeSize(ty), | ||
| /*isSigned=*/false); | ||
| break; | ||
| default: | ||
| cgm.errorNYI(SourceLocation(), "processing of built-in type", type); | ||
| resultType = cir::IntType::get(cgm.getBuilder().getContext(), 32, | ||
| /*isSigned=*/true); | ||
| break; | ||
| } | ||
| break; | ||
| } | ||
| case Type::BitInt: { | ||
| const auto *bitIntTy = cast<BitIntType>(type); | ||
| if (bitIntTy->getNumBits() > cir::IntType::maxBitwidth()) { | ||
| cgm.errorNYI(SourceLocation(), "large _BitInt type", type); | ||
| resultType = cir::IntType::get(cgm.getBuilder().getContext(), 32, | ||
| /*isSigned=*/true); | ||
| } else { | ||
| resultType = | ||
| cir::IntType::get(cgm.getBuilder().getContext(), | ||
| bitIntTy->getNumBits(), bitIntTy->isSigned()); | ||
| } | ||
| break; | ||
| } | ||
| default: | ||
| cgm.errorNYI(SourceLocation(), "processing of type", type); | ||
| resultType = | ||
| cir::IntType::get(cgm.getBuilder().getContext(), 32, /*isSigned=*/true); | ||
| break; | ||
| } | ||
|
|
||
| assert(resultType && "Type conversion not yet implemented"); | ||
|
|
||
| return resultType; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| //===--- CIRGenTypes.h - Type translation for CIR CodeGen -------*- C++ -*-===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // This is the code that handles AST -> CIR type lowering. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #ifndef LLVM_CLANG_LIB_CODEGEN_CODEGENTYPES_H | ||
| #define LLVM_CLANG_LIB_CODEGEN_CODEGENTYPES_H | ||
|
|
||
| #include "clang/CIR/Dialect/IR/CIRTypes.h" | ||
|
|
||
| namespace clang { | ||
| class ASTContext; | ||
| class QualType; | ||
| } // namespace clang | ||
|
|
||
| namespace mlir { | ||
| class Type; | ||
| } | ||
|
|
||
| namespace clang::CIRGen { | ||
|
|
||
| class CIRGenModule; | ||
|
|
||
| /// This class organizes the cross-module state that is used while lowering | ||
| /// AST types to CIR types. | ||
| class CIRGenTypes { | ||
| CIRGenModule &cgm; | ||
| clang::ASTContext &context; | ||
|
|
||
| public: | ||
| CIRGenTypes(CIRGenModule &cgm); | ||
| ~CIRGenTypes(); | ||
|
|
||
| /// Convert a Clang type into a mlir::Type. | ||
| mlir::Type convertType(clang::QualType type); | ||
| }; | ||
|
|
||
| } // namespace clang::CIRGen | ||
|
|
||
| #endif |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| // Global variables of intergal types | ||
| // RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o - | FileCheck %s | ||
|
|
||
| char c; | ||
| // CHECK: cir.global @c : !cir.int<s, 8> | ||
|
|
||
| signed char sc; | ||
| // CHECK: cir.global @sc : !cir.int<s, 8> | ||
|
|
||
| unsigned char uc; | ||
| // CHECK: cir.global @uc : !cir.int<u, 8> | ||
|
|
||
| short ss; | ||
| // CHECK: cir.global @ss : !cir.int<s, 16> | ||
|
|
||
| unsigned short us; | ||
| // CHECK: cir.global @us : !cir.int<u, 16> | ||
|
|
||
| int si; | ||
| // CHECK: cir.global @si : !cir.int<s, 32> | ||
|
|
||
| unsigned ui; | ||
| // CHECK: cir.global @ui : !cir.int<u, 32> | ||
|
|
||
| long sl; | ||
| // CHECK: cir.global @sl : !cir.int<s, 64> | ||
|
|
||
| unsigned long ul; | ||
| // CHECK: cir.global @ul : !cir.int<u, 64> | ||
|
|
||
| long long sll; | ||
| // CHECK: cir.global @sll : !cir.int<s, 64> | ||
|
|
||
| unsigned long long ull; | ||
| // CHECK: cir.global @ull : !cir.int<u, 64> | ||
|
|
||
| __int128 s128; | ||
| // CHECK: cir.global @s128 : !cir.int<s, 128> | ||
|
|
||
| unsigned __int128 u128; | ||
| // CHECK: cir.global @u128 : !cir.int<u, 128> | ||
|
|
||
| wchar_t wc; | ||
| // CHECK: cir.global @wc : !cir.int<s, 32> | ||
|
|
||
| char8_t c8; | ||
| // CHECK: cir.global @c8 : !cir.int<u, 8> | ||
|
|
||
| char16_t c16; | ||
| // CHECK: cir.global @c16 : !cir.int<u, 16> | ||
|
|
||
| char32_t c32; | ||
| // CHECK: cir.global @c32 : !cir.int<u, 32> | ||
|
|
||
| _BitInt(20) sb20; | ||
| // CHECK: cir.global @sb20 : !cir.int<s, 20> | ||
|
|
||
| unsigned _BitInt(48) ub48; | ||
| // CHECK: cir.global @ub48 : !cir.int<u, 48> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| # libc++ Maintainers | ||
|
|
||
| This file is a list of the | ||
| [maintainers](https://llvm.org/docs/DeveloperPolicy.html#maintainers) for | ||
| libc++. | ||
|
|
||
| # Lead maintainer | ||
|
|
||
| Louis Dionne \ | ||
| ldionne.2@gmail.com (email), [ldionne](https://github.com/ldionne) (GitHub) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,142 @@ | ||
| # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5 | ||
| # RUN: llc -mtriple aarch64-none-elf -mattr=+mte --run-pass=aarch64-ldst-opt %s -o - | FileCheck %s | ||
|
|
||
| ## When generating code with sanitize_memtag, we make use of the fact that the | ||
| ## sp+imm forms of many load and store instructions are not tag-checked, so we | ||
| ## can use SP directly instead of needing a register holding the tagged | ||
| ## pointer. However, this isn't true for the writeback versions of the | ||
| ## instructions, so we can't fold ADDs and SUBs into them in | ||
| ## AArch64LoadStoreOptimizer. This would be possible in cases where the | ||
| ## loads/stores only access untagged stack slots, but that information isn't | ||
| ## easily available after frame index elimination. | ||
|
|
||
| --- | | ||
| define void @pre_index() { | ||
| entry: | ||
| ret void | ||
| } | ||
| define void @pre_index_memtag() sanitize_memtag { | ||
| entry: | ||
| ret void | ||
| } | ||
| define void @pre_index_memtag_not_sp() sanitize_memtag { | ||
| entry: | ||
| ret void | ||
| } | ||
| define void @post_index() { | ||
| entry: | ||
| ret void | ||
| } | ||
| define void @post_index_memtag() sanitize_memtag { | ||
| entry: | ||
| ret void | ||
| } | ||
| define void @post_index_memtag_not_sp() sanitize_memtag { | ||
| entry: | ||
| ret void | ||
| } | ||
| ... | ||
| --- | ||
| name: pre_index | ||
| body: | | ||
| bb.0.entry: | ||
| liveins: $x0 | ||
|
|
||
| ; CHECK-LABEL: name: pre_index | ||
| ; CHECK: liveins: $x0 | ||
| ; CHECK-NEXT: {{ $}} | ||
| ; CHECK-NEXT: $sp = frame-setup SUBXri $sp, 16, 0 | ||
| ; CHECK-NEXT: early-clobber $sp = STRXpre killed renamable $x0, $sp, 16 | ||
| ; CHECK-NEXT: RET undef $lr | ||
| $sp = frame-setup SUBXri $sp, 16, 0 | ||
| STRXui killed renamable $x0, $sp, 2 | ||
| $sp = ADDXri $sp, 16, 0 | ||
| RET undef $lr | ||
| ... | ||
| --- | ||
| name: pre_index_memtag | ||
| body: | | ||
| bb.0.entry: | ||
| liveins: $x0 | ||
|
|
||
| ; CHECK-LABEL: name: pre_index_memtag | ||
| ; CHECK: liveins: $x0 | ||
| ; CHECK-NEXT: {{ $}} | ||
| ; CHECK-NEXT: $sp = frame-setup SUBXri $sp, 16, 0 | ||
| ; CHECK-NEXT: STRXui killed renamable $x0, $sp, 2 | ||
| ; CHECK-NEXT: $sp = ADDXri $sp, 16, 0 | ||
| ; CHECK-NEXT: RET undef $lr | ||
| $sp = frame-setup SUBXri $sp, 16, 0 | ||
| STRXui killed renamable $x0, $sp, 2 | ||
| $sp = ADDXri $sp, 16, 0 | ||
| RET undef $lr | ||
| ... | ||
| --- | ||
| name: pre_index_memtag_not_sp | ||
| body: | | ||
| bb.0.entry: | ||
| liveins: $x0, $x1 | ||
|
|
||
| ; CHECK-LABEL: name: pre_index_memtag_not_sp | ||
| ; CHECK: liveins: $x0, $x1 | ||
| ; CHECK-NEXT: {{ $}} | ||
| ; CHECK-NEXT: $x1 = frame-setup SUBXri $x1, 16, 0 | ||
| ; CHECK-NEXT: early-clobber $x1 = STRXpre killed renamable $x0, $x1, 16 | ||
| ; CHECK-NEXT: RET undef $lr, implicit $x1 | ||
| $x1 = frame-setup SUBXri $x1, 16, 0 | ||
| STRXui killed renamable $x0, $x1, 2 | ||
| $x1 = ADDXri $x1, 16, 0 | ||
| RET undef $lr, implicit $x1 | ||
| ... | ||
| --- | ||
| name: post_index | ||
| body: | | ||
| bb.0.entry: | ||
| liveins: $x0 | ||
|
|
||
| ; CHECK-LABEL: name: post_index | ||
| ; CHECK: liveins: $x0 | ||
| ; CHECK-NEXT: {{ $}} | ||
| ; CHECK-NEXT: $sp = frame-setup SUBXri $sp, 16, 0 | ||
| ; CHECK-NEXT: early-clobber $sp = STRXpost killed renamable $x0, $sp, 16 | ||
| ; CHECK-NEXT: RET undef $lr | ||
| $sp = frame-setup SUBXri $sp, 16, 0 | ||
| STRXui killed renamable $x0, $sp, 0 | ||
| $sp = ADDXri $sp, 16, 0 | ||
| RET undef $lr | ||
| ... | ||
| --- | ||
| name: post_index_memtag | ||
| body: | | ||
| bb.0.entry: | ||
| liveins: $x0 | ||
|
|
||
| ; CHECK-LABEL: name: post_index_memtag | ||
| ; CHECK: liveins: $x0 | ||
| ; CHECK-NEXT: {{ $}} | ||
| ; CHECK-NEXT: $sp = frame-setup SUBXri $sp, 16, 0 | ||
| ; CHECK-NEXT: STRXui killed renamable $x0, $sp, 0 | ||
| ; CHECK-NEXT: $sp = ADDXri $sp, 16, 0 | ||
| ; CHECK-NEXT: RET undef $lr | ||
| $sp = frame-setup SUBXri $sp, 16, 0 | ||
| STRXui killed renamable $x0, $sp, 0 | ||
| $sp = ADDXri $sp, 16, 0 | ||
| RET undef $lr | ||
| ... | ||
| --- | ||
| name: post_index_memtag_not_sp | ||
| body: | | ||
| bb.0.entry: | ||
| liveins: $x0, $x1 | ||
|
|
||
| ; CHECK-LABEL: name: post_index_memtag_not_sp | ||
| ; CHECK: liveins: $x0, $x1 | ||
| ; CHECK-NEXT: {{ $}} | ||
| ; CHECK-NEXT: $x1 = frame-setup SUBXri $x1, 16, 0 | ||
| ; CHECK-NEXT: early-clobber $x1 = STRXpost killed renamable $x0, $x1, 16 | ||
| ; CHECK-NEXT: RET undef $lr, implicit $x1 | ||
| $x1 = frame-setup SUBXri $x1, 16, 0 | ||
| STRXui killed renamable $x0, $x1, 0 | ||
| $x1 = ADDXri $x1, 16, 0 | ||
| RET undef $lr, implicit $x1 | ||
| ... |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py | ||
| ; RUN: llc < %s -mtriple=i686-unknown | FileCheck %s --check-prefix=X86 | ||
| ; RUN: llc < %s -mtriple=x86_64-unknown | FileCheck %s --check-prefix=X64 | ||
|
|
||
| define void @PR118934(i1 %b, ptr %f, ptr %k) { | ||
| ; X86-LABEL: PR118934: | ||
| ; X86: # %bb.0: # %entry | ||
| ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax | ||
| ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx | ||
| ; X86-NEXT: movzbl {{[0-9]+}}(%esp), %edx | ||
| ; X86-NEXT: andb $1, %dl | ||
| ; X86-NEXT: addb %dl, %dl | ||
| ; X86-NEXT: addb $-2, %dl | ||
| ; X86-NEXT: movsbl %dl, %edx | ||
| ; X86-NEXT: addl $-6, %edx | ||
| ; X86-NEXT: addl $6, %edx | ||
| ; X86-NEXT: movl %edx, (%ecx) | ||
| ; X86-NEXT: addl %edx, %edx | ||
| ; X86-NEXT: movl %edx, (%eax) | ||
| ; | ||
| ; X64-LABEL: PR118934: | ||
| ; X64: # %bb.0: # %entry | ||
| ; X64-NEXT: andb $1, %dil | ||
| ; X64-NEXT: addb %dil, %dil | ||
| ; X64-NEXT: addb $-2, %dil | ||
| ; X64-NEXT: movsbl %dil, %eax | ||
| ; X64-NEXT: addl $-6, %eax | ||
| ; X64-NEXT: addl $6, %eax | ||
| ; X64-NEXT: movl %eax, (%rsi) | ||
| ; X64-NEXT: addl %eax, %eax | ||
| ; X64-NEXT: movl %eax, (%rdx) | ||
| entry: | ||
| %0 = select i1 %b, i8 0, i8 -2 | ||
| br label %for.end | ||
|
|
||
| for.end: | ||
| %n.i.i = select i1 poison, i32 6, i32 7 | ||
| %narrow = add nsw i8 %0, -6 | ||
| %add2.i = sext i8 %narrow to i32 | ||
| %conv5.i = add nsw i32 %n.i.i, %add2.i | ||
| store i32 %conv5.i, ptr %f, align 4 | ||
| %add = shl nsw i32 %conv5.i, 1 | ||
| store i32 %add, ptr %k, align 4 | ||
| unreachable | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,74 @@ | ||
| // NOTE: Assertions have been autogenerated by utils/update_mc_test_checks.py UTC_ARGS: --version 5 | ||
| // RUN: llvm-mc -triple=amdgcn -mcpu=gfx1100 -show-encoding %s | FileCheck --check-prefix=GFX11 %s | ||
|
|
||
| v_interp_p10_f32 v0, v1, v2, v3 wait_exp:5 | ||
| // GFX11: v_interp_p10_f32 v0, v1, v2, v3 wait_exp:5 ; encoding: [0x00,0x05,0x00,0xcd,0x01,0x05,0x0e,0x04] | ||
|
|
||
| v_interp_p10_f32 v0, -v1, v2, v3 | ||
| // GFX11: v_interp_p10_f32 v0, -v1, v2, v3 wait_exp:0 ; encoding: [0x00,0x00,0x00,0xcd,0x01,0x05,0x0e,0x24] | ||
|
|
||
| v_interp_p10_f32 v0, v1, -v2, v3 | ||
| // GFX11: v_interp_p10_f32 v0, v1, -v2, v3 wait_exp:0 ; encoding: [0x00,0x00,0x00,0xcd,0x01,0x05,0x0e,0x44] | ||
|
|
||
| v_interp_p10_f32 v0, v1, v2, -v3 | ||
| // GFX11: v_interp_p10_f32 v0, v1, v2, -v3 wait_exp:0 ; encoding: [0x00,0x00,0x00,0xcd,0x01,0x05,0x0e,0x84] | ||
|
|
||
| v_interp_p2_f32 v0, v1, v2, v3 wait_exp:5 | ||
| // GFX11: v_interp_p2_f32 v0, v1, v2, v3 wait_exp:5 ; encoding: [0x00,0x05,0x01,0xcd,0x01,0x05,0x0e,0x04] | ||
|
|
||
| v_interp_p2_f32 v0, -v1, v2, v3 | ||
| // GFX11: v_interp_p2_f32 v0, -v1, v2, v3 wait_exp:0 ; encoding: [0x00,0x00,0x01,0xcd,0x01,0x05,0x0e,0x24] | ||
|
|
||
| v_interp_p2_f32 v0, v1, -v2, v3 | ||
| // GFX11: v_interp_p2_f32 v0, v1, -v2, v3 wait_exp:0 ; encoding: [0x00,0x00,0x01,0xcd,0x01,0x05,0x0e,0x44] | ||
|
|
||
| v_interp_p2_f32 v0, v1, v2, -v3 | ||
| // GFX11: v_interp_p2_f32 v0, v1, v2, -v3 wait_exp:0 ; encoding: [0x00,0x00,0x01,0xcd,0x01,0x05,0x0e,0x84] | ||
|
|
||
| v_interp_p10_f16_f32 v0, v1, v2, v3 wait_exp:5 | ||
| // GFX11: v_interp_p10_f16_f32 v0, v1, v2, v3 wait_exp:5 ; encoding: [0x00,0x05,0x02,0xcd,0x01,0x05,0x0e,0x04] | ||
|
|
||
| v_interp_p10_f16_f32 v0, -v1, v2, v3 | ||
| // GFX11: v_interp_p10_f16_f32 v0, -v1, v2, v3 wait_exp:0 ; encoding: [0x00,0x00,0x02,0xcd,0x01,0x05,0x0e,0x24] | ||
|
|
||
| v_interp_p10_f16_f32 v0, v1, -v2, v3 | ||
| // GFX11: v_interp_p10_f16_f32 v0, v1, -v2, v3 wait_exp:0 ; encoding: [0x00,0x00,0x02,0xcd,0x01,0x05,0x0e,0x44] | ||
|
|
||
| v_interp_p10_f16_f32 v0, v1, v2, -v3 | ||
| // GFX11: v_interp_p10_f16_f32 v0, v1, v2, -v3 wait_exp:0 ; encoding: [0x00,0x00,0x02,0xcd,0x01,0x05,0x0e,0x84] | ||
|
|
||
| v_interp_p2_f16_f32 v0, v1, v2, v3 wait_exp:5 | ||
| // GFX11: v_interp_p2_f16_f32 v0, v1, v2, v3 wait_exp:5 ; encoding: [0x00,0x05,0x03,0xcd,0x01,0x05,0x0e,0x04] | ||
|
|
||
| v_interp_p2_f16_f32 v0, -v1, v2, v3 | ||
| // GFX11: v_interp_p2_f16_f32 v0, -v1, v2, v3 wait_exp:0 ; encoding: [0x00,0x00,0x03,0xcd,0x01,0x05,0x0e,0x24] | ||
|
|
||
| v_interp_p2_f16_f32 v0, v1, -v2, v3 | ||
| // GFX11: v_interp_p2_f16_f32 v0, v1, -v2, v3 wait_exp:0 ; encoding: [0x00,0x00,0x03,0xcd,0x01,0x05,0x0e,0x44] | ||
|
|
||
| v_interp_p2_f16_f32 v0, v1, v2, -v3 | ||
| // GFX11: v_interp_p2_f16_f32 v0, v1, v2, -v3 wait_exp:0 ; encoding: [0x00,0x00,0x03,0xcd,0x01,0x05,0x0e,0x84] | ||
|
|
||
| v_interp_p10_rtz_f16_f32 v0, v1, v2, v3 wait_exp:5 | ||
| // GFX11: v_interp_p10_rtz_f16_f32 v0, v1, v2, v3 wait_exp:5 ; encoding: [0x00,0x05,0x04,0xcd,0x01,0x05,0x0e,0x04] | ||
|
|
||
| v_interp_p10_rtz_f16_f32 v0, -v1, v2, v3 | ||
| // GFX11: v_interp_p10_rtz_f16_f32 v0, -v1, v2, v3 wait_exp:0 ; encoding: [0x00,0x00,0x04,0xcd,0x01,0x05,0x0e,0x24] | ||
|
|
||
| v_interp_p10_rtz_f16_f32 v0, v1, -v2, v3 | ||
| // GFX11: v_interp_p10_rtz_f16_f32 v0, v1, -v2, v3 wait_exp:0 ; encoding: [0x00,0x00,0x04,0xcd,0x01,0x05,0x0e,0x44] | ||
|
|
||
| v_interp_p10_rtz_f16_f32 v0, v1, v2, -v3 | ||
| // GFX11: v_interp_p10_rtz_f16_f32 v0, v1, v2, -v3 wait_exp:0 ; encoding: [0x00,0x00,0x04,0xcd,0x01,0x05,0x0e,0x84] | ||
|
|
||
| v_interp_p2_rtz_f16_f32 v0, v1, v2, v3 wait_exp:5 | ||
| // GFX11: v_interp_p2_rtz_f16_f32 v0, v1, v2, v3 wait_exp:5 ; encoding: [0x00,0x05,0x05,0xcd,0x01,0x05,0x0e,0x04] | ||
|
|
||
| v_interp_p2_rtz_f16_f32 v0, -v1, v2, v3 | ||
| // GFX11: v_interp_p2_rtz_f16_f32 v0, -v1, v2, v3 wait_exp:0 ; encoding: [0x00,0x00,0x05,0xcd,0x01,0x05,0x0e,0x24] | ||
|
|
||
| v_interp_p2_rtz_f16_f32 v0, v1, -v2, v3 | ||
| // GFX11: v_interp_p2_rtz_f16_f32 v0, v1, -v2, v3 wait_exp:0 ; encoding: [0x00,0x00,0x05,0xcd,0x01,0x05,0x0e,0x44] | ||
|
|
||
| v_interp_p2_rtz_f16_f32 v0, v1, v2, -v3 | ||
| // GFX11: v_interp_p2_rtz_f16_f32 v0, v1, v2, -v3 wait_exp:0 ; encoding: [0x00,0x00,0x05,0xcd,0x01,0x05,0x0e,0x84] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| // NOTE: Assertions have been autogenerated by utils/update_mc_test_checks.py UTC_ARGS: --version 5 | ||
| // RUN: llvm-mc -triple=amdgcn -mcpu=gfx1100 -show-encoding %s | FileCheck --check-prefix=GFX11 %s | ||
|
|
||
| v_interp_p2_new_f32 v0, v1, v2, v3 | ||
| // GFX11: v_interp_p2_f32 v0, v1, v2, v3 wait_exp:0 ; encoding: [0x00,0x00,0x01,0xcd,0x01,0x05,0x0e,0x04] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| // NOTE: Assertions have been autogenerated by utils/update_mc_test_checks.py UTC_ARGS: --version 5 | ||
| // RUN: llvm-mc -triple=amdgcn -mcpu=gfx1100 -mattr=+wavefrontsize64 -show-encoding %s | FileCheck -check-prefix=GFX11 %s | ||
|
|
||
| v_cmp_tru_i32 vcc, v1, v2 | ||
| // GFX11: v_cmp_t_i32_e32 vcc, v1, v2 ; encoding: [0x01,0x05,0x8e,0x7c] | ||
|
|
||
| v_cmp_tru_u32 vcc, v1, v2 | ||
| // GFX11: v_cmp_t_u32_e32 vcc, v1, v2 ; encoding: [0x01,0x05,0x9e,0x7c] | ||
|
|
||
| v_cmp_tru_i64 vcc, v[1:2], v[2:3] | ||
| // GFX11: v_cmp_t_i64_e32 vcc, v[1:2], v[2:3] ; encoding: [0x01,0x05,0xae,0x7c] | ||
|
|
||
| v_cmp_tru_u64 vcc, v[1:2], v[2:3] | ||
| // GFX11: v_cmp_t_u64_e32 vcc, v[1:2], v[2:3] ; encoding: [0x01,0x05,0xbe,0x7c] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| // NOTE: Assertions have been autogenerated by utils/update_mc_test_checks.py UTC_ARGS: --version 5 | ||
| // RUN: llvm-mc -triple=amdgcn -mcpu=gfx1100 -mattr=+wavefrontsize64 -show-encoding %s | FileCheck -check-prefix=GFX11 %s | ||
|
|
||
| v_cmpx_tru_i32 v1, v2 | ||
| // GFX11: v_cmpx_t_i32_e32 v1, v2 ; encoding: [0x01,0x05,0x8e,0x7d] | ||
|
|
||
| v_cmpx_tru_u32 v1, v2 | ||
| // GFX11: v_cmpx_t_u32_e32 v1, v2 ; encoding: [0x01,0x05,0x9e,0x7d] | ||
|
|
||
| v_cmpx_tru_i64 v[1:2], v[2:3] | ||
| // GFX11: v_cmpx_t_i64_e32 v[1:2], v[2:3] ; encoding: [0x01,0x05,0xae,0x7d] | ||
|
|
||
| v_cmpx_tru_u64 v[1:2], v[2:3] | ||
| // GFX11: v_cmpx_t_u64_e32 v[1:2], v[2:3] ; encoding: [0x01,0x05,0xbe,0x7d] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,74 @@ | ||
| # NOTE: Assertions have been autogenerated by utils/update_mc_test_checks.py UTC_ARGS: --version 5 | ||
| # RUN: llvm-mc -triple=amdgcn -mcpu=gfx1100 -disassemble -show-encoding < %s | FileCheck -strict-whitespace -check-prefix=GFX11 %s | ||
|
|
||
| 0x00,0x05,0x00,0xcd,0x01,0x05,0x0e,0x04 | ||
| # GFX11: v_interp_p10_f32 v0, v1, v2, v3 wait_exp:5 ; encoding: [0x00,0x05,0x00,0xcd,0x01,0x05,0x0e,0x04] | ||
|
|
||
| 0x00,0x00,0x00,0xcd,0x01,0x05,0x0e,0x24 | ||
| # GFX11: v_interp_p10_f32 v0, -v1, v2, v3 wait_exp:0 ; encoding: [0x00,0x00,0x00,0xcd,0x01,0x05,0x0e,0x24] | ||
|
|
||
| 0x00,0x00,0x00,0xcd,0x01,0x05,0x0e,0x44 | ||
| # GFX11: v_interp_p10_f32 v0, v1, -v2, v3 wait_exp:0 ; encoding: [0x00,0x00,0x00,0xcd,0x01,0x05,0x0e,0x44] | ||
|
|
||
| 0x00,0x00,0x00,0xcd,0x01,0x05,0x0e,0x84 | ||
| # GFX11: v_interp_p10_f32 v0, v1, v2, -v3 wait_exp:0 ; encoding: [0x00,0x00,0x00,0xcd,0x01,0x05,0x0e,0x84] | ||
|
|
||
| 0x00,0x05,0x01,0xcd,0x01,0x05,0x0e,0x04 | ||
| # GFX11: v_interp_p2_f32 v0, v1, v2, v3 wait_exp:5 ; encoding: [0x00,0x05,0x01,0xcd,0x01,0x05,0x0e,0x04] | ||
|
|
||
| 0x00,0x00,0x01,0xcd,0x01,0x05,0x0e,0x24 | ||
| # GFX11: v_interp_p2_f32 v0, -v1, v2, v3 wait_exp:0 ; encoding: [0x00,0x00,0x01,0xcd,0x01,0x05,0x0e,0x24] | ||
|
|
||
| 0x00,0x00,0x01,0xcd,0x01,0x05,0x0e,0x44 | ||
| # GFX11: v_interp_p2_f32 v0, v1, -v2, v3 wait_exp:0 ; encoding: [0x00,0x00,0x01,0xcd,0x01,0x05,0x0e,0x44] | ||
|
|
||
| 0x00,0x00,0x01,0xcd,0x01,0x05,0x0e,0x84 | ||
| # GFX11: v_interp_p2_f32 v0, v1, v2, -v3 wait_exp:0 ; encoding: [0x00,0x00,0x01,0xcd,0x01,0x05,0x0e,0x84] | ||
|
|
||
| 0x00,0x05,0x02,0xcd,0x01,0x05,0x0e,0x04 | ||
| # GFX11: v_interp_p10_f16_f32 v0, v1, v2, v3 wait_exp:5 ; encoding: [0x00,0x05,0x02,0xcd,0x01,0x05,0x0e,0x04] | ||
|
|
||
| 0x00,0x00,0x02,0xcd,0x01,0x05,0x0e,0x24 | ||
| # GFX11: v_interp_p10_f16_f32 v0, -v1, v2, v3 wait_exp:0 ; encoding: [0x00,0x00,0x02,0xcd,0x01,0x05,0x0e,0x24] | ||
|
|
||
| 0x00,0x00,0x02,0xcd,0x01,0x05,0x0e,0x44 | ||
| # GFX11: v_interp_p10_f16_f32 v0, v1, -v2, v3 wait_exp:0 ; encoding: [0x00,0x00,0x02,0xcd,0x01,0x05,0x0e,0x44] | ||
|
|
||
| 0x00,0x00,0x02,0xcd,0x01,0x05,0x0e,0x84 | ||
| # GFX11: v_interp_p10_f16_f32 v0, v1, v2, -v3 wait_exp:0 ; encoding: [0x00,0x00,0x02,0xcd,0x01,0x05,0x0e,0x84] | ||
|
|
||
| 0x00,0x05,0x03,0xcd,0x01,0x05,0x0e,0x04 | ||
| # GFX11: v_interp_p2_f16_f32 v0, v1, v2, v3 wait_exp:5 ; encoding: [0x00,0x05,0x03,0xcd,0x01,0x05,0x0e,0x04] | ||
|
|
||
| 0x00,0x00,0x03,0xcd,0x01,0x05,0x0e,0x24 | ||
| # GFX11: v_interp_p2_f16_f32 v0, -v1, v2, v3 wait_exp:0 ; encoding: [0x00,0x00,0x03,0xcd,0x01,0x05,0x0e,0x24] | ||
|
|
||
| 0x00,0x00,0x03,0xcd,0x01,0x05,0x0e,0x44 | ||
| # GFX11: v_interp_p2_f16_f32 v0, v1, -v2, v3 wait_exp:0 ; encoding: [0x00,0x00,0x03,0xcd,0x01,0x05,0x0e,0x44] | ||
|
|
||
| 0x00,0x00,0x03,0xcd,0x01,0x05,0x0e,0x84 | ||
| # GFX11: v_interp_p2_f16_f32 v0, v1, v2, -v3 wait_exp:0 ; encoding: [0x00,0x00,0x03,0xcd,0x01,0x05,0x0e,0x84] | ||
|
|
||
| 0x00,0x05,0x04,0xcd,0x01,0x05,0x0e,0x04 | ||
| # GFX11: v_interp_p10_rtz_f16_f32 v0, v1, v2, v3 wait_exp:5 ; encoding: [0x00,0x05,0x04,0xcd,0x01,0x05,0x0e,0x04] | ||
|
|
||
| 0x00,0x00,0x04,0xcd,0x01,0x05,0x0e,0x24 | ||
| # GFX11: v_interp_p10_rtz_f16_f32 v0, -v1, v2, v3 wait_exp:0 ; encoding: [0x00,0x00,0x04,0xcd,0x01,0x05,0x0e,0x24] | ||
|
|
||
| 0x00,0x00,0x04,0xcd,0x01,0x05,0x0e,0x44 | ||
| # GFX11: v_interp_p10_rtz_f16_f32 v0, v1, -v2, v3 wait_exp:0 ; encoding: [0x00,0x00,0x04,0xcd,0x01,0x05,0x0e,0x44] | ||
|
|
||
| 0x00,0x00,0x04,0xcd,0x01,0x05,0x0e,0x84 | ||
| # GFX11: v_interp_p10_rtz_f16_f32 v0, v1, v2, -v3 wait_exp:0 ; encoding: [0x00,0x00,0x04,0xcd,0x01,0x05,0x0e,0x84] | ||
|
|
||
| 0x00,0x05,0x05,0xcd,0x01,0x05,0x0e,0x04 | ||
| # GFX11: v_interp_p2_rtz_f16_f32 v0, v1, v2, v3 wait_exp:5 ; encoding: [0x00,0x05,0x05,0xcd,0x01,0x05,0x0e,0x04] | ||
|
|
||
| 0x00,0x00,0x05,0xcd,0x01,0x05,0x0e,0x24 | ||
| # GFX11: v_interp_p2_rtz_f16_f32 v0, -v1, v2, v3 wait_exp:0 ; encoding: [0x00,0x00,0x05,0xcd,0x01,0x05,0x0e,0x24] | ||
|
|
||
| 0x00,0x00,0x05,0xcd,0x01,0x05,0x0e,0x44 | ||
| # GFX11: v_interp_p2_rtz_f16_f32 v0, v1, -v2, v3 wait_exp:0 ; encoding: [0x00,0x00,0x05,0xcd,0x01,0x05,0x0e,0x44] | ||
|
|
||
| 0x00,0x00,0x05,0xcd,0x01,0x05,0x0e,0x84 | ||
| # GFX11: v_interp_p2_rtz_f16_f32 v0, v1, v2, -v3 wait_exp:0 ; encoding: [0x00,0x00,0x05,0xcd,0x01,0x05,0x0e,0x84] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,212 @@ | ||
| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 | ||
| ; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s | ||
|
|
||
| define i1 @test_icmp_ult_zext_icmp_trunc_nuw(i16 %x, i32 %y) { | ||
| ; CHECK-LABEL: define i1 @test_icmp_ult_zext_icmp_trunc_nuw( | ||
| ; CHECK-SAME: i16 [[X:%.*]], i32 [[Y:%.*]]) { | ||
| ; CHECK-NEXT: [[EXT:%.*]] = zext i16 [[X]] to i32 | ||
| ; CHECK-NEXT: [[COND:%.*]] = icmp ult i32 [[Y]], [[EXT]] | ||
| ; CHECK-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]] | ||
| ; CHECK: [[IF_THEN]]: | ||
| ; CHECK-NEXT: [[CONV:%.*]] = trunc nuw i32 [[Y]] to i16 | ||
| ; CHECK-NEXT: ret i1 false | ||
| ; CHECK: [[IF_ELSE]]: | ||
| ; CHECK-NEXT: ret i1 false | ||
| ; | ||
| %ext = zext i16 %x to i32 | ||
| %cond = icmp ult i32 %y, %ext | ||
| br i1 %cond, label %if.then, label %if.else | ||
|
|
||
| if.then: | ||
| %conv = trunc nuw i32 %y to i16 | ||
| %cmp = icmp eq i16 %x, %conv | ||
| ret i1 %cmp | ||
|
|
||
| if.else: | ||
| ret i1 false | ||
| } | ||
|
|
||
| define i1 @test_icmp_slt_sext_icmp_trunc_nsw(i16 %x, i32 %y) { | ||
| ; CHECK-LABEL: define i1 @test_icmp_slt_sext_icmp_trunc_nsw( | ||
| ; CHECK-SAME: i16 [[X:%.*]], i32 [[Y:%.*]]) { | ||
| ; CHECK-NEXT: [[EXT:%.*]] = sext i16 [[X]] to i32 | ||
| ; CHECK-NEXT: [[COND:%.*]] = icmp slt i32 [[Y]], [[EXT]] | ||
| ; CHECK-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]] | ||
| ; CHECK: [[IF_THEN]]: | ||
| ; CHECK-NEXT: [[CONV:%.*]] = trunc nsw i32 [[Y]] to i16 | ||
| ; CHECK-NEXT: ret i1 false | ||
| ; CHECK: [[IF_ELSE]]: | ||
| ; CHECK-NEXT: ret i1 false | ||
| ; | ||
| %ext = sext i16 %x to i32 | ||
| %cond = icmp slt i32 %y, %ext | ||
| br i1 %cond, label %if.then, label %if.else | ||
|
|
||
| if.then: | ||
| %conv = trunc nsw i32 %y to i16 | ||
| %cmp = icmp slt i16 %x, %conv | ||
| ret i1 %cmp | ||
|
|
||
| if.else: | ||
| ret i1 false | ||
| } | ||
|
|
||
| define i1 @test_icmp_ult_trunc_nsw_nneg_icmp_trunc_nuw(i64 %x, i32 %y) { | ||
| ; CHECK-LABEL: define i1 @test_icmp_ult_trunc_nsw_nneg_icmp_trunc_nuw( | ||
| ; CHECK-SAME: i64 [[X:%.*]], i32 [[Y:%.*]]) { | ||
| ; CHECK-NEXT: [[EXT:%.*]] = trunc nsw i64 [[X]] to i32 | ||
| ; CHECK-NEXT: [[NNEG:%.*]] = icmp sgt i64 [[X]], -1 | ||
| ; CHECK-NEXT: [[COND:%.*]] = icmp ult i32 [[Y]], [[EXT]] | ||
| ; CHECK-NEXT: [[AND:%.*]] = and i1 [[NNEG]], [[COND]] | ||
| ; CHECK-NEXT: br i1 [[AND]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]] | ||
| ; CHECK: [[IF_THEN]]: | ||
| ; CHECK-NEXT: [[CONV:%.*]] = zext i32 [[Y]] to i64 | ||
| ; CHECK-NEXT: ret i1 false | ||
| ; CHECK: [[IF_ELSE]]: | ||
| ; CHECK-NEXT: ret i1 false | ||
| ; | ||
| %ext = trunc nsw i64 %x to i32 | ||
| %nneg = icmp sgt i64 %x, -1 | ||
| %cond = icmp ult i32 %y, %ext | ||
| %and = and i1 %nneg, %cond | ||
| br i1 %and, label %if.then, label %if.else | ||
|
|
||
| if.then: | ||
| %conv = zext i32 %y to i64 | ||
| %cmp = icmp eq i64 %x, %conv | ||
| ret i1 %cmp | ||
|
|
||
| if.else: | ||
| ret i1 false | ||
| } | ||
|
|
||
| define i1 @test2(i32 %n) { | ||
| ; CHECK-LABEL: define i1 @test2( | ||
| ; CHECK-SAME: i32 [[N:%.*]]) { | ||
| ; CHECK-NEXT: [[COND:%.*]] = icmp sgt i32 [[N]], 0 | ||
| ; CHECK-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]] | ||
| ; CHECK: [[IF_THEN]]: | ||
| ; CHECK-NEXT: [[EXT:%.*]] = zext nneg i32 [[N]] to i64 | ||
| ; CHECK-NEXT: [[END:%.*]] = add nsw i64 [[EXT]], -1 | ||
| ; CHECK-NEXT: br label %[[FOR_BODY:.*]] | ||
| ; CHECK: [[FOR_BODY]]: | ||
| ; CHECK-NEXT: [[INDVAR:%.*]] = phi i64 [ 0, %[[IF_THEN]] ], [ [[INDVAR_NEXT:%.*]], %[[FOR_NEXT:.*]] ] | ||
| ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[INDVAR]], [[END]] | ||
| ; CHECK-NEXT: br i1 [[CMP]], label %[[IF_ELSE]], label %[[FOR_NEXT]] | ||
| ; CHECK: [[FOR_NEXT]]: | ||
| ; CHECK-NEXT: [[INDVAR_NEXT]] = add nuw nsw i64 [[INDVAR]], 1 | ||
| ; CHECK-NEXT: [[COND2:%.*]] = call i1 @cond() | ||
| ; CHECK-NEXT: br i1 [[COND2]], label %[[FOR_BODY]], label %[[FOR_END:.*]] | ||
| ; CHECK: [[FOR_END]]: | ||
| ; CHECK-NEXT: [[TRUNC:%.*]] = trunc nsw i64 [[INDVAR_NEXT]] to i32 | ||
| ; CHECK-NEXT: ret i1 true | ||
| ; CHECK: [[IF_ELSE]]: | ||
| ; CHECK-NEXT: ret i1 false | ||
| ; | ||
| %cond = icmp sgt i32 %n, 0 | ||
| br i1 %cond, label %if.then, label %if.else | ||
|
|
||
| if.then: | ||
| %ext = zext nneg i32 %n to i64 | ||
| %end = add nsw i64 %ext, -1 | ||
| br label %for.body | ||
|
|
||
| for.body: | ||
| %indvar = phi i64 [ 0, %if.then ], [ %indvar.next, %for.next ] | ||
| %cmp = icmp eq i64 %indvar, %end | ||
| br i1 %cmp, label %if.else, label %for.next | ||
|
|
||
| for.next: | ||
| %indvar.next = add nuw nsw i64 %indvar, 1 | ||
| %cond2 = call i1 @cond() | ||
| br i1 %cond2, label %for.body, label %for.end | ||
|
|
||
| for.end: | ||
| %trunc = trunc nsw i64 %indvar.next to i32 | ||
| %res = icmp sgt i32 %n, %trunc | ||
| ret i1 %res | ||
|
|
||
| if.else: | ||
| ret i1 false | ||
| } | ||
|
|
||
| define i1 @test_icmp_ult_zext_icmp_trunc(i16 %x, i32 %y) { | ||
| ; CHECK-LABEL: define i1 @test_icmp_ult_zext_icmp_trunc( | ||
| ; CHECK-SAME: i16 [[X:%.*]], i32 [[Y:%.*]]) { | ||
| ; CHECK-NEXT: [[EXT:%.*]] = zext i16 [[X]] to i32 | ||
| ; CHECK-NEXT: [[COND:%.*]] = icmp ult i32 [[Y]], [[EXT]] | ||
| ; CHECK-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]] | ||
| ; CHECK: [[IF_THEN]]: | ||
| ; CHECK-NEXT: [[CONV:%.*]] = trunc i32 [[Y]] to i16 | ||
| ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[X]], [[CONV]] | ||
| ; CHECK-NEXT: ret i1 [[CMP]] | ||
| ; CHECK: [[IF_ELSE]]: | ||
| ; CHECK-NEXT: ret i1 false | ||
| ; | ||
| %ext = zext i16 %x to i32 | ||
| %cond = icmp ult i32 %y, %ext | ||
| br i1 %cond, label %if.then, label %if.else | ||
|
|
||
| if.then: | ||
| %conv = trunc i32 %y to i16 | ||
| %cmp = icmp eq i16 %x, %conv | ||
| ret i1 %cmp | ||
|
|
||
| if.else: | ||
| ret i1 false | ||
| } | ||
|
|
||
| define i1 @test_icmp_ult_zext_icmp_trunc_nuw_i128(i16 %x, i128 %y) { | ||
| ; CHECK-LABEL: define i1 @test_icmp_ult_zext_icmp_trunc_nuw_i128( | ||
| ; CHECK-SAME: i16 [[X:%.*]], i128 [[Y:%.*]]) { | ||
| ; CHECK-NEXT: [[EXT:%.*]] = zext i16 [[X]] to i128 | ||
| ; CHECK-NEXT: [[COND:%.*]] = icmp ult i128 [[Y]], [[EXT]] | ||
| ; CHECK-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]] | ||
| ; CHECK: [[IF_THEN]]: | ||
| ; CHECK-NEXT: [[CONV:%.*]] = trunc nuw i128 [[Y]] to i16 | ||
| ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[X]], [[CONV]] | ||
| ; CHECK-NEXT: ret i1 [[CMP]] | ||
| ; CHECK: [[IF_ELSE]]: | ||
| ; CHECK-NEXT: ret i1 false | ||
| ; | ||
| %ext = zext i16 %x to i128 | ||
| %cond = icmp ult i128 %y, %ext | ||
| br i1 %cond, label %if.then, label %if.else | ||
|
|
||
| if.then: | ||
| %conv = trunc nuw i128 %y to i16 | ||
| %cmp = icmp eq i16 %x, %conv | ||
| ret i1 %cmp | ||
|
|
||
| if.else: | ||
| ret i1 false | ||
| } | ||
|
|
||
| ; We do not know the sign of %x, so we cannot infer nuw for %ext. | ||
| define i1 @test_icmp_ult_trunc_nsw_icmp_trunc_nuw(i64 %x, i32 %y) { | ||
| ; CHECK-LABEL: define i1 @test_icmp_ult_trunc_nsw_icmp_trunc_nuw( | ||
| ; CHECK-SAME: i64 [[X:%.*]], i32 [[Y:%.*]]) { | ||
| ; CHECK-NEXT: [[EXT:%.*]] = trunc nsw i64 [[X]] to i32 | ||
| ; CHECK-NEXT: [[COND:%.*]] = icmp ult i32 [[Y]], [[EXT]] | ||
| ; CHECK-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]] | ||
| ; CHECK: [[IF_THEN]]: | ||
| ; CHECK-NEXT: [[CONV:%.*]] = zext i32 [[Y]] to i64 | ||
| ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[X]], [[CONV]] | ||
| ; CHECK-NEXT: ret i1 [[CMP]] | ||
| ; CHECK: [[IF_ELSE]]: | ||
| ; CHECK-NEXT: ret i1 false | ||
| ; | ||
| %ext = trunc nsw i64 %x to i32 | ||
| %cond = icmp ult i32 %y, %ext | ||
| br i1 %cond, label %if.then, label %if.else | ||
|
|
||
| if.then: | ||
| %conv = zext i32 %y to i64 | ||
| %cmp = icmp eq i64 %x, %conv | ||
| ret i1 %cmp | ||
|
|
||
| if.else: | ||
| ret i1 false | ||
| } | ||
|
|
||
| declare void @cond() |