I'm translating llvm's intermediate representation, after optimization, to the intermediate representation of another optimizer. One of the problems I've run into is that llvm sometimes (although rarely) produces strangely sized integers after an opt pass with -O3 (in this example, 832 bits). I need to use 8, 16, or 32 bit integers for the other intermediate language. In short, I'm wondering if there's a way to prevent opt from producing ridiculously sized integers, so that my code doesn't have to deal with them. I tried to get a small sample of code to produce this problem, so that you'd have an example: * * *void gsm_print (unsigned char *c)* *{* * short xmc[52];* * xmc[19] = (*c >> 2) & 0x7;* * xmc[22] = (*c >> 1) & 0x7;* * xmc[24] = (*c >> 3) & 0x7;* * xmc[28] = (*c++ & 0x1) << 2;* * xmc[29] = (*c >> 3) & 0x7;* * printf("%.2d %.2d %.2d\n", xmc[19], xmc[22], xmc[24]);* *}* I used the following commands to produce the llvm optimized code: clang -std=c89 -ccc-host-triple mipsel-unknown-linux -msoft-float -ccc-clang-archs mipsel -S -emit-llvm test-.c -o test.cll opt -S -O3 test.cll -o test.ll The 832 bit integer is introduced by OPT: *; ModuleID = 'test.cll'* *target datalayout "e-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32" * *target triple = "mipsel-unknown-linux"* *@.str = private unnamed_addr constant [16 x i8] c"%.2d %.2d %.2d\0A\00", align 1* *define void @gsm_print(i8* nocapture %c) nounwind {* *entry:* * %0 = load i8* %c, align 1* * %conv = zext i8 %0 to i32* * %shr13 = lshr i32 %conv, 2* * %1 = zext i32 %shr13 to i832* * %2 = shl nuw nsw i832 %1, 304* * %shr314 = lshr i32 %conv, 1* * %and4 = and i32 %shr314, 7* * %3 = zext i32 %shr314 to i832* * %4 = shl nuw nsw i832 %3, 352* * %shr815 = lshr i32 %conv, 3* * %5 = zext i32 %shr815 to i832* * %6 = shl nuw nsw i832 %5, 384* * %and13 = shl nuw nsw i32 %conv, 2* * %7 = zext i32 %and13 to i832* * %8 = shl nuw nsw i832 %7, 448* * %ins9 = or i832 %6, %8* * %ins6 = or i832 %ins9, %4* * %ins3 = or i832 %ins6, %2* * %mask = and i832 %ins3, 2907354897182427562473109274990997453148240953923409872292419068024036200676295656363596833343228648301157852525925214200579414210641920 * * %sext17 = lshr exact i832 %mask, 304* * %conv2220 = trunc i832 %sext17 to i32* * %9 = lshr i832 %mask, 384* * %10 = trunc i832 %9 to i32* * %call = tail call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([16 x i8]* @.str, i32 0, i32 0), i32 %conv2220, i32 %and4, i32 %10) nounwind* * ret void* *}* *declare i32 @printf(i8* nocapture, ...) nounwind* Do I have to implement logic for extremely large integers, or is there a way to limit the size of the integers that opt produces? -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20120824/0ce3597f/attachment.html>
On Fri, Aug 24, 2012 at 10:00 AM, ryan baird <ryanrbaird at gmail.com> wrote:> I'm translating llvm's intermediate representation, after optimization, to > the intermediate representation of another optimizer. > > One of the problems I've run into is that llvm sometimes (although rarely) > produces strangely sized integers after an opt pass with -O3 (in this > example, 832 bits). I need to use 8, 16, or 32 bit integers for the other > intermediate language. In short, I'm wondering if there's a way to prevent > opt from producing ridiculously sized integers, so that my code doesn't have > to deal with them. > > I tried to get a small sample of code to produce this problem, so that you'd > have an example: > > void gsm_print (unsigned char *c) > { > short xmc[52]; > > xmc[19] = (*c >> 2) & 0x7; > xmc[22] = (*c >> 1) & 0x7; > xmc[24] = (*c >> 3) & 0x7; > xmc[28] = (*c++ & 0x1) << 2; > xmc[29] = (*c >> 3) & 0x7; > > printf("%.2d %.2d %.2d\n", xmc[19], xmc[22], xmc[24]); > } > > I used the following commands to produce the llvm optimized code: > clang -std=c89 -ccc-host-triple mipsel-unknown-linux -msoft-float > -ccc-clang-archs mipsel -S -emit-llvm test-.c -o test.cll > opt -S -O3 test.cll -o test.ll > > The 832 bit integer is introduced by OPT: > > ; ModuleID = 'test.cll' > target datalayout > "e-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32" > target triple = "mipsel-unknown-linux" > > @.str = private unnamed_addr constant [16 x i8] c"%.2d %.2d %.2d\0A\00", > align 1 > > define void @gsm_print(i8* nocapture %c) nounwind { > entry: > %0 = load i8* %c, align 1 > %conv = zext i8 %0 to i32 > %shr13 = lshr i32 %conv, 2 > %1 = zext i32 %shr13 to i832 > %2 = shl nuw nsw i832 %1, 304 > %shr314 = lshr i32 %conv, 1 > %and4 = and i32 %shr314, 7 > %3 = zext i32 %shr314 to i832 > %4 = shl nuw nsw i832 %3, 352 > %shr815 = lshr i32 %conv, 3 > %5 = zext i32 %shr815 to i832 > %6 = shl nuw nsw i832 %5, 384 > %and13 = shl nuw nsw i32 %conv, 2 > %7 = zext i32 %and13 to i832 > %8 = shl nuw nsw i832 %7, 448 > %ins9 = or i832 %6, %8 > %ins6 = or i832 %ins9, %4 > %ins3 = or i832 %ins6, %2 > %mask = and i832 %ins3, > 2907354897182427562473109274990997453148240953923409872292419068024036200676295656363596833343228648301157852525925214200579414210641920 > %sext17 = lshr exact i832 %mask, 304 > %conv2220 = trunc i832 %sext17 to i32 > %9 = lshr i832 %mask, 384 > %10 = trunc i832 %9 to i32 > %call = tail call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([16 > x i8]* @.str, i32 0, i32 0), i32 %conv2220, i32 %and4, i32 %10) nounwind > ret void > } > > declare i32 @printf(i8* nocapture, ...) nounwind > > Do I have to implement logic for extremely large integers, or is there a way > to limit the size of the integers that opt produces?Large integer operations are normally converted by the CPU backend's legalization pass into sequences of operations supported by the native instruction set. You might look into implementing your translator as a CPU backend, or using some of the standard legalization rules in a custom optimizer pass. -Joe
Hi Ryan, On 24/08/12 19:00, ryan baird wrote:> I'm translating llvm's intermediate representation, after optimization, to the > intermediate representation of another optimizer. > > One of the problems I've run into is that llvm sometimes (although rarely) > produces strangely sized integers after an opt pass with -O3 (in this example, > 832 bits). I need to use 8, 16, or 32 bit integers for the other intermediate > language. In short, I'm wondering if there's a way to prevent opt from > producing ridiculously sized integers, so that my code doesn't have to deal with > them.these integers are produced by the sroa (scalar replacement of aggregates) pass. This pass is currently being rewritten by Chandler so that it doesn't create funky integers any more. In the meantime I think this is controlled by the ScalarLoadThreshold parameter to createScalarReplAggregatesPass. Ciao, Duncan.> > I tried to get a small sample of code to produce this problem, so that you'd > have an example: > / > / > /void gsm_print (unsigned char *c)/ > /{/ > / short xmc[52];/ > > / xmc[19] = (*c >> 2) & 0x7;/ > / xmc[22] = (*c >> 1) & 0x7;/ > / xmc[24] = (*c >> 3) & 0x7;/ > / xmc[28] = (*c++ & 0x1) << 2;/ > / xmc[29] = (*c >> 3) & 0x7;/ > > / printf("%.2d %.2d %.2d\n", xmc[19], xmc[22], xmc[24]);/ > /}/ > > I used the following commands to produce the llvm optimized code: > clang -std=c89 -ccc-host-triple mipsel-unknown-linux -msoft-float > -ccc-clang-archs mipsel -S -emit-llvm test-.c -o test.cll > opt -S -O3 test.cll -o test.ll > > The 832 bit integer is introduced by OPT: > > /; ModuleID = 'test.cll'/ > /target datalayout > "e-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32"/ > /target triple = "mipsel-unknown-linux"/ > > /@.str = private unnamed_addr constant [16 x i8] c"%.2d %.2d %.2d\0A\00", align 1/ > > /define void @gsm_print(i8* nocapture %c) nounwind {/ > /entry:/ > / %0 = load i8* %c, align 1/ > / %conv = zext i8 %0 to i32/ > / %shr13 = lshr i32 %conv, 2/ > / %1 = zext i32 %shr13 to i832/ > / %2 = shl nuw nsw i832 %1, 304/ > / %shr314 = lshr i32 %conv, 1/ > / %and4 = and i32 %shr314, 7/ > / %3 = zext i32 %shr314 to i832/ > / %4 = shl nuw nsw i832 %3, 352/ > / %shr815 = lshr i32 %conv, 3/ > / %5 = zext i32 %shr815 to i832/ > / %6 = shl nuw nsw i832 %5, 384/ > / %and13 = shl nuw nsw i32 %conv, 2/ > / %7 = zext i32 %and13 to i832/ > / %8 = shl nuw nsw i832 %7, 448/ > / %ins9 = or i832 %6, %8/ > / %ins6 = or i832 %ins9, %4/ > / %ins3 = or i832 %ins6, %2/ > / %mask = and i832 %ins3, > 2907354897182427562473109274990997453148240953923409872292419068024036200676295656363596833343228648301157852525925214200579414210641920/ > / %sext17 = lshr exact i832 %mask, 304/ > / %conv2220 = trunc i832 %sext17 to i32/ > / %9 = lshr i832 %mask, 384/ > / %10 = trunc i832 %9 to i32/ > / %call = tail call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([16 x > i8]* @.str, i32 0, i32 0), i32 %conv2220, i32 %and4, i32 %10) nounwind/ > / ret void/ > /}/ > > /declare i32 @printf(i8* nocapture, ...) nounwind/ > > Do I have to implement logic for extremely large integers, or is there a way to > limit the size of the integers that opt produces? > > > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >