diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp --- a/llvm/lib/Transforms/Utils/Local.cpp +++ b/llvm/lib/Transforms/Utils/Local.cpp @@ -3391,6 +3391,11 @@ if (DemandedBW > ITy->getScalarSizeInBits()) return false; + // Check that the bswap/bitreverse will have legal bit width. + auto &DL = I->getModule()->getDataLayout(); + if (DL.isIllegalInteger(DemandedBW)) + return false; + // Now, is the bit permutation correct for a bswap or a bitreverse? We can // only byteswap values with an even number of bytes. APInt DemandedMask = APInt::getAllOnes(DemandedBW); diff --git a/llvm/test/Transforms/CodeGenPrepare/X86/bitreverse-recognize.ll b/llvm/test/Transforms/CodeGenPrepare/X86/bitreverse-recognize.ll --- a/llvm/test/Transforms/CodeGenPrepare/X86/bitreverse-recognize.ll +++ b/llvm/test/Transforms/CodeGenPrepare/X86/bitreverse-recognize.ll @@ -1,6 +1,8 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt < %s -loop-unroll -codegenprepare -S -mtriple=x86_64-- -mattr=+xop | FileCheck %s +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128-n8:16:32:64" + define i32 @bitreverse_i32(i32 %a) { ; CHECK-LABEL: @bitreverse_i32( ; CHECK-NEXT: entry: diff --git a/llvm/test/Transforms/InstCombine/bitreverse.ll b/llvm/test/Transforms/InstCombine/bitreverse.ll --- a/llvm/test/Transforms/InstCombine/bitreverse.ll +++ b/llvm/test/Transforms/InstCombine/bitreverse.ll @@ -1,7 +1,7 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt < %s -passes=instcombine -S | FileCheck %s -target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128-n8:16:32" +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128-n8:16:32:64" declare i16 @llvm.bitreverse.i16(i16) declare i32 @llvm.bitreverse.i32(i32) @@ -261,6 +261,23 @@ ret i8 %10 } +define i32 @illegal_width(i32 %x) { +; CHECK-LABEL: @illegal_width( +; CHECK-NEXT: [[B1:%.*]] = shl i32 [[X:%.*]], 6 +; CHECK-NEXT: [[SHIFT1:%.*]] = and i32 [[B1]], 128 +; CHECK-NEXT: [[B0:%.*]] = shl i32 [[X]], 8 +; CHECK-NEXT: [[SHIFT0:%.*]] = and i32 [[B0]], 256 +; CHECK-NEXT: [[REVERSE:%.*]] = or i32 [[SHIFT0]], [[SHIFT1]] +; CHECK-NEXT: ret i32 [[REVERSE]] +; + %b0 = and i32 %x, 1 + %b1 = and i32 %x, 2 + %shift1 = mul nuw nsw i32 %b1, 64 + %shift0 = shl nuw nsw i32 %b0, 8 + %reverse = add i32 %shift0, %shift1 + ret i32 %reverse +} + define i4 @shuf_4bits(<4 x i1> %x) { ; CHECK-LABEL: @shuf_4bits( ; CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x i1> [[X:%.*]] to i4 diff --git a/llvm/test/Transforms/InstCombine/bswap.ll b/llvm/test/Transforms/InstCombine/bswap.ll --- a/llvm/test/Transforms/InstCombine/bswap.ll +++ b/llvm/test/Transforms/InstCombine/bswap.ll @@ -1,7 +1,7 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt < %s -passes=instcombine -S | FileCheck %s -target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128-n8:16:32" +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128-n8:16:32:64" define i32 @test1(i32 %i) { ; CHECK-LABEL: @test1( diff --git a/llvm/test/Transforms/InstCombine/fsh.ll b/llvm/test/Transforms/InstCombine/fsh.ll --- a/llvm/test/Transforms/InstCombine/fsh.ll +++ b/llvm/test/Transforms/InstCombine/fsh.ll @@ -670,9 +670,8 @@ define i32 @fshl_mask_args_same2(i32 %a) { ; CHECK-LABEL: @fshl_mask_args_same2( -; CHECK-NEXT: [[TRUNC:%.*]] = trunc i32 [[A:%.*]] to i16 -; CHECK-NEXT: [[REV:%.*]] = shl i16 [[TRUNC]], 8 -; CHECK-NEXT: [[T2:%.*]] = zext i16 [[REV]] to i32 +; CHECK-NEXT: [[T1:%.*]] = shl i32 [[A:%.*]], 8 +; CHECK-NEXT: [[T2:%.*]] = and i32 [[T1]], 65280 ; CHECK-NEXT: ret i32 [[T2]] ; %t1 = and i32 %a, 255 @@ -682,8 +681,8 @@ define i32 @fshl_mask_args_same3(i32 %a) { ; CHECK-LABEL: @fshl_mask_args_same3( -; CHECK-NEXT: [[REV:%.*]] = shl i32 [[A:%.*]], 24 -; CHECK-NEXT: ret i32 [[REV]] +; CHECK-NEXT: [[T2:%.*]] = shl i32 [[A:%.*]], 24 +; CHECK-NEXT: ret i32 [[T2]] ; %t1 = and i32 %a, 255 %t2 = call i32 @llvm.fshl.i32(i32 %t1, i32 %t1, i32 24)